#include <stdio.h>
#include <assert.h>
#include <ctype.h>
struct T {
int val, nr;
T* next[26];
T(int _val, int _nr) {
val = _val;
nr = _nr;
for (int i = 0; i < 26; i++) {
next[i] = NULL;
}
}
} *R;
void make()
{
R = new T(0, 0);
}
void add(T* &n, char cuv[21])
{
if (isalpha(cuv[0])) {
if (n->next[cuv[0] - 'a'] == 0) {
n->next[cuv[0] - 'a'] = new T(0, 0);
n->nr ++;
}
add(n->next[cuv[0] - 'a'], cuv + 1);
} else {
n->val ++;
}
}
int erase(T* &n, char cuv[21])
{
if (!isalpha(cuv[0])) {
n->val --;
} else if (erase(n->next[cuv[0] - 'a'], cuv + 1)) {
n->next[cuv[0] - 'a'] = 0;
n->nr --;
}
if (n->val == 0 && n->nr == 0 && n != R) {
delete n;
return 1;
}
return 0;
}
int count(T *n, char cuv[21])
{
if (isalpha(cuv[0])) {
if (n->next[cuv[0] - 'a']) {
return count(n->next[cuv[0] - 'a'], cuv + 1);
} else {
return 0;
}
} else {
return n->val;
}
}
int lpref(T *n, char cuv[21])
{
if (!isalpha(cuv[0]) || n->next[cuv[0] - 'a'] == 0) {
return 0;
} else {
return lpref(n->next[cuv[0] - 'a'], cuv + 1) + 1;
}
}
int main()
{
FILE *fin, *fout;
fin = fopen("trie.in", "r");
fout = fopen("trie.out", "w");
make();
do {
// Citire op si cuv
int op;
char cuv[21];
fscanf(fin, "%d", &op);
fgetc(fin);
fgets(cuv, sizeof(cuv), fin);
if (!feof(fin)) {
if (op == 0) {
add(R, cuv);
} else if (op == 1) {
erase(R, cuv);
} else if (op == 2) {
fprintf(fout, "%d\n", count(R, cuv));
} else if (op == 3) {
fprintf(fout, "%d\n", lpref(R, cuv));
} else {
assert(0);
}
}
} while (!feof(fin));
fclose(fin);
fclose(fout);
return 0;
}