#include <bits/stdc++.h>
using namespace std;
inline int Read() {
  int s = 0, f = 1;
  char x;
  for (x = getchar(); x < '0' || x > '9'; x = getchar())
    if (x == '-') f = -1;
  for (; x >= '0' && x <= '9'; x = getchar()) s = (s * 10) + (x & 15);
  return f == 1 ? s : -s;
}
const int A = 1e6 + 5;
int n, m;
char nw[A];
int tr[A][26], tot;
int is[A], wr[A];
int fail[A];
int ex[A];
int head[A], tot_road;
struct Road {
  int nex, to;
} road[2 * A];
inline void ljb(int x, int y) {
  road[++tot_road] = {head[x], y};
  head[x] = tot_road;
}
inline void build(int now) {
  int len = strlen(nw);
  int p = 0;
  for (int i = 0; i < len; i++) {
    if (!tr[p][nw[i] - 'a']) tr[p][nw[i] - 'a'] = ++tot;
    p = tr[p][nw[i] - 'a'];
  }
  is[p] = now;
  wr[now] = p;
  return;
}
inline void acm() {
  queue<int> q;
  int p = 0;
  for (int i = 0; i < 26; i++) {
    p = tr[0][i];
    if (!p) continue;
    q.push(p);
    fail[p] = 0;
  }
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (int i = 0; i < 26; i++) {
      p = tr[x][i];
      if (!p) {
        tr[x][i] = tr[fail[x]][i];
        continue;
      }
      q.push(p);
      int w = fail[x];
      while (w && !tr[w][i]) w = fail[w];
      fail[p] = tr[w][i];
    }
    ljb(x, fail[x]), ljb(fail[x], x);
  }
  return;
}
int dfn[A], size[A], all;
inline void DFS(int fa, int x) {
  dfn[x] = ++all, size[x] = 1;
  for (int y = head[x]; y; y = road[y].nex) {
    int z = road[y].to;
    if (z == fa) continue;
    DFS(x, z);
    size[x] += size[z];
  }
  return;
}
int tree[A];
inline int lowbit(int x) { return x & (-x); }
inline void add(int x, int v) {
  while (x <= all) {
    tree[x] += v;
    x += lowbit(x);
  }
  return;
}
inline int qurey(int x) {
  int ans = 0;
  while (x) {
    ans += tree[x];
    x -= lowbit(x);
  }
  return ans;
}
inline int find() {
  int ans = 0;
  int len = strlen(nw);
  int p = 0;
  for (int i = 0; i < len; i++) {
    p = tr[p][nw[i] - 'a'];
    ans += qurey(dfn[p]);
  }
  return ans;
}
signed main() {
  n = Read(), m = Read();
  for (int i = 1; i <= m; i++) {
    scanf("%s", nw);
    build(i);
  }
  acm();
  DFS(0, 0);
  for (int i = 1; i <= m; i++) {
    ex[i] = 1;
    int x = wr[i];
    add(dfn[x], 1);
    add(dfn[x] + size[x], -1);
  }
  while (n--) {
    char opt = getchar();
    while (opt != '?' && opt != '-' && opt != '+') opt = getchar();
    if (opt == '?') {
      scanf("%s", nw);
      printf("%d\n", find());
    } else if (opt == '+') {
      int k = Read();
      if (ex[k]) continue;
      ex[k] = 1;
      int x = wr[k];
      add(dfn[x], 1);
      add(dfn[x] + size[x], -1);
    } else {
      int k = Read();
      if (!ex[k]) continue;
      ex[k] = 0;
      int x = wr[k];
      add(dfn[x], -1);
      add(dfn[x] + size[x], 1);
    }
  }
  return 0;
}
