/* gyt Live up to every day */ #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring> #include<queue> #include<set> #include<string> #include<map> #include <time.h> #define PI acos(-1) using namespace std; typedef long long ll; typedef double db; const int maxn = 6000005; const ll maxm = 1e7; const ll mod = 1e9 + 7; const int INF = 0x3f3f3f; const ll inf = 1e15 + 5; const db eps = 1e-9; const int kind=26; char ch[2505][1105]; int vis[3000],n; struct Node{ int key,cnt; struct Node *next[kind],*fail; Node(){ key=0; for(int i=0;i<kind;i++) next[i]=0; } }*root; int Index(char c){ return c-'A'; } void insert(char *s,int t){ int i=0; Node *p=root; while(s[i]){ if(p->next[Index(s[i])]==0){ p->next[Index(s[i])]=new Node(); } p=p->next[Index(s[i])]; i++; } p->key=1; p->cnt=t; } void build_fail() { root->fail=root; queue<Node *> q; q.push(root); while(!q.empty()){ Node *t=q.front();q.pop(); Node *p=0; for(int i=0;i<kind;i++){ if(t->next[i]!=0){ if(t==root) t->next[i]->fail = root; else{ p=t->fail; while(p!=root&&p->next[i]==0) p=p->fail; if(p->next[i]) { t->next[i]->fail=p->next[i]; } else t->next[i]->fail=root; } q.push(t->next[i]); } } } } int bfs(char *s){ int i=0,sum=0,len=strlen(s); Node *p=root; while(s[i]){ int pos=s[i]-'A'; while(p->next[Index(s[i])]==0&&p!=root){ p=p->fail; } p=p->next[pos]; if (!p) p=root; Node *t=p; while(t!=root&&t->key!=-3){ if(abs(t->key)==1&&vis[t->cnt]){ vis[t->cnt]=0; } t->key=-3; t=t->fail; } i++; } } int query1(char *s){ int i=0,sum=0; Node *p=root; while(s[i]){ int pos=s[i]-'A'; while(p->next[Index(s[i])]==0&&p!=root){ p=p->fail; } p=p->next[pos]; if (!p) p=root; Node *t=p; while(t!=root&&t->key!=-4){ if(abs(t->key)==1) sum+=1; t->key=-4; t=t->fail; } i++; } return sum; } int query(char *s){ int i=0,sum=0; Node *p=root; while(s[i]){ int pos=s[i]-'A'; while(p->next[Index(s[i])]==0&&p!=root){ p=p->fail; } p=p->next[pos]; if (!p) p=root; Node *t=p; while(t!=root&&t->key>=0){ if(t->key==1){ vis[t->cnt]=1; t->key=-1; } else t->key=-2; t=t->fail; } i++; } for(int i=1;i<=n;i++) if(vis[i]){ bfs(ch[i]); insert(ch[i],i); } sum=query1(s); return sum; } char str1[5100009],str2[5100009]; void solve(){ int m,tt,i,j; memset(vis,0,sizeof(vis)); root=new Node(); scanf("%d", &n); for(int t=1;t<=n;t++){ scanf("%s", str1+1); for(i=1, j=1; str1[i]; i++) { if(str1[i]>='A' && str1[i]<='Z') str2[j++] = str1[i]; else { i++; int k = str1[i]-'0';i++; while(str1[i]<'A' || str1[i]>'Z') k = k*10+ str1[i++]-'0'; while(k--) str2[j++] = str1[i]; i++; } } str2[j] = '\0'; strcpy(ch[t],str2+1); insert(str2+1,t); } build_fail(); scanf("%s", str1+1); for(i=1, j=1; str1[i]; i++){ if(str1[i]>='A' && str1[i]<='Z') str2[j++] = str1[i]; else{ i++; int k = str1[i]-'0';i++; while(str1[i]<'A' || str1[i]>'Z') k = k*10+ str1[i++]-'0'; while(k--) str2[j++] = str1[i]; i++; } } str2[j] = '\0'; int ans = query(str2+1); printf("%d\n", ans); } int main() { int t = 1; // freopen("in.txt", "r", stdin); scanf("%d", &t); while(t--) solve(); return 0; }