#include <bits/stdc++.h>
using namespace std;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);
struct AhoCorasick {
  static const int SIZE = 30;
  struct State {
    int index;
    int next[SIZE];
    vector<int> accept;
    int cnt;
    State(int index) : index(index), cnt(0) { memset(next, -1, sizeof(next)); }
  };
  bool build;
  vector<State> pma;
  vector<int> lens;
  vector<vector<int> > use;
  vector<bool> exist;
  AhoCorasick() {
    build = false;
    pma.clear();
    pma.push_back(State(0));
    lens.clear();
  }
  void Insert(int t, int v) {
    pma[t].accept.push_back(v);
    pma[t].cnt = pma[t].accept.size();
    use[v].push_back(t);
  }
  void Add(int v) {
    if (exist[v]) {
      return;
    }
    for (__typeof((use[v]).begin()) it = (use[v]).begin(); it != (use[v]).end();
         it++) {
      pma[*it].cnt++;
    }
    exist[v] = true;
  }
  void Erase(int v) {
    if (!exist[v]) {
      return;
    }
    for (__typeof((use[v]).begin()) it = (use[v]).begin(); it != (use[v]).end();
         it++) {
      pma[*it].cnt--;
    }
    exist[v] = false;
  }
  void AddString(const char *str) {
    assert(!build);
    int t = 0;
    for (int i = 0; str[i]; i++) {
      int c = str[i];
      if (pma[t].next[c] == -1) {
        int m = pma.size();
        pma[t].next[c] = m;
        pma.push_back(State(m));
      }
      t = pma[t].next[c];
    }
    use.push_back(vector<int>());
    exist.push_back(true);
    Insert(t, lens.size());
    lens.push_back(strlen(str));
  }
  void BuildPMA() {
    assert(!build);
    queue<int> que;
    for (int c = 1; c < SIZE; c++) {
      if (pma[0].next[c] != -1) {
        pma[pma[0].next[c]].next[0] = 0;
        que.push(pma[0].next[c]);
      } else {
        pma[0].next[c] = 0;
      }
    }
    while (!que.empty()) {
      int t = que.front();
      que.pop();
      for (int c = 1; c < SIZE; c++) {
        if (pma[t].next[c] != -1) {
          que.push(pma[t].next[c]);
          int r = pma[t].next[0];
          while (pma[r].next[c] == -1) {
            r = pma[r].next[0];
          }
          pma[pma[t].next[c]].next[0] = pma[r].next[c];
          for (__typeof((pma[pma[r].next[c]].accept).begin()) it =
                   (pma[pma[r].next[c]].accept).begin();
               it != (pma[pma[r].next[c]].accept).end(); it++) {
            Insert(pma[t].next[c], *it);
          }
        }
      }
    }
    build = true;
  }
  int OneMove(int index, int c) {
    return pma[index].next[c] != -1
               ? pma[index].next[c]
               : pma[index].next[c] = OneMove(pma[index].next[0], c);
  }
  long long Match(const char *t) {
    assert(build);
    int index = 0;
    long long ret = 0;
    int n = strlen(t);
    for (int i = 0; i < n; i++) {
      int c = t[i];
      index = OneMove(index, c);
      ret += pma[index].cnt;
    }
    return ret;
  }
};
int n, q;
AhoCorasick aho;
char str[1000010];
void Convert() {
  int pos = 0;
  while (str[pos]) {
    str[pos] -= 'a' - 1;
    pos++;
  }
}
int main() {
  while (scanf("%d %d", &q, &n) > 0) {
    aho = AhoCorasick();
    for (int i = 0; i < (int)(n); i++) {
      scanf("%s", str);
      Convert();
      aho.AddString(str);
    }
    aho.BuildPMA();
    for (int i = 0; i < (int)(q); i++) {
      scanf("%s", str);
      if (str[0] == '?') {
        Convert();
        printf("%I64d\n", aho.Match(str + 1));
      } else if (str[0] == '-') {
        aho.Erase(atoi(str + 1) - 1);
      } else if (str[0] == '+') {
        aho.Add(atoi(str + 1) - 1);
      } else {
        assert(false);
      }
    }
  }
}
