#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 500;
char s[N];
int son[N][26];
int fail[N], pos[N];
int n, m;
int cnt;
inline void insert(char s[], int n, int id) {
  int i, cur = 0;
  for (i = 1; i <= n; i++) {
    if (!son[cur][s[i] - 'a']) son[cur][s[i] - 'a'] = ++cnt;
    cur = son[cur][s[i] - 'a'];
  }
  pos[id] = cur;
}
queue<int> Q;
inline void build() {
  int i;
  for (i = 0; i <= 25; i++)
    if (son[0][i]) Q.push(son[0][i]);
  while (!Q.empty()) {
    int x = Q.front();
    Q.pop();
    for (i = 0; i <= 25; i++)
      if (!son[x][i])
        son[x][i] = son[fail[x]][i];
      else
        fail[son[x][i]] = son[fail[x]][i], Q.push(son[x][i]);
  }
}
struct Edge {
  int to, nxt;
};
Edge e[N << 1];
int lst[N];
inline void add(int u, int v) {
  static int cnt = 0;
  e[++cnt] = (Edge){v, lst[u]}, lst[u] = cnt;
}
int dfn[N], low[N];
inline void dfs(int x) {
  static int idx = 0;
  int i;
  dfn[x] = ++idx;
  for (i = lst[x]; ~i; i = e[i].nxt) dfs(e[i].to);
  low[x] = idx;
}
int C[N];
inline void update(int x, int delta) {
  while (x <= cnt + 1) C[x] += delta, x += ((x) & -(x));
}
inline int query(int x) {
  int res = 0;
  while (x > 0) res += C[x], x -= ((x) & -(x));
  return res;
}
int del[N];
int main() {
  int i;
  scanf("%d%d", &m, &n);
  for (i = 1; i <= n; i++) scanf(" %s ", s + 1), insert(s, strlen(s + 1), i);
  build();
  for (i = 0; i <= cnt; i++) lst[i] = -1;
  for (i = 1; i <= cnt; i++) add(fail[i], i);
  dfs(0);
  for (i = 1; i <= n; i++) update(dfn[pos[i]], 1), update(low[pos[i]] + 1, -1);
  while (m--) {
    scanf(" %s ", s), n = strlen(s + 1);
    if (s[0] == '?') {
      int cur = 0, ans = 0;
      for (i = 1; i <= n; i++) {
        if (!son[cur][s[i] - 'a'])
          cur = fail[cur];
        else
          cur = son[cur][s[i] - 'a'];
        ans += query(dfn[cur]);
      }
      printf("%d\n", ans);
    } else {
      int id = 0;
      for (i = 1; i <= n; i++) id = (id << 1) + (id << 3) + (s[i] ^ 48);
      if (s[0] == '-') {
        if (!del[id])
          update(dfn[pos[id]], -1), update(low[pos[id]] + 1, 1), del[id] = 1;
      } else if (del[id])
        update(dfn[pos[id]], 1), update(low[pos[id]] + 1, -1), del[id] = 0;
    }
  }
  return 0;
}
