#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000020;
const int maxx = 1000000;
const int MOd = 1e9 + 7;
const int K = 1000;
const int P = 143;
int loc[maxn];
class Aho_Corasick {
 public:
  int last, next[maxn][26];
  short used[maxn][26], step;
  int deg[maxn], dad[maxn];
  int dep, fail[maxn];
  char name[maxn];
  int now[maxn], pre[maxn], E, go[maxn];
  int beg[maxn], end[maxn], cnt;
  int n, segment[1 << 21];
  vector<int> w[maxn];
  void update(int k, int x) {
    for (int l = beg[k] + n - 1, r = end[k] + n - 1; l <= r;
         l = (l + 1) >> 1, r = (r - 1) >> 1) {
      if (l & 1) segment[l] += x;
      if (~r & 1) segment[r] += x;
    }
  }
  inline void add(int i, int j) {
    pre[++E] = now[i];
    now[i] = E;
    go[E] = j;
  }
  void calc() {
    for (int l = 1; l <= dep; l++) {
      for (int i = now[l]; i; i = pre[i]) {
        int t = fail[dad[go[i]]];
        char c = name[go[i]];
        while (t && used[t][c] != step) t = fail[t];
        if (used[t][c] == step && next[t][c] != go[i]) t = next[t][c];
        fail[go[i]] = t;
        w[t].push_back(go[i]);
      }
    }
  }
  void dfs(int n) {
    beg[n] = ++cnt;
    for (int i = 0; i < w[n].size(); i++) dfs(w[n][i]);
    end[n] = cnt;
  }
  inline long long find(int k) {
    long long ret = 0;
    for (k += n - 1; k; k >>= 1) ret += segment[k];
    return ret;
  }
  void build(char *ar, int sz, int id) {
    int p = 0;
    for (int i = 1; i <= sz; i++) {
      char h = ar[i] - 'a';
      if (used[p][h] != step) {
        used[p][h] = step;
        next[p][h] = ++last;
        deg[last] = deg[p] + 1;
        dep = max(dep, (deg[last]));
        dad[last] = p;
        name[last] = h;
        add(deg[last], last);
      }
      p = next[p][h];
      if (i == sz) loc[id] = p;
    }
  }
  long long get(char *ar, int sz) {
    long long ret = 0;
    int p = 0;
    for (int i = 1; i <= sz; i++) {
      char c = ar[i] - 'a';
      while (p && used[p][c] != step) p = fail[p];
      if (used[p][c] == step) p = next[p][c];
      ret += find(beg[p]);
    }
    return ret;
  }
} trie;
int len[maxn];
bool exist[maxn], used[maxn];
char ch[maxn];
int q, a;
char *ar[maxn];
int main() {
  scanf("%d %d", &q, &a);
  trie.n = 1 << 20;
  trie.step = 1;
  for (int i = 1; i <= a; i++) {
    scanf(" %s", ch);
    exist[i] = 1;
    ar[i] = new char[strlen(ch) + 20];
    memset(ar[i], 0, sizeof(ar[i]));
    len[i] = strlen(ch);
    for (int j = 1; j <= len[i]; j++) {
      ar[i][j] = ch[j - 1];
      ch[j - 1] = 0;
    }
    trie.build(ar[i], len[i], i);
  }
  trie.calc();
  trie.dfs(0);
  for (int i = 1; i <= a; i++) trie.update(loc[i], 1);
  vector<int> w;
  while (q--) {
    char c;
    int x;
    scanf(" %c", &c);
    if (c == '?') {
      scanf(" %s", ch + 1);
      int l = strlen(ch + 1);
      cout << trie.get(ch, l) << endl;
    }
    if (c == '-' || c == '+') {
      scanf("%d", &x);
      if (c == '-' && exist[x]) trie.update(loc[x], -1), exist[x] = 0;
      if (c == '+' && !exist[x]) trie.update(loc[x], 1), exist[x] = 1;
    }
  }
  return 0;
}
