#include <fstream>
#include <string>
#include <stdlib.h>
#define max 26
#define MAX 100000
using namespace std;
ifstream fin("trie.in");
ofstream fout("trie.out");
struct Trie{
int pass; // how many nodes pass through this node
int appear; // how many nodes end here
struct Trie *refs[max];
};
typedef struct Trie Trie;
Trie root;
void addWord(string word){
int index = 0, len = word.size();
Trie *t = &root;
while(index < len){
if(t->refs[word[index]-'a'] == NULL){
Trie *nou = (Trie*)malloc(1*sizeof(Trie));
nou->pass = 1;
nou->appear = 0;
for(int i = 0; i < max; i++)
nou->refs[i] = NULL;
t->refs[word[index]-'a'] = nou;
}else{
t->refs[word[index]-'a']->pass++;
}
// sets final node
if(index == len-1){
t->refs[word[index]-'a']->appear ++;
}
t = t->refs[word[index]-'a'];
index ++;
}
}
int printHowMany(string word){
Trie *t = &root;
int index = 0, len = word.size();
while(index < len && t != NULL){
t = t->refs[word[index]-'a'];
index ++;
}
if(index == len && t != NULL){
return t->appear;
}
return 0;
}
void deleteWord(string word){
Trie *t = &root, *next;
int index = 0, len = word.size();
if(printHowMany(word) == 0) return ;
while(index < len){
if(t->refs[word[index]-'a']->pass == 1){
if(t->refs[word[index]-'a']->appear > 0){
free(t->refs[word[index]-'a']);
t->refs[word[index]-'a'] = NULL;
}else{
for(int i = 0; i < 26; i++){
if(t->refs[word[index]-'a']->refs[i] != NULL){
next = t->refs[word[index]-'a']->refs[i];
free(t->refs[word[index]-'a']);
t->refs[word[index]-'a'] = NULL;
t->refs[i] = next;
break;
}
}
}
}else{
t->refs[word[index]-'a']->pass--;
if(index == len-1){
t->refs[word[index]-'a']->appear--;
}
t = t->refs[word[index]-'a'];
}
index++;
}
}
int printPrefix(string prefix){
Trie *t = &root;
int len = prefix.size(), index = 0, maxim = 0;
while(index < len){
if(t->refs[prefix[index] - 'a'] != NULL){
t = t->refs[prefix[index] - 'a'];
maxim++;
}else{
break;
}
index++;
}
return maxim;
}
void process(int which, string word){
switch(which){
case 0: addWord(word); break;
case 1: deleteWord(word); break;
case 2: fout << printHowMany(word) << "\n"; break;
case 3: fout << printPrefix(word) << "\n";
}
}
int main(){
int which, i = 16;
string word;
root.appear = 0;
root.pass = 0; // passul asta nu are relevanta pt root
for(int i = 0; i < max; i++)
root.refs[i] = NULL;
while(fin >> which >> word){
process(which, word);
i--;
}
return 0;
}