#include <cstdio>
using namespace std;
struct nod_trie
{
static const int SIGMA = 'z' - 'a' + 1;
nod_trie* fii[SIGMA];
int cnt;
int nrfii;
nod_trie()
{
cnt = 0;
nrfii = 0;
for (int i = 0;i < SIGMA;++i)
fii[i] = NULL;
}
void adaugare(char *s)
{
if (*s == 0)
{
++cnt;
return;
}
int idc = *s - 'a';
if (fii[idc] == NULL)
{
fii[idc] = new nod_trie;
++nrfii;
}
fii[idc] -> adaugare(s + 1);
}
bool stergere(char *s) //returneaza adevarat daca stergerea va modifica structura trie-ului
{
if (*s == 0)
--cnt;
else
{
int idc = *s - 'a';
if (fii[idc] -> stergere(s + 1))//daca s-a sters un fiu, il scoatem
{
delete fii[idc];
fii[idc] = NULL;
--nrfii;
}
}
if (nrfii == 0 && cnt == 0)
return true;
return false;
}
int aparitii(char *s)
{
if (*s == 0)
return cnt;
int idc = *s - 'a';
if (fii[idc] != NULL)
return fii[idc] -> aparitii(s + 1);
return 0;
}
int prefix(char *s, int rasp)
{
int idc = *s - 'a';
if (*s == 0 || fii[idc] == NULL)
return rasp;
return fii[idc] -> prefix(s + 1,rasp + 1);
}
};
nod_trie * trie = new nod_trie;
const int MAXRAND = 32;
char rand[MAXRAND];
int main()
{
freopen("trie.in","r",stdin);
freopen("trie.out","w",stdout);
while(!feof(stdin))
{
for (int i = 0;i < MAXRAND;++i)
rand[i] = 0;
gets(rand);
char c = rand[0] - '0';
char *v = rand + 2;
if (c == 0)
trie -> adaugare(v);
else if (c == 1)
trie -> stergere(v);
else if (c == 2)
printf("%d\n",trie -> aparitii(v));
else if (c == 3)
printf("%d\n",trie -> prefix(v,0));
}
return 0;
}