#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N=1e6+10;
int lowbit(int x){
return x&(-x);
}
struct sb{
int to,nxt;
}edge[N];
int head[N];
int ntt;
void add(int u,int v){
edge[++ntt]={v,head[u]};
head[u]=ntt;
}
bool is_end[N];
int dfn[N],conb[N],in[N],out[N];
int tmr;
void dfs(int x,int last,int ttt){
if(is_end[x]) ttt++;
dfn[x]=++tmr;
in[x]=tmr;
conb[tmr]=ttt;
for(int i=head[x];i!=-1;i=edge[i].nxt){
if(edge[i].to==last) continue;
dfs(edge[i].to,x,ttt);
}
out[x]=tmr;
}
struct node{
int son[26];
}trie[2*N];
int cnt;
int fail[N];
char str[N];
int ins(int &pos,int sp,int len,bool ch){
if(pos==0&&ch==true){
cnt++;
pos=cnt;
}
if(sp==len-1){
return pos;
}
return ins(trie[pos].son[str[sp+1]-'a'],sp+1,len,true);
}
queue<int> q;
int a[N];
bool exi[N];
int trans[N];
int root;
void upd(int x,int v){
while(x<=ntt){
a[x]+=v;
x+=lowbit(x);
}
}
int ask(int x){
int tmp=0;
while(x>0){
tmp+=a[x];
x-=lowbit(x);
}
return tmp;
}
void build_fail(){
while(!q.empty()) q.pop();
for(int i=0;i<26;i++){
if(trie[0].son[i]) q.push(trie[0].son[i]);
}
while(!q.empty()){
int now=q.front();
q.pop();
for(int i=0;i<26;i++){
if(!trie[now].son[i]) continue;
int j=fail[now];
while(j!=0&&!trie[j].son[i]){
j=fail[j];
}
fail[trie[now].son[i]]=trie[j].son[i];
in[trie[j].son[i]]++;
q.push(trie[now].son[i]);
}
}
for(int i=1;i<=cnt;i++){
add(i,fail[i]);
add(fail[i],i);
}
dfs(0,-1,0);
for(int i=1;i<=ntt;i++){
upd(i,conb[i]-conb[i-1]);
}
}
int vst[N];
char s[N];
int n,k,ml;
int comp(){
int tt=0,zyhlqr=0;
for(int i=0;i<ml;i++){
while(tt&&!trie[tt].son[s[i]-'a']) tt=fail[tt];
tt=trie[tt].son[s[i]-'a'];
zyhlqr+=ask(in[tt]);
}
return zyhlqr;
}
char xh[N];
int main(){
memset(head,-1,sizeof(head));
ios::sync_with_stdio(false);
cin>>n>>k;
for(int i=1;i<=k;i++){
cin>>str;
trans[i]=ins(root,-1,strlen(str),false);
is_end[trans[i]]=true;
exi[i]=true;
}
build_fail();
while(n--){
cin>>xh;
int tlen=strlen(xh);
if(xh[0]=='?'){
ml=0;
for(int i=1;i<tlen;i++){
s[ml++]=xh[i];
}
cout<<comp()<<'\n';
}else if(xh[0]=='+'){
int num=0;
for(int i=1;i<tlen;i++){
num*=10;
num+=xh[i]-'0';
}
if(exi[num]) continue;
exi[num]=true;
upd(in[trans[num]],1);
upd(out[trans[num]]+1,-1);
}else{
int num=0;
for(int i=1;i<tlen;i++){
num*=10;
num+=xh[i]-'0';
}
if(!exi[num]) continue;
exi[num]=false;
upd(in[trans[num]],-1);
upd(out[trans[num]]+1,1);
}
}
return 0;
}