#include <iostream>
#include <fstream>
using namespace std;
struct TrieNode
{
TrieNode* alphabet[26]={};
int cnt=0, children=0;
};
void insert(TrieNode *currNode, const string& word, int index)
{
if (index==word.length())
{
++currNode->cnt;
return;
}
++currNode->children;
if (currNode->alphabet[word[index]-'a']==nullptr)
{
currNode->alphabet[word[index]-'a']=new TrieNode;
}
insert(currNode->alphabet[word[index]-'a'], word, index+1);
}
void remove(TrieNode *currNode, const string& word, int index)
{
if (index==word.length())
{
--currNode->cnt;
if (currNode->cnt==0)
delete currNode;
return;
}
//if (index==word.length()-1 && currNode->alphabet[word[index]-'a']->cnt==1)
--currNode->children;
remove(currNode->alphabet[word[index]-'a'], word, index+1);
}
int frequency(TrieNode *currNode, const string& word, int index)
{
if (index==word.length())
return currNode->cnt;
if (currNode->alphabet[word[index]-'a']==nullptr)
return 0;
return frequency(currNode->alphabet[word[index]-'a'], word, index+1);
}
int longestPrefix(TrieNode *currNode, const string& word, int index)
{
if (currNode->alphabet[word[index]-'a']==nullptr)
return 0;
if (currNode->children>=2)
return max(index+1, longestPrefix(currNode->alphabet[word[index]-'a'], word, index+1));
return 0;
}
int main()
{
ifstream fin("trie.in");
ofstream fout("trie.out");
TrieNode *head=new TrieNode;
int op;
string word;
while (fin>>op>>word)
{
if (op==0)
{
insert(head, word, 0);
}
else if (op==1)
{
remove(head, word, 0);
}
else if (op==2)
{
fout<<frequency(head, word, 0)<<'\n';
}
else
{
fout<<longestPrefix(head, word, 0)<<'\n';
}
}
return 0;
}