#include <bits/stdc++.h>
using namespace std;
struct node {
  int nxt[26];
  int suf_link;
  int id;
  int elink;
  bool leaf;
};
int n, k;
int bit[2000005];
int ti = 1;
vector<int> at[100005];
int st[1000005], en[1000005];
vector<int> adj[1000005];
node tree[1000005];
int cur = 0;
bool tak[100005];
queue<int> q;
string t, s;
void upd(int i, int x) {
  while (i > 0 && i <= 2e6 + 1) {
    bit[i] += x;
    i += (i & -i);
  }
}
int sum(int i) {
  int an = 0;
  while (i > 0) {
    an += bit[i];
    i -= (i & -i);
  }
  return an;
}
void dfs(int i) {
  st[i] = ti++;
  for (auto j : adj[i]) dfs(j);
  en[i] = ti++;
  if (tree[i].leaf == 0) return;
  upd(st[i], 1);
  upd(en[i] + 1, -1);
}
int make_new() {
  tree[cur].suf_link = -1;
  tree[cur].elink = 0;
  tree[cur].leaf = 0;
  for (int j = 0; j < 26; j++) tree[cur].nxt[j] = -1;
  cur++;
  return (cur - 1);
}
void add(string &a, int in) {
  int i = 0;
  for (int j = 0; j < a.length(); j++) {
    if (tree[i].nxt[a[j] - 'a'] == -1) tree[i].nxt[a[j] - 'a'] = make_new();
    i = tree[i].nxt[a[j] - 'a'];
  }
  at[in].push_back(i);
  tree[i].leaf = 1;
  tree[i].id = in;
}
int get_suflink(int i, int j) {
  if (i == -1) return 0;
  if (tree[i].nxt[j] != -1) return tree[i].nxt[j];
  return get_suflink(tree[i].suf_link, j);
}
void make_links() {
  q.push(0);
  while (!q.empty()) {
    int i = q.front();
    q.pop();
    for (int j = 0; j < 26; j++) {
      if (tree[i].nxt[j] != -1) {
        tree[tree[i].nxt[j]].suf_link = get_suflink(tree[i].suf_link, j);
        tree[tree[i].nxt[j]].elink =
            tree[tree[tree[i].nxt[j]].suf_link].leaf
                ? tree[tree[i].nxt[j]].suf_link
                : tree[tree[tree[i].nxt[j]].suf_link].elink;
        q.push(tree[i].nxt[j]);
      }
    }
  }
}
int check(int i, int j) {
  if (i == 0) return 0;
  if (tree[i].leaf) return i;
  return (tree[i].elink);
}
int work(string &t) {
  int an = 0;
  int i = 0;
  for (int j = 0; j < t.length(); j++) {
    if (tree[i].nxt[t[j] - 'a'] != -1)
      i = tree[i].nxt[t[j] - 'a'];
    else
      i = get_suflink(tree[i].suf_link, t[j] - 'a');
    int h = check(i, j);
    an += (sum(st[h]));
  }
  return an;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  cin >> k;
  make_new();
  for (int i = 1; i <= k; i++) {
    tak[i] = 1;
    cin >> s;
    add(s, i);
  }
  make_links();
  for (int i = 1; i < cur; i++) {
    adj[tree[i].elink].push_back(i);
  }
  dfs(0);
  for (int i = 1; i <= n; i++) {
    cin >> s;
    if (s[0] != '?') {
      char c = s[0];
      reverse(s.begin(), s.end());
      s.pop_back();
      reverse(s.begin(), s.end());
      int x = 0;
      for (auto j : s) {
        x = x * 10 + (j - '0');
      }
      if (c == '+') {
        if (!tak[x]) {
          tak[x] = 1;
          for (auto j : at[x]) {
            upd(st[j], 1);
            upd(en[j] + 1, -1);
          }
        }
      } else {
        if (tak[x]) {
          tak[x] = 0;
          for (auto j : at[x]) {
            upd(st[j], -1);
            upd(en[j] + 1, 1);
          }
        }
      }
    } else {
      reverse(s.begin(), s.end());
      s.pop_back();
      reverse(s.begin(), s.end());
      cout << work(s) << '\n';
    }
  }
  return 0;
}
