#include <iostream>
#include <fstream>
using namespace std;
ifstream in("trie.in");
ofstream out("trie.out");
struct node {
node *fii['z' - 'a' + 1];
int frecv;
int nr_fii;
node() {
frecv = 0;
nr_fii = 0;
for (int i = 0; i < 'z' - 'a' + 1; i++) {
fii[i] = nullptr;
}
}
};
void add_word(node* nod, const string& word, int i = 0) {
if (i == word.size()) {
nod->frecv++;
return;
}
if (nod->fii[word[i] - 'a'] == nullptr) {
node* temp = new node();
nod->fii[word[i] - 'a'] = temp;
nod->nr_fii++;
add_word(temp, word, i + 1);
}
else
add_word(nod->fii[word[i] - 'a'], word, i + 1);
}
void afis_word(node* nod, string word) {
if (nod->frecv > 0)
cout << word << " " << nod->frecv << endl;
for (int i = 0; i < 'z' - 'a' + 1; i++) {
if (nod->fii[i] == nullptr) continue;
afis_word(nod->fii[i], word + char(i + 'a'));
}
}
bool delete_word(node* nod, const string& word, int i = 0) {
if (i == word.size()) {
nod->frecv--;
return (nod->frecv <= 0 && nod->nr_fii == 0);
}
if (nod->fii[word[i] - 'a'] == nullptr) return false;
if (delete_word(nod->fii[word[i] - 'a'], word, i + 1)) {
delete nod->fii[word[i] - 'a'];
nod->fii[word[i] - 'a'] = nullptr;
nod->nr_fii--;
if (nod->frecv <= 0 && nod->nr_fii == 0) return true;
}
return false;
}
int get_frecv(node* nod, const string& word, int i = 0) {
if (i == word.size()) return nod->frecv;
if (nod->fii[word[i] - 'a'] == nullptr) return 0;
return get_frecv(nod->fii[word[i] - 'a'], word, i + 1);
}
int get_prefix(node* nod, const string& word, int i = 0) {
if (i == word.size()) {
return 0;
}
if (nod->fii[word[i] - 'a'] == nullptr) return 0;
return get_prefix(nod->fii[word[i] - 'a'], word, i + 1) + 1;
}
int main() {
node *root = new node();
int op;
while (in >> op) {
string s;
in >> s;
switch (op) {
case 0: {add_word(root, s); break;}
case 1: {delete_word(root, s); break;}
case 2: {out<<get_frecv(root, s) << endl; break;}
case 3: {out<<get_prefix(root, s) << endl; break;}
default: {
break;
}
}
}
//afis_word(root, "");
return 0;
}