#include <bits/stdc++.h>
using namespace std;
ifstream fin("trie.in");
ofstream fout("trie.out");
const int CMAX = 26;
struct Node {
int frequency_ending_words;
int frequency_prefix;
int children[CMAX];
Node() {
frequency_ending_words = frequency_prefix = 0;
for(int i = 0; i < CMAX; i++) {
children[i] = -1;
}
}
};
struct Trie {
vector<Node> nodes;
Trie() {
nodes.push_back(Node());
}
int create_node() {
int index = nodes.size();
nodes.push_back(Node());
return index;
}
void insert(string& s) {
int node = 0;
nodes[node].frequency_prefix++;
for(char x : s) {
if(nodes[node].children[x - 'a'] == -1) {
nodes[node].children[x - 'a'] = create_node();
}
node = nodes[node].children[x - 'a'];
nodes[node].frequency_prefix++;
}
nodes[node].frequency_ending_words++;
}
void erase(string& s) {
int node = 0;
nodes[node].frequency_prefix--;
for(char x : s) {
assert(nodes[node].children[x - 'a'] != -1);
node = nodes[node].children[x - 'a'];
nodes[node].frequency_prefix--;
}
nodes[node].frequency_ending_words--;
}
int get_frequency(string& s) {
int node = 0;
for(char x : s) {
if(nodes[node].children[x - 'a'] == -1) {
return 0;
}
node = nodes[node].children[x - 'a'];
}
return nodes[node].frequency_ending_words;
}
int get_longest_common_prefix(string& s) {
int node = 0;
int i = 0;
while(i < (int) s.size() && nodes[node].children[s[i] - 'a'] != -1 && nodes[node].frequency_prefix > 0) {
node = nodes[node].children[s[i] - 'a'];
i++;
}
return i - (nodes[node].frequency_prefix == 0);
}
}trie;
int type;
string s;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
while(fin >> type >> s) {
if(type == 0) {
trie.insert(s);
}
else if(type == 1) {
trie.erase(s);
}
else if(type == 2) {
fout << trie.get_frequency(s) << '\n';
}
else {
fout << trie.get_longest_common_prefix(s) << '\n';
}
}
return 0;
}