#include <bits/stdc++.h>
using namespace std;
const int SIGMA = 26;
struct trie {
trie *adj[SIGMA];
int frq, dp;
trie() {
frq = 0, dp = 0;
for(int i=0; i<SIGMA; i++) adj[i] = NULL;
}
};
trie *start = new trie;
void add(trie *node, char *w) {
if(*w=='\0') {
node -> frq ++;
return;
}
if(node -> adj[*w-'a'] == NULL) {
node -> adj[*w-'a'] = new trie;
node -> dp ++;
}
add(node -> adj[*w-'a'], w+1);
}
bool erase(trie *node, char *w) {
if(*w=='\0')
node -> frq --;
else if(node -> adj[*w-'a'] != NULL and erase(node -> adj[*w-'a'], w+1)) {
node -> adj[*w-'a'] = NULL;
node -> dp --;
}
if(node -> frq == 0 and node -> dp == 0 and node!=start) {
delete node;
return 1;
}
return 0;
}
int query(trie *node, char *w) {
if(*w=='\0') return node -> frq;
else if(node -> adj[*w-'a'] != NULL) return query(node -> adj[*w-'a'], w+1);
return 0;
}
int pref(trie *node, char *w, int lg) {
if(*w=='\0' or node -> adj[*w-'a']==NULL) return lg;
return pref(node -> adj[*w-'a'], w+1, lg+1);
}
int main() {
ifstream f("trie.in");
ofstream g("trie.out");
int op; char cuv[21];
while(f >> op >> cuv) {
if(op==0) add(start, cuv);
else if(op==1) erase(start, cuv);
else if(op==2) g << query(start, cuv) << "\n";
else if(op==3) g << pref(start,cuv,0) << "\n";
}
return 0;
}