AC 自动机,95pts
#include <bits/stdc++.h>
using namespace std;
int edge[5005][200], fail[5005], fa[5005], r[5005], len[5005], f[5000005];
string s[25], t;
char v[5005], tx[2000005];
int n, top, m;
queue<int> q;
bool vis[5005];
int dfs(short x) {
//cout << "Now is " << x << endl;
if(!vis[x] && x){
len[x] |= dfs(fail[x]);
vis[x] = 1;
}
return len[x];
}
inline void read(string &s) {
s = "";
char c = getchar_unlocked();
while (c < 'a' || c > 'z') c = getchar_unlocked();
while (c >= 'a' && c <= 'z')
s += c, c = getchar_unlocked();
}
inline int read2(char *s) {
register int tp = 0;
char c = getchar_unlocked();
while (c < 'a' || c > 'z') c = getchar_unlocked();
while (c >= 'a' && c <= 'z')
s[tp++] = c, c = getchar_unlocked();
return tp;
}
void write(int x) {
if(x>9) write(x/10);
putchar_unlocked(x % 10 + '0');
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
read(s[i]);
for (int i = 1; i <= n; i++) {
int now = 0;
for (int j = 0; j < s[i].size(); j++) {
if (!edge[now][s[i][j]]) // 建边
edge[now][s[i][j]] = ++top, fa[top] = now; // 建立节点
now = edge[now][s[i][j]];
if (j + 1 == s[i].size())
len[now] = 1 << (s[i].size() - 1);
v[now] = s[i][j];
}
}
q.push(0);
while (!q.empty()) {
int f = q.front();
q.pop();
for (int i = 'a'; i <= 'z'; i ++)
if (edge[f][i])
q.push(edge[f][i]);
if (fa[f] != 0) {
fail[f] = edge[fail[fa[f]]][v[f]];
r[fail[f]]++;
//cout << "Fail[" << f << "]" << " is " << fail[f] << endl;
}
for(int i = 'a'; i <= 'z'; i ++)
if(!edge[f][i])
edge[f][i] = edge[fail[f]][i];
}
for(int i = 1;i <= top;i ++)
if(!r[i] && !vis[i])
dfs(i);
while(m --) {
int sz=read2(tx);
int now = 0;
for(int i = 0; i < sz; i ++) {
now = edge[now][tx[i]];
if(i)
f[i] = f[i - 1];
//cout << now << " " << v[now] << " " << len[now] << endl;
if(len[now])
for(int j = 1; len[now] >> (j - 1); j ++)
if((len[now] & (1 << (j - 1))) && f[i - j] == i - j + 1){
f[i] = i + 1;
break;
}
}
write(f[sz - 1]);
putchar_unlocked('\n');
}
return 0;
}
/*
20 20
10 10
aaab
abab
abaaa
baab
baaaa
b
ab
abaa
bbb
aaabba
*/