#include <bits/stdc++.h>
using namespace std;
bool debug = false;
int n, m;
bool ingov[1000005];
int trie[1000005][27];
int fail[1000005];
int triesz;
int val[1000005];
int settle[1000005];
int AC_addString(string& s, int id) {
  int v = 0;
  for (int i = 0; i < s.size(); i++) {
    if (!trie[v][s[i] - 'a']) {
      triesz++;
      trie[v][s[i] - 'a'] = triesz;
    }
    v = trie[v][s[i] - 'a'];
  }
  val[v] = id;
  return v;
}
void AC_getFail() {
  queue<int> q;
  fail[0] = 0;
  for (int i = 0; i < 26; i++) {
    if (trie[0][i]) {
      q.push(trie[0][i]);
      fail[trie[0][i]] = 0;
    }
  }
  while (!q.empty()) {
    int last = q.front();
    q.pop();
    for (int i = 0; i < 26; i++) {
      int ano = trie[last][i];
      if (!ano) {
        continue;
      }
      q.push(ano);
      int v = fail[last];
      while (v && !trie[v][i]) {
        v = fail[v];
      }
      fail[ano] = trie[v][i];
    }
  }
}
int bit[3000005];
int bit_sz;
void bit_add(int pos, int val) {
  while (pos <= bit_sz) {
    bit[pos] += val;
    pos += pos & (-pos);
  }
}
int bit_sum(int pos) {
  int ans = 0;
  while (pos) {
    ans += bit[pos];
    pos -= pos & (-pos);
  }
  return ans;
}
vector<int> nei[1000005];
int in[1000005], out[1000005];
int timestamp;
void FT_processEdge() {
  for (int i = 0; i <= triesz; i++) {
    if (fail[i] != i) {
      nei[fail[i]].push_back(i);
      nei[i].push_back(fail[i]);
    }
  }
}
void FT_dfs(int pos, int par) {
  timestamp++;
  in[pos] = timestamp;
  for (int i = 0; i < nei[pos].size(); i++) {
    if (nei[pos][i] == par) {
      continue;
    }
    FT_dfs(nei[pos][i], pos);
  }
  timestamp++;
  out[pos] = timestamp;
}
void bit_print() {
  for (int i = 0; i <= bit_sz; i++) {
    cout << bit[i] << " ";
  }
  cout << endl;
}
int main(int argc, char* argv[]) {
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    string s;
    cin >> s;
    int node = AC_addString(s, i + 1);
    settle[i] = node;
  }
  AC_getFail();
  FT_processEdge();
  FT_dfs(0, -1);
  bit_sz = triesz * 2;
  for (int i = 0; i < m; i++) {
    bit_add(in[settle[i]], 1);
    bit_add(out[settle[i]], -1);
    ingov[i] = true;
  }
  for (int i = 0; i < n; i++) {
    string query;
    cin >> query;
    if (query[0] == '?') {
      int v = 0;
      int ans = 0;
      string x = query.substr(1);
      for (int i = 0; i < x.size(); i++) {
        while (v && !trie[v][x[i] - 'a']) {
          v = fail[v];
        }
        v = trie[v][x[i] - 'a'];
        ans += bit_sum(in[v]);
      }
      cout << ans << endl;
    }
    if (query[0] == '+') {
      int toadd = atoi(query.substr(1).c_str());
      toadd--;
      if (!ingov[toadd]) {
        ingov[toadd] = true;
        bit_add(in[settle[toadd]], 1);
        bit_add(out[settle[toadd]], -1);
      }
    }
    if (query[0] == '-') {
      int toadd = atoi(query.substr(1).c_str());
      toadd--;
      if (ingov[toadd]) {
        ingov[toadd] = false;
        bit_add(in[settle[toadd]], -1);
        bit_add(out[settle[toadd]], 1);
      }
    }
  }
  return 0;
}
