#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
inline T1 max(T1 a, T2 b) {
  return a < b ? b : a;
}
template <typename T1, typename T2>
inline T1 min(T1 a, T2 b) {
  return a < b ? a : b;
}
const char lf = '\n';
namespace ae86 {
const int bufl = 1 << 15;
char buf[bufl], *s = buf, *t = buf;
inline int fetch() {
  if (s == t) {
    t = (s = buf) + fread(buf, 1, bufl, stdin);
    if (s == t) return EOF;
  }
  return *s++;
}
inline int ty() {
  int a = 0;
  int b = 1, c = fetch();
  while (!isdigit(c)) b ^= c == '-', c = fetch();
  while (isdigit(c)) a = a * 10 + c - 48, c = fetch();
  return b ? a : -a;
}
inline int tc() {
  int c = fetch();
  while (c <= 32 && c != EOF) c = fetch();
  return c;
}
inline string ts() {
  string s = "";
  int c = fetch();
  while (c <= 32 && c != EOF) c = fetch();
  while (c > 32 && c != EOF) s.push_back(c), c = fetch();
  return s;
}
}  // namespace ae86
using ae86::tc;
using ae86::ts;
using ae86::ty;
const int _ = 100007, __ = 1000007, alp = 26;
struct amata {
  int fa[__], ch[__][alp], tcnt;
  int val[__];
  int push(string s) {
    int now = 1;
    for (auto c_ : s) {
      int c = c_ - 'a';
      if (!ch[now][c]) ch[now][c] = ++tcnt;
      now = ch[now][c];
    }
    val[now]++;
    return now;
  }
  vector<int> e[__];
  void make() {
    queue<int> q;
    fa[1] = 1;
    for (int i = 0; i < alp; i++) {
      if (ch[1][i])
        fa[ch[1][i]] = 1, q.emplace(ch[1][i]);
      else
        ch[1][i] = 1;
    }
    while (!q.empty()) {
      int a = q.front();
      q.pop();
      for (int i = 0; i < alp; i++) {
        int b = ch[a][i];
        if (b)
          fa[b] = ch[fa[a]][i], val[b] += val[fa[b]], q.emplace(b);
        else
          ch[a][i] = ch[fa[a]][i];
      }
    }
    for (int i = 2; i <= tcnt; i++) e[fa[i]].emplace_back(i);
  }
  int finding(string s) {
    int now = 1, ans = 0;
    for (auto c_ : s) {
      int c = c_ - 'a';
      now = ch[now][c], ans += val[now];
    }
    return ans;
  }
  int got[__] = {0};
  void change(int x, int d) {
    queue<int> q;
    q.emplace(x);
    while (!q.empty()) {
      int a = q.front();
      q.pop();
      val[a] += d;
      for (auto b : e[a])
        if (!got[b]) q.emplace(b), got[b] = 1;
      got[a] = 0;
    }
  }
  amata() {
    memset(this, 0, sizeof(amata));
    tcnt = 1;
  }
} t;
int n, qn, loc[_] = {0}, ali[_] = {0};
string str[_];
int main() {
  ios::sync_with_stdio(0), cout.tie(nullptr);
  qn = ty(), n = ty();
  for (int i = 1; i <= n; i++)
    str[i] = ts(), loc[i] = t.push(str[i]), ali[i] = 1;
  t.make();
  for (int qq = 1; qq <= qn; qq++) {
    int op = tc();
    if (op == '?') cout << t.finding(ts()) << lf;
    if (op == '-') {
      int a = ty();
      if (ali[a]) ali[a] = 0, t.change(loc[a], -1);
    }
    if (op == '+') {
      int a = ty();
      if (!ali[a]) ali[a] = 1, t.change(loc[a], 1);
    }
  }
  return 0;
}
