#include <fstream>
#include <string>
#include <vector>
using namespace std;
class Trie {
struct Node
{
int cnt = 0, lvs = 0;
int next[26] = {};
};
vector<Node> trie;
public:
inline Trie() noexcept
: trie (1) {}
inline void insert (const string& str) {
int node = 0;
for (const char chr : str) {
if (trie[node].next[chr - 'a'] == 0) {
trie[node].next[chr - 'a'] = trie.size();
trie.emplace_back();
}
node = trie[node].next[chr - 'a'];
++trie[node].lvs;
}
++trie[node].cnt;
}
inline void erase (const string& str) {
int node = 0;
for (const char chr : str) {
node = trie[node].next[chr - 'a'];
--trie[node].lvs;
}
--trie[node].cnt;
node = 0;
for (const char chr : str) {
if (trie[trie[node].next[chr - 'a']].lvs == 0) {
trie[node].next[chr - 'a'] = 0;
return;
}
node = trie[node].next[chr - 'a'];
}
}
inline int count (const string& str) {
int node = 0;
for (const char chr : str) {
if (trie[node].next[chr - 'a'] == 0)
return 0;
node = trie[node].next[chr - 'a'];
}
return trie[node].cnt;
}
inline int lcp (const string& str) {
int node = 0, len = 0;
for (const char chr : str) {
if (trie[node].next[chr - 'a'] == 0)
return len;
node = trie[node].next[chr - 'a'];
++len;
}
return len;
}
};
ifstream fin ("trie.in");
ofstream fout ("trie.out");
int main()
{
Trie trie;
int task;
string str;
while (fin >> task >> str)
{
if (task == 0)
trie.insert (str);
else if (task == 1)
trie.erase (str);
else if (task == 2)
fout << trie.count (str) << '\n';
else
fout << trie.lcp (str) << '\n';
}
fin.close();
fout.close();
return 0;
}