#include <fstream>
using namespace std;
struct trie{
int ncuv, nfii;
trie *fiu[26];
} *t;
char s[31];
bool sters;
void add(trie *nod, char *p);
int cate(trie *nod, char *p);
int prefix(trie *nod, char *p, int lg);
void init(trie *nod);
void del(trie *nod, char *p);
int main()
{
int cod;
ifstream fin("trie.in");
ofstream fout("trie.out");
t = new trie;
init(t);
while(fin.getline(s, 30)){
cod = s[0]-'0';
if(cod==0) add(t, s+2);
if(cod==1) sters = false, del(t, s+2);
if(cod==2) fout<<cate(t, s+2)<<'\n';
if(cod==3) fout<<prefix(t, s+2, 0)<<'\n';
}
return 0;
}
void del(trie *nod, char *p){
if(*p=='\0'){
nod->ncuv--;
if(nod->nfii==0 && nod->ncuv==0){
delete nod;
sters = true;
return;
}
}
int index = *p - 'a';
del(nod->fiu[index], p+1);
if(sters==true){
nod->fiu[index] = NULL;
nod->nfii--;
if(nod->nfii==0 && nod->ncuv==0){
delete nod;
return;
}
}
sters = false;
}
int prefix(trie *nod, char *p, int lg){
if(*p=='\0') return lg;
int index = *p-'a';
if(nod->fiu[index]==NULL) return lg;
return prefix(nod->fiu[index], p+1, lg+1);
}
int cate(trie *nod, char *p){
if(*p=='\0') return nod->ncuv;
int index = *p-'a';
if(nod->fiu[index]==NULL) return 0;
return cate(nod->fiu[index], p+1);
}
void add(trie *nod, char *p){
if(*p=='\0') {nod->ncuv++; return;}
int index = *p-'a';
if(nod->fiu[index]==NULL){
nod->nfii++;
nod->fiu[index] = new trie;
init(nod->fiu[index]);
}
add(nod->fiu[index], p+1);
}
void init(trie *nod){
nod->ncuv = nod->nfii = 0;
for(int i=0; i<26; i++) nod->fiu[i]=NULL;
}