class AC {
public:
int next[maxn][26], lst[maxn], fail[maxn], val[maxn];
int sz, root;
void init() {
root = sz = 0;
for (int i=0; i<26; ++i)
next[sz][i] = 0;
val[sz] = 0;
sz = 1;
}
inline int getid(char ch) {
return ch-'a';
}
inline int newnode() {
for (int i=0; i<26; ++i)
next[sz][i] = 0;
val[sz] = 0;
return sz++;
}
void insert(char s[]) {
int rt, i, id, len;
rt = 0; len = strlen(s);
for (i=0; i<len; ++i) {
id = getid(s[i]);
if (!next[rt][id]) next[rt][id] = newnode();
rt = next[rt][id];
}
val[rt]++;
}
void build() {
queue<int> q;
int i, rt, id;
fail[root] = root;
lst[root] = root;
for (i=0; i<26; ++i) {
if (!next[root][i]) next[root][i] = root;
else {
fail[next[root][i]] = root;
q.push(next[root][i]);
lst[next[root][i]] = val[fail[next[root][i]]] ? fail[next[root][i]] : lst[fail[next[root][i]]];
}
}
while (!q.empty()) {
rt = q.front(); q.pop();
for (i=0; i<26; ++i) {
if (!next[rt][i]) next[rt][i] = next[fail[rt]][i];
else {
fail[next[rt][i]] = next[fail[rt]][i];
q.push(next[rt][i]);
lst[next[rt][i]] = val[fail[next[rt][i]]] ? fail[next[rt][i]] : lst[fail[next[rt][i]]];
}
}
}
}
int query(char s[]) {
int i, rt, tmp, now = 0, res = 0, len = strlen(s);
for (i=0; i<len; ++i) {
now = next[now][getid(s[i])];
tmp = now;
while (tmp) {
res += val[tmp];
val[tmp] = 0;
tmp = lst[tmp];
}
}
return res;
}
};