#include <bits/stdc++.h>
using namespace std;
string s[300005];
vector<pair<int, int> > vec1, vec2;
queue<int> que;
struct AC {
  int root, idxN;
  struct NODE {
    int son[26], fail;
    long long val;
    void init() { memset(son, -1, sizeof son), val = 0, fail = -1; }
  } node[300005];
  void init() {
    root = idxN = 0;
    node[root].init();
  }
  void insert(string s, int v) {
    int now = root;
    for (int i = 0; i < s.size(); ++i) {
      int id = s[i] - 'a';
      if (node[now].son[id] == -1) {
        node[now].son[id] = ++idxN;
        node[idxN].init();
      }
      now = node[now].son[id];
    }
    node[now].val += v;
  }
  void build_ac() {
    que.push(root);
    while (!que.empty()) {
      int now = que.front();
      que.pop();
      for (int i = 0; i < 26; ++i) {
        if (node[now].son[i] == -1) {
          if (now == root)
            node[now].son[i] = root;
          else
            node[now].son[i] = node[node[now].fail].son[i];
        } else {
          int nex = node[now].son[i];
          if (now == root)
            node[nex].fail = root;
          else {
            node[nex].fail = node[node[now].fail].son[i];
            if (node[node[nex].fail].val)
              node[nex].val += node[node[nex].fail].val;
          }
          que.push(nex);
        }
      }
    }
  }
  long long query(string s) {
    long long res = 0;
    int now = root;
    for (int i = 0; i < (int)s.size(); ++i) {
      int id = s[i] - 'a';
      now = node[now].son[id];
      res += node[now].val;
    }
    return res;
  }
} A1, A2;
int main() {
  int q;
  scanf("%d", &q);
  for (int _ = 0; _ < q; ++_) {
    int ty;
    scanf("%d", &ty);
    cin >> s[_];
    if (ty <= 2) {
      vec1.push_back(make_pair(_, 3 - 2 * ty));
      A1.init();
      for (int i = 0; i < (int)vec1.size(); ++i)
        A1.insert(s[vec1[i].first], vec1[i].second);
      if (A1.idxN > 600) {
        for (int i = 0; i < (int)vec1.size(); ++i) vec2.push_back(vec1[i]);
        vec1.clear(), A1.init();
        A2.init();
        for (int i = 0; i < (int)vec2.size(); ++i)
          A2.insert(s[vec2[i].first], vec2[i].second);
        A2.build_ac();
      }
      A1.build_ac();
    } else {
      printf("%lld\n", A1.query(s[_]) + A2.query(s[_]));
      fflush(stdout);
    }
  }
  return 0;
}
