#include <bits/stdc++.h>
using namespace std;
ifstream fin("trie.in");
ofstream fout("trie.out");
struct trieNode{
int wordsContained, wordsEnd;
trieNode *next[26];
trieNode(){
wordsContained=0;
wordsEnd=0;
for(int i=0;i<26;i++)
next[i]=NULL;
}
};
void addTrie(trieNode *&node, char *word){
node->wordsContained++;
if(*word==0){
node->wordsEnd++;
return;
}
int nextIndex=word[0]-'a';
if(node->next[nextIndex]==NULL)
node->next[nextIndex]=new trieNode;
addTrie(node->next[nextIndex],word+1);
}
void removeTrie(trieNode *&node, char *word){
node->wordsContained--;
if(*word==0){
node->wordsEnd--;
return;
}
int nextIndex=word[0]-'a';
removeTrie(node->next[nextIndex],word+1);
if(node->next[nextIndex]->wordsContained==0){
trieNode *p=node->next[nextIndex];
node->next[nextIndex]=NULL;
delete p;
}
}
int appTrie(trieNode *&node, char *word){
if(*word==0){
return node->wordsEnd;
}
int nextIndex=word[0]-'a';
if(node->next[nextIndex]==NULL)
return 0;
return appTrie(node->next[nextIndex],word+1);
}
int longestCommonPrefix(trieNode *&node, char *word){
if(*word==0)
return 0;
int nextIndex=word[0]-'a';
if(node->next[nextIndex]==NULL)
return 0;
return 1+longestCommonPrefix(node->next[nextIndex],word+1);
}
int main()
{
int cerinta;
char word[25]={};
trieNode *start=new trieNode;
while(fin>>cerinta){
fin>>word;
if(cerinta==0)
addTrie(start,word);
else if(cerinta==1)
removeTrie(start,word);
else if(cerinta==2)
fout<<appTrie(start,word)<<'\n';
else if(cerinta==3)
fout<<longestCommonPrefix(start,word)<<'\n';
}
fin.close();
fout.close();
return 0;
}