#include <bits/stdc++.h>
using namespace std;
template <class T, class L>
bool smax(T &x, L y) {
  return x < y ? (x = y, 1) : 0;
}
template <class T, class L>
bool smin(T &x, L y) {
  return y < x ? (x = y, 1) : 0;
}
const int maxn = 1e6 + 17, sq = 317, z = 26;
string s[maxn];
int n, f[maxn], nxt[maxn][z], trie_size = 1, q[maxn], ver[maxn], iman[maxn],
                              st[maxn], en[maxn];
vector<int> g[maxn];
bool in[maxn];
void dfs_order(int v = 0) {
  static int tim = 0;
  st[v] = tim++;
  for (auto u : g[v]) dfs_order(u);
  en[v] = tim;
}
void majid(int p, int v) {
  for (p++; p < maxn; p += p & -p) iman[p] += v;
}
void majid(int l, int r, int v) { majid(l, v), majid(r, -v); }
int hamid(int p) {
  int ans = 0;
  for (p++; p; p ^= p & -p) ans += iman[p];
  return ans;
}
void aho() {
  for (int i = 0; i < n; i++) {
    int p = 0;
    for (auto c : s[i])
      p = nxt[p][c - 'a'] ? nxt[p][c - 'a'] : nxt[p][c - 'a'] = trie_size++;
    ver[i] = p;
  }
  int h = 0, t = 0;
  for (int i = 0; i < z; i++)
    if (nxt[0][i]) q[t++] = nxt[0][i];
  while (h != t) {
    int v = q[h++];
    for (int i = 0; i < z; i++)
      if (nxt[v][i])
        f[nxt[v][i]] = nxt[f[v]][i], q[t++] = nxt[v][i];
      else
        nxt[v][i] = nxt[f[v]][i];
  }
  for (int i = 1; i < trie_size; i++) g[f[i]].push_back(i);
  dfs_order();
  for (int i = 0; i < n; i++) majid(st[ver[i]], en[ver[i]], 1);
}
string p;
int main() {
  memset(in, 1, sizeof in);
  int nq;
  cin >> nq >> n;
  for (int i = 0; i < n; i++) cin >> s[i];
  aho();
  while (nq--) {
    char t;
    cin.get(t), cin.get(t);
    if (t == '+' || t == '-') {
      int id;
      cin >> id, id--;
      if (in[id] == (t == '+')) continue;
      majid(st[ver[id]], en[ver[id]], t == '+' ? 1 : -1);
      in[id] ^= 1;
      continue;
    }
    cin >> p;
    int pos = 0;
    long long ans = 0;
    for (auto c : p) ans += hamid(st[pos = nxt[pos][c - 'a']]);
    cout << ans << '\n';
  }
  return 0;
}
