夜来香???
//#pragma GCC optimize(3,"Ofast","inline")
#include<unordered_map>
#include<unordered_set>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<functional>
#include<cstring>
#include<string>
#include<cstdlib>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#include<stack>
#include<vector>
#include<sstream>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn= 5e5+10;
const ll mod=1e9+7;
int cnt;
queue<int>que;
struct node
{
int flag;
int fail;
int next[26];
}trie[maxn];
void inserts(char *s){
int n=strlen(s);
int now=0;
for(int i=0;i<n;i++)
{
char c=s[i];
if(!trie[now].next[c-'a'])
trie[now].next[c-'a']=cnt++;
now=trie[now].next[c-'a'];
}
trie[now].flag++;
return ;
}
void init()
{
while(!que.empty())que.pop();
for(int i=0;i<maxn;i++)
{
memset(trie[i].next,0,sizeof trie[i].next);
trie[i].fail=trie[i].flag=0;
}
cnt=1;
return ;
}
void built()
{
trie[0].fail=-1;
que.push(0);
while(!que.empty())
{
int u=que.front();que.pop();
for(int i=0;i<26;i++)
{
if(trie[u].next[i])
{
if(u==0)trie[trie[u].next[i]].fail=0;
else
{
int v=trie[u].fail;
while(v!=-1)
{
if(trie[v].next[i])
{
trie[trie[u].next[i]].fail=trie[v].next[i];
break;
}
v=trie[v].fail;
}
if(v==-1)trie[trie[u].next[i]].fail=0;
}
que.push(trie[u].next[i]);
}
}
}
}
int Get(int u)
{
int ans=0;
while(u)
{
ans+=trie[u].flag;
trie[u].flag=0;
u=trie[u].fail;
}
return ans;
}
int match(char *s)
{
int n=strlen(s);
int ans=0,now=0;
for(int i=0;i<n;i++)
{
char c=s[i];
if(trie[now].next[c-'a'])
now=trie[now].next[c-'a'];
else
{
int p=trie[now].fail;
while(p!=-1&&trie[p].next[c-'a']==0)p=trie[p].fail;
if(p==-1)now=0;
else now=trie[p].next[c-'a'];
}
if(trie[now].flag)
ans+=Get(now);
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
char s[1000009];
while(t--)
{
init();
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",s);
inserts(s);
}
built();
scanf("%s",s);
printf("%d\n",match(s));
}
return 0;
}