#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxN 130002
#define maxL 22
#define sigma 26
using namespace std;
int n, i, j, r, tsize = 1, st[maxN], top;
char w[maxL];
typedef struct
{
int c[sigma], p;
unsigned short val;
char nc;
} trie;
trie t[maxN];
void insert(char *s)
{
int ind = 1, C;
for ( ; *s; ++ s)
{
C = *s - 'a';
if (!t[ind].c[C])
{
if (top)
{
t[ind].c[C] = st[top];
-- top;
}
else
t[ind].c[C] = ++ tsize;
t[t[ind].c[C]].p = ind;
++ t[ind].nc;
}
ind = t[ind].c[C];
}
++ t[ind].val;
}
void erase(char *s)
{
int ind = 1;
for (; *s; s++)
ind = t[ind].c[*s - 'a'];
-- t[ind].val;
while (!t[ind].val && !t[ind].nc && (ind != 1))
{
-- s;
st[++ top] = ind;
ind = t[ind].p;
t[ind].c[*s - 'a'] = 0;
-- t[ind].nc;
}
}
int count(char *s)
{
int ind = 1;
while (*s && t[ind].c[*s - 'a'])
{
ind = t[ind].c[*s - 'a'];
++ s;
}
if (*s)
return 0;
return t[ind].val;
}
int prefix(char *s)
{
int ind = 1;
char *S = s;
while (*s && t[ind].c[*s - 'a'])
{
ind = t[ind].c[*s - 'a'];
++ s;
}
return s - S;
}
void rsw()
{
freopen("trie.in", "r", stdin);
freopen("trie.out", "w", stdout);
while (1)
{
r = -1;
scanf("%d %s\n", &r, &w);
if (r == -1)
return ;
if (r == 0)
insert(w);
else
if (r == 1)
erase(w);
else
if (r == 2)
printf("%d\n", count(w));
else
printf("%d\n", prefix(w));
}
}
int main()
{
rsw();
return 0;
}