#include <bits/stdc++.h>
using namespace std;
template <int ALPHA>
struct aho {
  mutable function<int(char)> decode;
  struct node {
    int been, end, name, st, en;
    node *sufflink;
    node *nxt[ALPHA];
    vector<node *> adj;
    node(int a = 0, int b = 0, node *c = NULL) : been(a), end(b), sufflink(c) {
      for (int i = 0; i < ALPHA; i++) nxt[i] = NULL;
    }
  };
  int T;
  node *ROOT;
  vector<node *> end_nodes;
  vector<int> bit;
  vector<node *> nodes;
  aho() : ROOT(NULL), T(0) {}
  vector<string> keys;
  void add_string(string &x) {
    keys.push_back(x);
    __insert(ROOT, x);
  }
  void build() {
    queue<node *> q;
    ROOT->sufflink = ROOT;
    q.push(ROOT);
    while (q.empty() == false) {
      node *f = q.front();
      q.pop();
      if (f == ROOT) {
        for (int i = 0; i < ALPHA; i++) {
          if (f->nxt[i] != NULL) {
            q.push(f->nxt[i]);
          }
        }
      } else {
        for (int i = 0; i < ALPHA; i++) {
          if (f->nxt[i] != NULL) {
            node *temp = f->sufflink;
            while (temp->nxt[i] == NULL and temp != ROOT) {
              temp = temp->sufflink;
            }
            f->nxt[i]->sufflink = (temp->nxt[i] == NULL ? ROOT : temp->nxt[i]);
            q.push(f->nxt[i]);
          }
        }
      }
    }
    build_tree();
  }
  void build_tree() {
    for (int i = 0; i < nodes.size(); i++) {
      if (nodes[i]->sufflink != nodes[i])
        nodes[i]->sufflink->adj.push_back(nodes[i]);
      else
        nodes[i] == ROOT;
    }
    int x = 0;
    dfs(ROOT, x);
    bit = vector<int>(nodes.size() + 3, 0);
    for (int i = 0; i < nodes.size(); i++)
      range_update(nodes[i]->st, nodes[i]->en, nodes[i]->end);
  }
  void update(int idx, int val) {
    if (idx == 0) return;
    while (idx <= nodes.size()) {
      bit[idx] += val;
      idx += idx & -idx;
    }
  }
  int query(int idx) {
    int res = 0;
    while (idx) {
      res += bit[idx];
      idx -= idx & -idx;
    }
    return res;
  }
  void range_update(int a, int b, int val) {
    update(a, val);
    update(b + 1, -val);
  }
  void dfs(node *root, int &pool) {
    root->st = ++pool;
    for (auto &elem : root->adj) {
      dfs(elem, pool);
    }
    root->en = pool;
  }
  void add(int idx) {
    end_nodes[idx - 1]->end++;
    range_update(end_nodes[idx - 1]->st, end_nodes[idx - 1]->en, 1);
  }
  void remove(int idx) {
    end_nodes[idx - 1]->end--;
    range_update(end_nodes[idx - 1]->st, end_nodes[idx - 1]->en, -1);
  }
  int __query(node *root, string &p, int d = 0) {
    if (!root) assert(false);
    int res = query(root->st);
    if (d == p.size()) return res;
    int x = decode(p[d]);
    if (root->nxt[x] == NULL) {
      while (root != ROOT and root->nxt[x] == NULL) {
        root = root->sufflink;
      }
      if (root->nxt[x] == NULL) return res + __query(ROOT, p, d + 1);
    }
    return res + __query(root->nxt[x], p, d + 1);
  }
  int query(string &p) { return __query(ROOT, p); }
  void __insert(node *&root, string &s, int d = 0) {
    if (!root) {
      root = new node(0, 0, ROOT);
      root->name = ++T;
      nodes.push_back(root);
    }
    root->been++;
    if (d == s.size()) {
      root->end++;
      end_nodes.push_back(root);
      return;
    }
    __insert(root->nxt[decode(s[d])], s, d + 1);
  }
};
const int MAXN = 1e6 + 3;
aho<26> AC;
char buf[MAXN];
string surnames[MAXN];
int n, q;
bool pres[MAXN];
int main() {
  AC.decode = [&](char x) { return x - 'a'; };
  int x;
  char opt;
  string temp;
  scanf("%d %d", &q, &n);
  for (int i = 1; i <= n; i++) {
    scanf(" %s", buf);
    temp = string(buf);
    AC.add_string(temp);
    pres[i] = true;
  }
  AC.build();
  while (q--) {
    scanf(" %c", &opt);
    if (opt == '+') {
      scanf("%d", &x);
      if (pres[x] == false) {
        pres[x] = true;
        AC.add(x);
      }
    } else if (opt == '-') {
      scanf("%d", &x);
      if (pres[x]) {
        pres[x] = false;
        AC.remove(x);
      }
    } else {
      scanf("%s", buf);
      temp = string(buf);
      printf("%d\n", AC.query(temp));
    }
  }
  return 0;
}
