#include <bits/stdc++.h>
using namespace std;
const static int alpha = 26;
inline int conv(char ch) { return ch - 'a'; }
const int nax = 3e5 + 20;
const int L = 20;
string pat[nax];
struct aho {
  int nodes;
  map<int, map<int, int>> trie;
  int fail[nax], end_word[nax], cnt_word[nax], fail_out[nax];
  vector<int> idxs;
  bool built;
  aho() {
    cnt_word[0] = fail_out[0] = fail[0] = end_word[0] = 0;
    trie.clear();
    nodes = 0, built = 0;
    idxs.clear();
  }
  void reset() {
    cnt_word[0] = fail_out[0] = fail[0] = end_word[0] = 0;
    trie.clear();
    nodes = 0, built = 0;
    idxs.clear();
  }
  void add(string &s, int i) {
    int cur = 0;
    for (char c : s) {
      int x = conv(c);
      if (!trie[cur][x]) {
        trie[cur][x] = ++nodes;
        cnt_word[nodes] = fail_out[nodes] = fail[nodes] = end_word[nodes] = 0;
      }
      cur = trie[cur][x];
    }
    ++cnt_word[cur];
    end_word[cur] = i;
  }
  void build() {
    queue<int> q;
    q.push(0);
    while (((int)q.size())) {
      int u = q.front();
      q.pop();
      for (int i = 0; i < alpha; ++i) {
        int v = trie[u][i];
        if (!v)
          trie[u][i] = trie[fail[u]][i];
        else
          q.push(v);
        if (!u || !v) continue;
        fail[v] = trie[fail[u]][i];
        fail_out[v] = end_word[fail[v]] ? fail[v] : fail_out[fail[v]];
        cnt_word[v] += cnt_word[fail[v]];
      }
    }
  }
  int match(string &s) {
    if (((int)idxs.size()) == 0) return 0;
    if (!built) {
      built = true;
      int j = 1;
      for (int p : idxs) add(pat[p], j++);
      build();
    }
    int u = 0, ans = 0;
    for (char c : s) {
      u = trie[u][conv(c)];
      ans += cnt_word[u];
    }
    return ans;
  }
};
aho st[2][L];
void add(int tipo, string &s, int id) {
  int cur = 1, where;
  vector<int> ids;
  ids.push_back(id);
  for (where = 0; where < L; ++where) {
    if (((int)st[tipo][where].idxs.size()) > cur) {
      cur += ((int)st[tipo][where].idxs.size());
      swap(ids, st[tipo][where].idxs);
    } else
      cur += ((int)st[tipo][where].idxs.size());
    for (int i : st[tipo][where].idxs) ids.push_back(i);
    st[tipo][where].reset();
    if (cur <= (1 << where)) {
      break;
    }
  }
  st[tipo][where].idxs = ids;
}
long long solve(string &s) {
  long long ans = 0;
  for (int i = 0; i < L; ++i) {
    ans += st[0][i].match(s);
    ans -= st[1][i].match(s);
  }
  return ans;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int m;
  cin >> m;
  int t;
  for (int i = 0; i < (int)m; ++i) {
    cin >> t >> pat[i];
    if (t == 1)
      add(t - 1, pat[i], i);
    else if (t == 2)
      add(t - 1, pat[i], i);
    else {
      cout << solve(pat[i]) << endl;
    }
  }
}
