#include <bits/stdc++.h>
using namespace std;
void file(string s) {
  freopen((s + ".in").c_str(), "r", stdin);
  freopen((s + ".out").c_str(), "w", stdout);
}
template <typename Tp>
void read(Tp &x) {
  long long fh = 1;
  char c = getchar();
  x = 0;
  while (c > '9' || c < '0') {
    if (c == '-') {
      fh = -1;
    }
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = (x << 1) + (x << 3) + (c & 15);
    c = getchar();
  }
  x *= fh;
}
long long n, m, T;
vector<long long> ft[1000005];
long long pos[1000005];
namespace FTree {
long long dfnl[1000005], dfnr[1000005], tot;
struct BIT {
  long long b[1000005];
  void add(long long x, long long v) {
    for (; x <= tot; x += (x & (-x))) b[x] += v;
  }
  long long ask(long long x) {
    long long ret = 0;
    for (; x; x -= (x & (-x))) ret += b[x];
    return ret;
  }
} Tr;
void dfs(long long x) {
  dfnl[x] = ++tot;
  for (unsigned i = 0; i < ft[x].size(); ++i) {
    long long y = ft[x][i];
    dfs(y);
  }
  dfnr[x] = tot;
}
void prep() {
  dfs(0);
  for (long long i = 1; i <= n; ++i) {
    Tr.add(dfnl[pos[i]], 1);
    Tr.add(dfnr[pos[i]] + 1, -1);
  }
}
void upd(long long x, long long v) {
  Tr.add(dfnl[x], v);
  Tr.add(dfnr[x] + 1, -v);
}
long long qry(long long x) { return Tr.ask(dfnl[x]); }
}  // namespace FTree
namespace ACAM {
signed ch[1000005][26], fail[1000005], tot;
long long ins(const char *str) {
  long long p = 0, nn = strlen(str), dir;
  for (long long i = 0; i < nn; ++i) {
    dir = str[i] - 'a';
    if (!ch[p][dir]) ch[p][dir] = ++tot;
    p = ch[p][dir];
  }
  return p;
}
void build() {
  queue<long long> q;
  for (long long i = 0; i < 26; ++i)
    if (ch[0][i]) q.push(ch[0][i]);
  while (!q.empty()) {
    long long x = q.front();
    q.pop();
    for (long long i = 0; i < 26; ++i) {
      if (ch[x][i]) {
        fail[ch[x][i]] = ch[fail[x]][i];
        q.push(ch[x][i]);
      } else {
        ch[x][i] = ch[fail[x]][i];
      }
    }
  }
  for (long long i = 1; i <= tot; ++i) ft[fail[i]].push_back(i);
  FTree::prep();
}
void mtch(const char *str) {
  long long p = 0, nn = strlen(str), ans = 0;
  for (long long i = 0; i < nn; ++i) {
    p = ch[p][str[i] - 'a'];
    ans += FTree::qry(p);
  }
  printf("%lld\n", ans);
}
}  // namespace ACAM
char sstr[1000005];
bool vis[1000005];
signed main() {
  read(T);
  read(n);
  for (long long i = 1; i <= n; ++i) {
    scanf("%s", sstr);
    pos[i] = ACAM::ins(sstr);
    vis[i] = 1;
  }
  ACAM::build();
  char op;
  for (long long i = 1, x; i <= T; ++i) {
    scanf("\n%c", &op);
    if (op == '?') {
      scanf("%s", sstr);
      ACAM::mtch(sstr);
    }
    if (op == '+') {
      read(x);
      if (!vis[x]) {
        FTree::upd(pos[x], 1), vis[x] = 1;
      }
    }
    if (op == '-') {
      read(x);
      if (vis[x]) {
        FTree::upd(pos[x], -1), vis[x] = 0;
      }
    }
  }
  return 0;
}
