#include<bits/stdc++.h>
using namespace std;
const int maxn=2000101;
struct node
{
int son[30],flag,fail,ans;
void clear()
{
memset(son,0,sizeof(son));
fail=flag=0;
}
} trie[maxn];
int n,cnt,vis[maxn],Map[maxn];
char s[maxn],T[maxn];
queue<int>q;
struct ac
{
struct node
{
int son[30],flag,fail,ans;
void clear()
{
memset(son,0,sizeof(son));
fail=flag=0;
}
} trie[maxn];
int in[maxn],ans;
void init()
{
for (int i=0; i<=cnt; i++)
{
trie[i].clear();
}
for (int i=1; i<=n; i++)
{
vis[i]=0;
}
cnt=1;
ans=0;
}
void insert_(char *str,int num)
{
int u=1,len=strlen(str);
for (int i=0; i<len; i++)
{
int id=str[i]-'a';
if (!trie[u].son[id])
{
trie[u].son[id]=++cnt;
}
u=trie[u].son[id];
}
if (!trie[u].flag) trie[u].flag=num;
Map[num]=trie[u].flag;
}
void getfail()
{
for (int i=0; i<26; i++)
{
trie[0].son[i]=1;
}
q.push(1);
while (!q.empty())
{
int u=q.front();
q.pop();
int fail=trie[u].fail;
for (int i=0; i<26; i++)
{
int v=trie[u].son[i];
if (!v)
{
trie[u].son[i]=trie[fail].son[i];
continue;
}
trie[v].fail=trie[fail].son[i];
in[trie[v].fail]++;
q.push(v);
}
}
};
void topu()
{
for (int i=1; i<=cnt; i++)
{
if (!in[i])
{
q.push(i);
}
}
while (!q.empty())
{
int u=q.front();
q.pop();
vis[trie[u].flag]=trie[u].ans;
int v=trie[u].fail;
trie[v].ans+=trie[u].ans;
if (!--in[v])
{
q.push(v);
}
}
}
void query(char *str)
{
int u=1,ans=0,len=strlen(str);
for (int i=0; i<len; i++)
{
int id=str[i]-'a';
u=trie[u].son[id];
trie[u].ans++;
}
}
} AC;
int main()
{
scanf("%d",&n);
AC.init();
for (int i=1; i<=n; i++)
{
scanf("%s",s);
AC.insert_(s,i);
}
AC.getfail();
scanf("%s",T);
AC.query(T);
AC.topu();
for (int i=1; i<=n; i++)
{
printf("%d
",vis[Map[i]]);
}
}

#include<bits/stdc++.h>
using namespace std;
const int maxn=2000101;
struct node
{
int son[30],flag,fail,ans;
void clear()
{
memset(son,0,sizeof(son));
fail=flag=0;
}
} trie[maxn];
int n,cnt,vis[maxn],Map[maxn];
char s[maxn][80],T[maxn];
queue<int>q;
struct ac
{
struct node
{
int son[30],flag,fail,ans;
void clear()
{
memset(son,0,sizeof(son));
fail=flag=ans=0;
}
} trie[maxn];
int in[maxn],ans;
void init()
{
for (int i=0; i<=cnt; i++)
{
trie[i].clear();
}
for (int i=1; i<=n; i++)
{
vis[i]=0;
}
cnt=1;
}
void insert_(char *str,int num)
{
int u=1,len=strlen(str);
for (int i=0; i<len; i++)
{
int id=str[i]-'a';
if (!trie[u].son[id])
{
trie[u].son[id]=++cnt;
}
u=trie[u].son[id];
}
if (!trie[u].flag) trie[u].flag=num;
Map[num]=trie[u].flag;
}
void getfail()
{
for (int i=0; i<26; i++)
{
trie[0].son[i]=1;
}
q.push(1);
while (!q.empty())
{
int u=q.front();
q.pop();
int fail=trie[u].fail;
for (int i=0; i<26; i++)
{
int v=trie[u].son[i];
if (!v)
{
trie[u].son[i]=trie[fail].son[i];
continue;
}
trie[v].fail=trie[fail].son[i];
in[trie[v].fail]++;
q.push(v);
}
}
};
void topu()
{
for (int i=1; i<=cnt; i++)
{
if (!in[i])
{
q.push(i);
}
}
while (!q.empty())
{
int u=q.front();
q.pop();
vis[trie[u].flag]=trie[u].ans;
int v=trie[u].fail;
trie[v].ans+=trie[u].ans;
if (!--in[v])
{
q.push(v);
}
}
}
void query(char *str)
{
int u=1,ans=0,len=strlen(str);
for (int i=0; i<len; i++)
{
int id=str[i]-'a';
u=trie[u].son[id];
trie[u].ans++;
}
}
} AC;
int main()
{
while (1)
{
memset(vis,0,sizeof(vis));
memset(Map,0,sizeof(Map));
scanf("%d",&n);
if (n==0){
break;
}
AC.init();
for (int i=1; i<=n; i++)
{
scanf("%s",s[i]);
AC.insert_(s[i],i);
}
AC.getfail();
scanf("%s",T);
AC.query(T);
AC.topu();
int mx=0;
for (int i=1; i<=n; i++)
{
mx=max(mx,vis[Map[i]]);
}
printf("%d
",mx);
for (int i=1;i<=n;i++){
if (vis[Map[i]]==mx){
printf("%s
",s[Map[i]]);
}
}
}
}

#include<bits/stdc++.h>
using namespace std;
const int maxn=2000101;
struct node
{
int son[30],flag,fail,ans;
void clear()
{
memset(son,0,sizeof(son));
fail=flag=0;
}
} trie[maxn];
int n,cnt,vis[maxn],Map[maxn];
char s[maxn],T[maxn];
queue<int>q;
struct ac
{
struct node
{
int son[30],flag,fail,ans;
void clear()
{
memset(son,0,sizeof(son));
fail=flag=0;
}
} trie[maxn];
int in[maxn],ans;
void init()
{
for (int i=0; i<=cnt; i++)
{
trie[i].clear();
}
for (int i=1; i<=n; i++)
{
vis[i]=0;
}
cnt=1;
ans=0;
}
void insert_(char *str,int num)
{
int u=1,len=strlen(str);
for (int i=0; i<len; i++)
{
int id=str[i]-'a';
if (!trie[u].son[id])
{
trie[u].son[id]=++cnt;
}
u=trie[u].son[id];
}
if (!trie[u].flag) trie[u].flag=num;
Map[num]=trie[u].flag;
}
void getfail()
{
for (int i=0; i<26; i++)
{
trie[0].son[i]=1;
}
q.push(1);
while (!q.empty())
{
int u=q.front();
q.pop();
int fail=trie[u].fail;
for (int i=0; i<26; i++)
{
int v=trie[u].son[i];
if (!v)
{
trie[u].son[i]=trie[fail].son[i];
continue;
}
trie[v].fail=trie[fail].son[i];
in[trie[v].fail]++;
q.push(v);
}
}
};
void topu()
{
for (int i=1; i<=cnt; i++)
{
if (!in[i])
{
q.push(i);
}
}
while (!q.empty())
{
int u=q.front();
q.pop();
vis[trie[u].flag]=trie[u].ans;
int v=trie[u].fail;
trie[v].ans+=trie[u].ans;
if (!--in[v])
{
q.push(v);
}
}
}
void query(char *str)
{
int u=1,ans=0,len=strlen(str);
for (int i=0; i<len; i++)
{
int id=str[i]-'a';
u=trie[u].son[id];
trie[u].ans++;
}
}
} AC;
int main()
{
scanf("%d",&n);
AC.init();
for (int i=1; i<=n; i++)
{
scanf("%s",s);
AC.insert_(s,i);
}
AC.getfail();
scanf("%s",T);
AC.query(T);
AC.topu();
for (int i=1; i<=n; i++)
{
printf("%d
",vis[Map[i]]);
}
}

#include<bits/stdc++.h>
using namespace std;
const int maxn=2000101;
struct node
{
int son[30],flag,fail,ans;
void clear()
{
memset(son,0,sizeof(son));
fail=flag=0;
}
} trie[maxn];
int n,cnt,vis[maxn],Map[maxn];
char s[maxn][80],T[maxn];
queue<int>q;
struct ac
{
struct node
{
int son[30],flag,fail,ans;
void clear()
{
memset(son,0,sizeof(son));
fail=flag=ans=0;
}
} trie[maxn];
int in[maxn],ans;
void init()
{
for (int i=0; i<=cnt; i++)
{
trie[i].clear();
}
for (int i=1; i<=n; i++)
{
vis[i]=0;
}
cnt=1;
}
void insert_(char *str,int num)
{
int u=1,len=strlen(str);
for (int i=0; i<len; i++)
{
int id=str[i]-'a';
if (!trie[u].son[id])
{
trie[u].son[id]=++cnt;
}
u=trie[u].son[id];
}
if (!trie[u].flag) trie[u].flag=num;
Map[num]=trie[u].flag;
}
void getfail()
{
for (int i=0; i<26; i++)
{
trie[0].son[i]=1;
}
q.push(1);
while (!q.empty())
{
int u=q.front();
q.pop();
int fail=trie[u].fail;
for (int i=0; i<26; i++)
{
int v=trie[u].son[i];
if (!v)
{
trie[u].son[i]=trie[fail].son[i];
continue;
}
trie[v].fail=trie[fail].son[i];
in[trie[v].fail]++;
q.push(v);
}
}
};
void topu()
{
for (int i=1; i<=cnt; i++)
{
if (!in[i])
{
q.push(i);
}
}
while (!q.empty())
{
int u=q.front();
q.pop();
vis[trie[u].flag]=trie[u].ans;
int v=trie[u].fail;
trie[v].ans+=trie[u].ans;
if (!--in[v])
{
q.push(v);
}
}
}
void query(char *str)
{
int u=1,ans=0,len=strlen(str);
for (int i=0; i<len; i++)
{
int id=str[i]-'a';
u=trie[u].son[id];
trie[u].ans++;
}
}
} AC;
int main()
{
int ans=0;
scanf("%d",&n);
AC.init();
for (int i=1; i<=n; i++)
{
scanf("%s",s[i]);
AC.insert_(s[i],i);
}
AC.getfail();
scanf("%s",T);
AC.query(T);
AC.topu();
int mx=0;
for (int i=1; i<=n; i++)
{
if (vis[Map[i]])
{
ans++;
}
}
printf("%d
",ans);
}