#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5, K = 1e6 + 50, M = 26;
int n, k, node = 1, nxt[K][M], f[K], cnt[K], idx[N], st[K], fn[K], timer,
          seg[K << 2], lazy[K << 2], plc[K];
bool mark[N];
vector<int> adj[K];
void add_trie(string &s, int dex, int v = 0) {
  for (auto ch : s) {
    if (!nxt[v][ch - 'a']) nxt[v][ch - 'a'] = node++;
    v = nxt[v][ch - 'a'];
  }
  cnt[v]++;
  idx[dex] = v;
}
void find_dfa() {
  queue<int> q;
  for (int i = 0; i < M; i++)
    if (nxt[0][i]) q.push(nxt[0][i]), cnt[nxt[0][i]] += cnt[0];
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    adj[f[v]].push_back(v);
    for (int i = 0; i < M; i++) {
      if (nxt[v][i]) {
        f[nxt[v][i]] = nxt[f[v]][i];
        cnt[nxt[v][i]] += cnt[nxt[f[v]][i]];
        q.push(nxt[v][i]);
      } else
        nxt[v][i] = nxt[f[v]][i];
    }
  }
}
void dfs(int v) {
  st[v] = timer++;
  plc[st[v]] = v;
  for (auto u : adj[v]) dfs(u);
  fn[v] = timer;
}
void build(int id = 1, int b = 0, int e = timer) {
  if (e - b == 1) {
    seg[id] = cnt[plc[b]];
    return;
  }
  int mid = (b + e) >> 1, lc = id * 2, rc = lc | 1;
  build(lc, b, mid);
  build(rc, mid, e);
  seg[id] = seg[lc] + seg[rc];
}
void shift(int id, int b, int e) {
  if (lazy[id] != 0) {
    int mid = (e + b) >> 1, lc = id * 2, rc = lc | 1;
    seg[lc] += (mid - b) * lazy[id];
    seg[rc] += (e - mid) * lazy[id];
    lazy[lc] += lazy[id];
    lazy[rc] += lazy[id];
    lazy[id] = 0;
  }
}
void add(int l, int r, int val, int id = 1, int b = 0, int e = timer) {
  if (l >= e || b >= r) return;
  if (l <= b && e <= r) {
    seg[id] += val * (e - b);
    lazy[id] += val;
    return;
  }
  shift(id, b, e);
  int mid = (b + e) >> 1, lc = id * 2, rc = lc | 1;
  add(l, r, val, lc, b, mid);
  add(l, r, val, rc, mid, e);
  seg[id] = seg[lc] + seg[rc];
}
int get(int pos, int id = 1, int b = 0, int e = timer) {
  if (e - b == 1) return seg[id];
  shift(id, b, e);
  int mid = (b + e) >> 1, lc = id * 2, rc = lc | 1;
  if (pos < mid)
    return get(pos, lc, b, mid);
  else
    return get(pos, rc, mid, e);
}
void iterate(string &A) {
  int v = 0;
  long long ans = 0;
  for (auto ch : A) {
    v = nxt[v][ch - 'a'];
    ans += get(st[v]);
  }
  cout << ans << "\n";
}
string s[N];
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n >> k;
  for (int i = 0; i < k; i++) {
    cin >> s[i];
    add_trie(s[i], i);
    mark[i] = true;
  }
  find_dfa();
  dfs(0);
  build();
  while (n--) {
    char type;
    int id;
    cin >> type;
    if (type == '?') {
      string A;
      cin >> A;
      iterate(A);
    } else {
      cin >> id;
      id--;
      int l = st[idx[id]], r = fn[idx[id]];
      if (type == '+') {
        if (mark[id]) continue;
        add(l, r, 1);
        mark[id] = true;
      } else {
        if (!mark[id]) continue;
        add(l, r, -1);
        mark[id] = false;
      }
    }
  }
}
