#include <bits/stdc++.h>
template <typename T>
void read(T& x) {
  x = 0;
  char ch = getchar();
  long long f = 1;
  while (!isdigit(ch)) {
    if (ch == '-') f *= -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - 48;
    ch = getchar();
  }
  x *= f;
}
using namespace std;
const int N = 310000;
string ss[N], tt[N];
struct AC_Auto {
  int sz = 0, now = 0, lst = 0;
  int tri[N][26], tri2[N][26], end[N], fail[N];
  int ans[N];
  int st[N], siz[N], ed_cnt[N];
  int init(int id = 0) {
    memset(tri[id], 0, sizeof(tri[id]));
    end[id] = fail[id] = ans[id] = 0;
    return sz = id;
  }
  int insert(int rt, string s) {
    for (int i = 0; s[i]; ++i) {
      int& v = tri[rt][s[i] - 'a'];
      if (v == 0) v = init(sz + 1);
      rt = v;
    }
    end[rt] = 1;
    return rt;
  }
  void clr(int rt) {
    queue<int> q;
    q.push(rt);
    while (!q.empty()) {
      int x = q.front();
      q.pop();
      for (int i = 0; i < 26; ++i) {
        int v = tri[x][i];
        tri2[x][i] = v;
        if (v) q.push(v);
      }
    }
  }
  void build(int rt) {
    queue<int> q;
    for (int i = 0; i < 26; ++i) {
      int v = tri2[rt][i];
      if (v) {
        fail[v] = rt;
        ans[v] = end[v];
        q.push(v);
      } else {
        tri2[rt][i] = rt;
      }
    }
    while (!q.empty()) {
      int x = q.front();
      q.pop();
      for (int i = 0; i < 26; ++i) {
        int& v = tri2[x][i];
        if (v) {
          fail[v] = tri2[fail[x]][i];
          ans[v] = end[v] + ans[fail[v]];
          q.push(v);
        } else {
          v = tri2[fail[x]][i];
        }
      }
    }
  }
  long long query(int x, string s) {
    long long res = 0;
    for (int i = 0; s[i]; ++i) {
      x = tri2[x][s[i] - 'a'];
      res += ans[x];
    }
    return res;
  }
  void fuck_insert(string* sss, string s) {
    sss[++lst] = s;
    ++now;
    if (now > 1) st[now] = init(sz + 1);
    insert(st[now], s);
    ed_cnt[now] = sz;
    siz[now] = 1;
    while (now > 1 && siz[now] == siz[now - 1]) {
      sz = ed_cnt[now - 1];
      for (int i = lst - siz[now] + 1; i <= lst; ++i) {
        insert(st[now - 1], sss[i]);
        ed_cnt[now - 1] = sz;
      }
      siz[now - 1] += siz[now];
      --now;
    }
    clr(st[now]);
    build(st[now]);
  }
  long long fuck_query(string s) {
    long long res = 0;
    for (int i = 1; i <= now; ++i) res += query(st[i], s);
    return res;
  }
};
AC_Auto ins, del;
string tmp;
int main() {
  int n, m;
  cin >> n;
  while (n--) {
    cin >> m >> tmp;
    if (m == 1) {
      ins.fuck_insert(ss, tmp);
    } else if (m == 2) {
      del.fuck_insert(tt, tmp);
    } else {
      cout << ins.fuck_query(tmp) - del.fuck_query(tmp) << endl;
    }
  }
  return 0;
}
