#include <bits/stdc++.h>
using namespace std;
void fre() {
  freopen("c://test//input.in", "r", stdin);
  freopen("c://test//output.out", "w", stdout);
}
template <class T1, class T2>
inline void gmax(T1 &a, T2 b) {
  if (b > a) a = b;
}
template <class T1, class T2>
inline void gmin(T1 &a, T2 b) {
  if (b < a) a = b;
}
const int N = 3e5 + 10, M = 0, L = 0, Z = 1e9 + 7, maxint = 2147483647,
          ms31 = 522133279, ms63 = 1061109567, ms127 = 2139062143;
char s[N];
const int LIM = 500;
struct Trie {
  int id;
  int fail[N];
  int nxt[N][26];
  bool flag[N];
  int cnt[N];
  void insert(char s[]) {
    int p = 1;
    for (int i = 0; s[i]; ++i) {
      int x = s[i] - 'a';
      if (!nxt[p][x]) nxt[p][x] = ++id;
      p = nxt[p][x];
    }
    flag[p] = 1;
  }
  int getfail(int p, int x) {
    while (p) {
      if (nxt[p][x]) return nxt[p][x];
      p = fail[p];
    }
    return 1;
  }
  void AC_automation() {
    queue<int> q;
    q.push(1);
    int pap, son;
    while (!q.empty()) {
      pap = q.front();
      q.pop();
      for (int x = 0; x < 26; ++x)
        if (nxt[pap][x]) {
          son = nxt[pap][x];
          fail[son] = getfail(fail[pap], x);
          cnt[son] = cnt[fail[son]] + flag[son];
          q.push(son);
        }
    }
  }
  long long query(char s[]) {
    int p = 1;
    long long ret = 0;
    for (int i = 0; s[i]; i++) {
      int x = s[i] - 'a';
      while (p && !nxt[p][x]) p = fail[p];
      if (p) {
        p = nxt[p][x];
        ret += cnt[p];
      } else
        p = 1;
    }
    return ret;
  }
  void clr() {
    memset(nxt, 0, (id + 2) * 4 * 26);
    memset(fail, 0, (id + 2) * 4);
    memset(flag, 0, (id + 2) * 1);
    memset(cnt, 0, (id + 2) * 0);
    id = 1;
  }
} BG[2], SM[2];
int O;
void dfs(int bg, int sm) {
  for (int i = 0; i < 26; ++i)
    if (SM[O].nxt[sm][i]) {
      int y = SM[O].nxt[sm][i];
      if (!BG[O].nxt[bg][i]) BG[O].nxt[bg][i] = ++BG[O].id;
      int x = BG[O].nxt[bg][i];
      BG[O].flag[x] |= SM[O].flag[y];
      dfs(x, y);
    }
}
void merge() {
  dfs(1, 1);
  SM[O].clr();
  BG[O].AC_automation();
}
int main() {
  BG[0].id = SM[0].id = 1;
  BG[1].id = SM[1].id = 1;
  int q;
  scanf("%d", &q);
  while (q--) {
    int op;
    scanf("%d", &op);
    scanf("%s", s);
    if (op == 1) {
      SM[0].insert(s);
      if (SM[0].id > LIM)
        O = 0, merge();
      else
        SM[0].AC_automation();
    } else if (op == 2) {
      SM[1].insert(s);
      if (SM[1].id > LIM)
        O = 1, merge();
      else
        SM[1].AC_automation();
    } else {
      long long ans =
          SM[0].query(s) + BG[0].query(s) - SM[1].query(s) - BG[1].query(s);
      printf("%lld\n", ans);
      fflush(stdout);
    }
  }
  return 0;
}
