#include <bits/stdc++.h>   const int N = 1000005;   using namespace std;   int n, m, t = 0, tot = 0, cnt = 0, q[N];   int dl[N], dr[N], vis[N][27];   int edge[N], nxt[N], lst[N], pt[N], fail[N], val[N], nm[N], vvis[N];   string s;   struct nn {     int lx, rx, num;   } tr[N << 2];   void add(int x, int y) {     edge[++t] = y;     nxt[t] = lst[x];     lst[x] = t;   }   void insert(string s, int id) {     int len = s.length(), pos = 0;     for (int i = 0; i < len; i++) {       int c = s[i] -  a  + 1;       if (!vis[pos][c]) tot++, vis[pos][c] = tot;       pos = vis[pos][c];     }     pt[id] = pos;     val[pos] = 1;   }   void build_trie() {     int pos = 0, l = 0, r = 0;     for (int i = 1; i <= 26; i++)       if (vis[pos][i]) {         r++;         q[r] = vis[pos][i];         fail[vis[pos][i]] = pos;         add(pos, vis[pos][i]);       }     while (l < r) {       l++;       pos = q[l];       for (int i = 1; i <= 26; i++) {         if (vis[pos][i]) {           int f = fail[pos];           while (f && !vis[f][i]) f = fail[f];           fail[vis[pos][i]] = vis[f][i];           add(vis[f][i], vis[pos][i]);           r++;           q[r] = vis[pos][i];         } else           vis[pos][i] = vis[fail[pos]][i];       }     }   }   void build_tree(int x, int num) {     cnt++;     dl[x] = dr[x] = cnt;     nm[dl[x]] = num;     for (int r = lst[x]; r; r = nxt[r]) {       build_tree(edge[r], num + val[edge[r]]);       dr[x] = max(dr[x], dr[edge[r]]);     }   }   void chang(int x, int l, int r, int l1, int r1, int yh) {     if (l1 <= l && r <= r1) {       tr[x].num += yh;       return;     }     int mid = (l + r) >> 1;     if (l1 > mid)       chang(tr[x].rx, mid + 1, r, l1, r1, yh);     else if (r1 <= mid)       chang(tr[x].lx, l, mid, l1, r1, yh);     else {       chang(tr[x].lx, l, mid, l1, mid, yh);       chang(tr[x].rx, mid + 1, r, mid + 1, r1, yh);     }     return;   }   void build_segtree(int x, int l, int r) {     if (l == r) {       tr[x].num = nm[l];       return;     }     int mid = (l + r) >> 1;     tr[x].lx = x + 1;     tr[x].rx = (mid - l + 1) * 2 + x;     build_segtree(tr[x].lx, l, mid);     build_segtree(tr[x].rx, mid + 1, r);   }   int chk(int x, int l, int r, int goal) {     int res = 0;     if (l == r) return tr[x].num;     res += tr[x].num;     int mid = (l + r) >> 1;     if (goal > mid) return res + chk(tr[x].rx, mid + 1, r, goal);     return res + chk(tr[x].lx, l, mid, goal);   }   int search(string s) {     int len = s.length(), pos = 0, ans = 0;     for (int i = 1; i < len; i++) {       int c = s[i] -  a  + 1;       pos = vis[pos][c];       ans += chk(1, 1, cnt, dl[pos]);     }     return ans;   }   int main() {     scanf( %d%d , &n, &m);     for (int i = 1; i <= m; i++) {       cin >> s;       insert(s, i);     }     build_trie();     build_tree(0, 0);     build_segtree(1, 1, cnt);     for (int i = 1; i <= n; i++) {       cin >> s;       if (s[0] ==  -  || s[0] ==  + ) {         int yh = 0, len = s.length();         for (int i = 1; i < len; i++) {           yh = yh * 10 + s[i] -  0 ;         }         if (s[0] ==  - )           if (vvis[yh] == 0)             chang(1, 1, cnt, dl[pt[yh]], dr[pt[yh]], -1), vvis[yh] = 1;         if (s[0] ==  + )           if (vvis[yh] == 1)             chang(1, 1, cnt, dl[pt[yh]], dr[pt[yh]], 1), vvis[yh] = 0;       } else {         printf( %d n , search(s));       }     }   }