#include <bits/stdc++.h>
using namespace std;
class DATrie {
public:
static const int MAXN = 5000000;
static const int MAXC = 63;
struct Node {
int check, base, fail, val;
} A[MAXN + MAXC];
int node_size, mem_size, emp_size;
int son_pos[MAXC], find_pos;
inline int toIndex(char c) {
if (isdigit(c)) return c - '0' + 1;
if (isupper(c)) return c - 'A' + 10 + 1;
if (islower(c)) return c - 'a' + 26 + 10 + 1;
assert(false);
}
inline bool isEMPTY(int u) {
return u < MAXN && A[u].check < 0 && A[u].base < 0;
}
void init() {
for (int i = 1; i < MAXN; i++)
A[i].check = -(i+1), A[i].base = -(i-1);
for (int i = MAXN; i < MAXN + MAXC; i++)
A[i].check = INT_MAX;
A[MAXN-1].check = -1, A[1].base = -(MAXN-1);
A[0].check = -1, A[0].base = 0;
node_size = mem_size = emp_size = 0, find_pos = 1;
}
inline void rm_node(int x) {
if (find_pos == x) find_pos = abs(A[x].check);
A[-A[x].base].check = A[x].check;
A[-A[x].check].base = A[x].base;
node_size++;
mem_size = max(mem_size, x);
}
inline void ad_node(int x) {
A[x].check = MAXN, A[x].base = MAXN;
emp_size++;
}
bool insert(const char *s) {
int st = 0, to, c;
int flag = 0;
for (int i = 0; s[i]; i++) {
c = toIndex(s[i]);
to = abs(A[st].base) + c;
if (st == abs(A[to].check)) {
st = to;
} else if (isEMPTY(to)) {
rm_node(to);
A[to].check = st, A[to].base = to;
st = to;
} else {
int son_sz = 0;
int pos = find_empty(st, c, son_sz);
relocate(st, pos, son_sz-1);
i--;
}
}
A[st].base = -abs(A[st].base);
return 1;
}
int find(const char *s) {
int st = 0, to, c;
for (int i = 0; s[i]; i++) {
c = toIndex(s[i]);
to = abs(A[st].base) + c;
if (st == abs(A[to].check))
st = to;
else
return 0;
}
return A[st].base < 0;
}
int find_empty(int st, int c, int &sz) {
sz = 0;
int bs = abs(A[st].base);
for (int i = 1, j = bs+1; i < MAXC; i++, j++) {
if (abs(A[j].check) == st)
son_pos[sz++] = i;
}
son_pos[sz++] = c;
int mn_pos = min(son_pos[0], c) - 1;
for (; find_pos && (find_pos < bs || find_pos < mn_pos); find_pos = abs(A[find_pos].check));
for (; find_pos; find_pos = abs(A[find_pos].check)) {
int ok = 1;
for (int i = 0; i < sz && ok; i++)
ok &= isEMPTY(find_pos + son_pos[i] - mn_pos);
if (ok)
return find_pos - mn_pos;
}
printf("Memory Leak -- %d\n", find_pos);
exit(0);
return -1;
}
void relocate(int st, int to, int sz) {
for (int i = sz-1; i >= 0; i--) {
int a = abs(A[st].base) + son_pos[i];
int b = to + son_pos[i];
rm_node(b);
A[b].check = st, A[b].base = A[a].base;
int vs = abs(A[a].base);
for (int j = 1, k = vs+1; j < MAXC; j++, k++) {
if (abs(A[k].check) == a)
A[k].check = b;
}
ad_node(a);
}
A[st].base = (A[st].base < 0 ? -1 : 1) * to;
}
void build() {
queue<int> Q;
int u, p, to, pto;
Q.push(0), A[0].fail = -1;
while (!Q.empty()) {
u = Q.front(), Q.pop();
for (int i = 1; i < MAXC; i++) {
to = abs(A[u].base) + i;
if (u != abs(A[to].check))
continue;
Q.push(to);
p = A[u].fail;
while (p != -1) {
pto = abs(A[p].base) + i;
if (p != abs(A[pto].check))
p = A[p].fail;
else
break;
}
if (p == -1)
A[to].fail = 0;
else
A[to].fail = abs(A[p].base) + i;
A[to].val = A[A[to].fail].val + (A[to].base < 0);
}
}
}
int query(const char *s) {
int st = 0, c, to;
int matched = 0;
for (int i = 0; s[i]; i++) {
c = toIndex(s[i]);
do {
to = abs(A[st].base) + c;
if (st != abs(A[to].check) && st != 0)
st = A[st].fail;
else
break;
} while (true);
to = abs(A[st].base) + c;
if (st != abs(A[to].check))
st = 0;
else
st = to;
matched += A[st].val;
}
return matched;
}
} tree;
char s[1048576];
int main() {
int n, m, cases = 0;
while (scanf("%d", &n) == 1) {
printf("Case #%d:\n", ++cases);
tree.init();
for (int i = 0; i < n; i++) {
scanf("%s", s);
tree.insert(s);
}
tree.build();
scanf("%d", &m);
for (int i = 0; i < m; i++) {
scanf("%s", s);
int t = tree.query(s);
printf("%d\n", t);
}
}
return 0;
}