func_code_string: #include <bits/stdc++.h>   using namespace std;   const int inf = 0x3f3f3f3f, oo = inf;   inline long long read() {     register long long x = 0, f = 1;     register char c = getchar();     for (; !isdigit(c); c = getchar())       if (c ==  - ) f = -1;     for (; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);     return x * f;   }   inline void write(long long x) {     if (x < 0) x = -x, putchar( - );     if (x >= 10) write(x / 10);     putchar(x % 10 +  0 );   }   inline void writeln(long long x) {     write(x);     puts(  );   }   const int Mod = 1e9 + 7;   inline int ppow(int a, int b) {     int ans = 1;     for (; b; b >>= 1, a = 1ll * a * a % Mod)       if (b & 1) ans = 1ll * ans * a % Mod;     return ans;   }   const int maxnode = 323333;   struct ACautomto {     struct node {       int nxt[26], fail, v, end;     } T[maxnode];     int tot;     int front, rear, q[maxnode], root[22];     ACautomto() {       tot = 0;       memset(T, 0, sizeof(T));     }     inline void merge(int o1, int o2) {       T[o2].end |= T[o1].end;       for (register int i = (0); i < (26); ++i) {         if (!T[o1].nxt[i])           continue;         else if (!T[o2].nxt[i])           T[o2].nxt[i] = T[o1].nxt[i];         else           merge(T[o1].nxt[i], T[o2].nxt[i]);       }     }     inline void insert(int o, char s[]) {       for (int i = 0; s[i]; ++i) {         if (!T[o].nxt[s[i] -  a ]) T[o].nxt[s[i] -  a ] = ++tot;         o = T[o].nxt[s[i] -  a ];       }       ++T[o].end;     }     inline void build(int rt) {       int u, v, p;       front = rear = 0;       q[rear++] = rt;       while (front < rear) {         u = q[front++];         for (register int i = (0); i < (26); ++i)           if (T[u].nxt[i]) {             v = T[u].nxt[i], p = T[u].fail;             while (p && !T[p].nxt[i]) p = T[p].fail;             T[v].fail = p ? T[p].nxt[i] : rt;             T[v].v = T[v].end + T[T[v].fail].v;             q[rear++] = v;           }       }     }     inline int query(int rt, char s[]) {       int ans = 0, o = rt;       for (int i = 0; s[i]; ++i) {         while (o && !T[o].nxt[s[i] -  a ]) o = T[o].fail;         if (o == 0) o = rt;         o = T[o].nxt[s[i] -  a ];         ans += T[o].v;       }       return ans;     }     inline void add(char s[]) {       int rt = ++tot;       insert(rt, s);       for (int i = 0; i < 20; ++i) {         if (!root[i]) {           root[i] = rt;           build(root[i]);           return;         } else {           merge(root[i], rt);           root[i] = 0;         }       }     }     inline int get(char s[]) {       int ans = 0;       for (int i = 0; i < 20; ++i) ans += query(root[i], s);       return ans;     }   } add, del;   char s[300005];   int main() {     int T = read();     while (T--) {       int op = read();       scanf( %s , s);       if (op == 1) {         add.add(s);       } else if (op == 2) {         del.add(s);       } else {         writeln(add.get(s) - del.get(s));       }       fflush(stdout);     }     return 0;   }   