#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int sz = 1e6 + 10;
const int MAX = 1e6 + 10;
char inp[sz];
string s;
vector<int> G[sz];
int st[sz], en[sz], vis[sz], tr[sz], Aho[sz / 10], tim;
void upd(int x, int v) {
  for (; x < sz; x += (x & -x)) tr[x] += v;
}
int qu(int x) {
  int ret = 0;
  for (; x > 0; x -= (x & -x)) ret += tr[x];
  return ret;
}
struct AhoCorasick {
  vector<int> mark[MAX + 7];
  int state, failure[MAX + 7];
  int trie[MAX + 7][26];
  int cnt[MAX + 7];
  AhoCorasick() { init(); }
  void init() {
    mark[0].clear();
    fill(trie[0], trie[0] + 26, -1);
    state = 0;
    tim = 0;
    memset(cnt, 0, sizeof cnt);
  }
  int value(char c) { return c - 'a'; }
  void add(const string &s, int t) {
    int root = 0, id;
    for (int i = 0; i < s.size(); i++) {
      id = value(s[i]);
      if (trie[root][id] == -1) {
        trie[root][id] = ++state;
        mark[state].clear();
        fill(trie[state], trie[state + 1] + 26, -1);
      }
      root = trie[root][id];
    }
    mark[root].push_back(t);
    cnt[root]++;
    Aho[t + 1] = root;
  }
  void computeFailure() {
    queue<int> Q;
    failure[0] = 0;
    for (int i = 0; i < 26; i++) {
      if (trie[0][i] != -1) {
        failure[trie[0][i]] = 0;
        Q.push(trie[0][i]);
      } else
        trie[0][i] = 0;
    }
    while (!Q.empty()) {
      int u = Q.front();
      G[failure[u]].push_back(u);
      Q.pop();
      for (int v : mark[failure[u]]) mark[u].push_back(v);
      for (int i = 0; i < 26; i++) {
        if (trie[u][i] != -1) {
          failure[trie[u][i]] = trie[failure[u]][i];
          Q.push(trie[u][i]);
        } else
          trie[u][i] = trie[failure[u]][i];
      }
    }
  }
  void graph(int u = 0) {
    vis[u] = 1;
    st[u] = ++tim;
    for (int v : G[u]) {
      if (!vis[v]) graph(v);
    }
    en[u] = tim;
    upd(st[u], cnt[u]);
    upd(en[u] + 1, -cnt[u]);
  }
  int ans(const string &s) {
    int ret = 0;
    for (int i = 0, root = 0, id; i < s.size(); i++) {
      id = value(s[i]);
      root = trie[root][id];
      if (root == 0) continue;
      ret += qu(st[root]);
    }
    return ret;
  }
} automata;
int main() {
  ios_base ::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, k;
  string q;
  char c;
  int ind, x;
  while (cin >> n >> k) {
    automata.init();
    for (int i = 0; i < k; i++) {
      cin >> s;
      automata.add(s, i);
    }
    automata.computeFailure();
    automata.graph();
    memset(vis, 0, sizeof vis);
    while (n--) {
      cin >> c;
      if (c == '+') {
        cin >> ind;
        cin.ignore();
        if (!vis[ind]) continue;
        vis[ind] = 0;
        x = Aho[ind];
        upd(st[x], +1);
        upd(en[x] + 1, -1);
      } else if (c == '-') {
        cin >> ind;
        cin.ignore();
        if (vis[ind]) continue;
        vis[ind] = 1;
        x = Aho[ind];
        upd(st[x], -1);
        upd(en[x] + 1, +1);
      } else {
        cin >> q;
        cout << automata.ans(q) << "\n";
      }
    }
    cerr << "----\n";
  }
  return 0;
}
