#include <fstream>
#include <iostream>
using namespace std;
ifstream fin("trie.in");
ofstream fout("trie.out");
struct trie {
int fii, nr;
trie *f[26];
trie() {
fii = nr = 0;
for (int i=0;i<26;i++)
f[i] = NULL;
}
};
trie *t = new trie;
char s[23];
int tip, x;
trie *root = t;
void insertTrie(trie *&t, char *p) {
if (*p != 0) {
if (t->f[*p - 'a'] == NULL) {
t->fii++;
t->f[*p - 'a'] = new trie;
}
insertTrie(t->f[*p - 'a'], p+1);
} else
t->nr++;
}
int deleteTrie(trie *&t, char *p) {
if (*p != 0) {
if (deleteTrie(t->f[*p - 'a'], p+1)) {
t->fii--;
if (t->fii == 0 && t->nr == 0 && t!=root) {
delete t;
t = 0;
return 1;
}
}
} else {
t->nr--;
if (t->nr == 0) {
if (t->fii == 0 && t!= root) {
delete t;
t = 0;
return 1;
}
}
}
return 0;
}
int queryTrie(trie *t, char *p) {
if (*p != 0) {
if (t->f[*p - 'a'] == NULL) {
return 0;
}
return queryTrie(t->f[*p - 'a'], p+1);
} else
return t->nr;
}
int prefixTrie(trie *t, char *p) {
if (*p != 0) {
if (t->f[*p - 'a'] == NULL) {
return 0;
}
return 1 + prefixTrie(t->f[*p - 'a'], p+1);
} else
return 0;// ???
}
int main() {
while (fin>>tip>>s) {
x++;
//cout<<x<<" "<<tip<<" "<<s<<"\n";
if (tip == 0) {
// insert
insertTrie(t, s);
} else
if (tip == 1) {
deleteTrie(t, s);
} else
if (tip == 2) {
fout<<queryTrie(t, s)<<"\n";
} else {
fout<<prefixTrie(t, s)<<"\n";
}
}
return 0;
}