#include <cstdio>
#include <cstring>
using namespace std;
struct Nod{
int nr;
Nod* vecini[26];
Nod(){
nr = 0;
for(int i = 0; i < 26; i++){
vecini[i] = NULL;
}
}
bool hasChildren(){
for(int i = 0; i < 26; i++){
if(vecini[i] != NULL){
return true;
}
}
return false;
}
};
class Trie{
private:
Nod* root;
bool deleteWordx(char x[25], Nod* nod){
if(x[0] == 0){
nod->nr--;
}
else if(deleteWordx(x + 1, nod->vecini[x[0] - 'a']) == 1){
nod->vecini[x[0] - 'a'] = 0;
}
if(nod->nr == 0 && nod->hasChildren() == false && nod != root){
return 1;
}
return 0;
}
public:
Trie(){
root = new Nod();
}
void deleteWord(char x[25]){
deleteWordx(x, root);
}
void insertWord(char x[25]){
Nod* nod = root;
int l = strlen(x);
for(int i = 0; i < l; i++){
int m = x[i] - 'a';
if(nod->vecini[m] == NULL){
nod->vecini[m] = new Nod();
nod = nod->vecini[m];
}
else{
nod = nod->vecini[m];
}
}
nod->nr++;
}
int lungimePrefix(char x[25]){
Nod* nod = root;
int l = strlen(x);
for(int i = 0; i < l; i++){
int m = x[i] - 'a';
if(nod->vecini[m] == NULL){
return i;
}
else{
nod = nod->vecini[m];
}
}
return l;
}
int numarAparitii(char x[25]){
Nod* nod = root;
int l = strlen(x);
for(int i = 0; i < l; i++){
int m = x[i] - 'a';
if(nod->vecini[m] == NULL){
return 0;
}
else{
nod = nod->vecini[m];
}
}
return nod->nr;
}
}trie;
int main() {
freopen("trie.in", "r", stdin);
freopen("trie.out", "w", stdout);
char tmp[25];
tmp[0] = 0;
fgets(tmp, 25, stdin);
while(tmp[0] != 0){
tmp[strlen(tmp) - 1] = 0;
int optiune;
char x[25];
sscanf(tmp, "%d %s", &optiune, &x);
switch(optiune){
case 0:
trie.insertWord(x);
break;
case 1:
trie.deleteWord(x);
break;
case 2:
printf("%d\n", trie.numarAparitii(x));
break;
case 3:
printf("%d\n", trie.lungimePrefix(x));
break;
}
tmp[0] = 0;
fgets(tmp, 25, stdin);
}
return 0;
}