#include<cstdio>
#include<cstring>
using namespace std;
char w[30] ;
struct nod
{
int cheie , cuv;
nod *fiu[27] ;
nod()
{
cheie = cuv =0;
memset(fiu,0,sizeof(fiu));
}
};
int tip;
nod *rad = new nod();
void insert(nod *&T , char s[] , int i);
void del(nod *&T , char s[] ,int i);
int query(nod *T, char s[] , int i);
int prefix(nod *T, char s[] , int i,int k);
int main()
{
freopen("trie.in" , "r" , stdin );
freopen("trie.out" , "w" , stdout );
while(scanf("%d %s\n" , &tip , w)>0)
{
if(tip==0)insert(rad,w,-1);
if(tip==1)del(rad,w,-1);
if(tip==2)printf("%d\n" , query(rad,w,-1));
if(tip==3)printf("%d\n" , prefix(rad,w,-1,0));
}
return 0;
}
void insert(nod *&n , char s[] , int i)
{
n->cheie++;
if(!s[i+1])
{n->cuv++;return;}
if(!(n->fiu[s[i+1]-'a'+1]) || !s[i+1])n->fiu[s[i+1]-'a'+1] = new nod();
insert(n->fiu[s[i+1]-'a'+1],s,i+1);
}
void del(nod *&n , char s[] , int i)
{
n->cheie--;
if(!(n->fiu[s[i+1]-'a'+1]) || !s[i+1]){n->cuv--;return ;}
del(n->fiu[s[i+1]-'a'+1],s,i+1);
}
int query(nod *n , char s[] , int i)
{
if(n->fiu[s[i+1]-'a'+1] && s[i+1])
return query(n->fiu[s[i+1]-'a'+1],s,i+1);
if(!s[i+1])return n->cuv;
else return 0;
}
int prefix(nod *n, char s[] , int i ,int k )
{
if(n->fiu[s[i+1]-'a'+1] && s[i+1] && n->fiu[s[i+1]-'a'+1]->cheie)
return prefix(n->fiu[s[i+1]-'a'+1],s,i+1,k+1);
return k;
}