#include <bits/stdc++.h>
int n, k, pos[1000005];
char s[1000005];
struct ac_automaton {
  int ch[1000005][26], fail[1000005], arr[1000005], cnt[1000005], totc;
  int fir[1000005], nxt[1000005], to[1000005], tot, in[1000005], out[1000005],
      block;
  void line(int x, int y) {
    nxt[++tot] = fir[x];
    fir[x] = tot;
    to[tot] = y;
  }
  void update(int x, int d) {
    for (int i = x; i <= block; i += i & (-i)) arr[i] += d;
  }
  int getsum(int x) {
    int s = 0;
    for (int i = x; i; i -= i & (-i)) s += arr[i];
    return s;
  }
  void insert(char *s, int k) {
    int r = 0, v;
    for (int i = 0; s[i]; i++) {
      v = s[i] - 'a';
      if (!ch[r][v]) ch[r][v] = ++totc;
      r = ch[r][v];
    }
    pos[k] = r;
  }
  int Q[1000005], head, tail;
  void build() {
    Q[head = 0] = 0, tail = 1;
    int r, c;
    while (head < tail) {
      r = Q[head++];
      for (int i = 0; i < 26; i++)
        if (c = ch[r][i]) {
          Q[tail++] = c;
          fail[c] = r ? ch[fail[r]][i] : 0;
        } else
          ch[r][i] = ch[fail[r]][i];
    }
    for (int i = 1; i <= totc; i++) line(fail[i], i);
  }
  void dfs(int u) {
    in[u] = ++block;
    for (int i = fir[u]; i; i = nxt[i]) dfs(to[i]);
    out[u] = block;
  }
  void modify(int x, int d) {
    if (cnt[x] == d) return;
    cnt[x] = d;
    update(in[x], d);
    update(out[x] + 1, -d);
  }
  int find(char *s) {
    int r = 0, v, ans = 0;
    for (int i = 0; s[i]; i++) {
      v = s[i] - 'a';
      r = ch[r][v];
      ans += getsum(in[r]);
    }
    return ans;
  }
} A;
int main() {
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= k; i++) scanf("%s", s), A.insert(s, i);
  A.build();
  A.dfs(0);
  for (int i = 1; i <= k; i++) A.modify(pos[i], 1);
  int x;
  char c;
  for (int i = 1; i <= n; i++) {
    getchar(), c = getchar();
    if (c == '?')
      scanf("%s", s), printf("%d\n", A.find(s));
    else
      scanf("%d", &x), A.modify(pos[x], c == '+' ? 1 : -1);
  }
}
