#include <bits/stdc++.h>
using namespace std;
const int nmax = 3e5;
const int mod = 666013;
const int base = 31;
const int mod1 = 1e9 + 7;
const int mod2 = 1e9 + 9;
struct u64 {
  int x, y;
  u64() {}
  u64(int k) { x = k % mod1, y = k % mod2; }
  u64 operator+(const u64 &shp) const {
    u64 aux;
    aux.x = x + shp.x;
    aux.y = y + shp.y;
    if (aux.x >= mod1) aux.x -= mod1;
    if (aux.y >= mod2) aux.y -= mod2;
    return aux;
  }
  u64 operator-(const u64 &shp) const {
    u64 aux;
    aux.x = x - shp.x;
    aux.y = y - shp.y;
    if (aux.x < 0) aux.x += mod1;
    if (aux.y < 0) aux.y += mod2;
    return aux;
  }
  u64 operator*(const u64 &shp) const {
    u64 aux;
    aux.x = 1LL * x * shp.x % mod1;
    aux.y = 1LL * y * shp.y % mod2;
    return aux;
  }
  bool operator==(const u64 &shp) const { return x == shp.x && y == shp.y; }
  bool operator<(const u64 &shp) const {
    return x == shp.x ? (y < shp.y) : (x < shp.x);
  }
};
map<pair<u64, int>, bool> mp;
vector<u64> v[mod];
u64 h[nmax + 1], pb[nmax + 1];
int find_key(u64 x) { return x.x + x.y; }
void baga(u64 x) { v[find_key(x) % mod].push_back(x); }
bool cauta(u64 x) {
  int key = find_key(x) % mod;
  for (auto i : v[key])
    if (i == x) return 1;
  return 0;
}
void sterge(u64 x) {
  int key = find_key(x) % mod;
  for (int i = 0; i < (int)v[key].size(); ++i) {
    if (v[key][i] == x) {
      swap(v[key][i], v[key].back());
      v[key].pop_back();
      return;
    }
  }
}
inline u64 find_hsh(int x, int y) { return h[y] - h[x - 1] * pb[y - x + 1]; }
int main() {
  cin.sync_with_stdio(false);
  cin.tie();
  cout.tie();
  pb[0] = 1;
  for (int i = 1; i <= nmax; ++i) pb[i] = pb[i - 1] * base;
  int q;
  cin >> q;
  int lim = sqrt(nmax) / 3;
  while (q--) {
    string s;
    int tip;
    cin >> tip >> s;
    if (tip == 1) {
      u64 hs = 0;
      for (auto i : s) hs = (hs * base + (i - 'a' + 1));
      baga(hs);
      if ((int)s.size() > lim) mp[{hs, (int)s.size()}] = 1;
    } else if (tip == 2) {
      u64 hs = 0;
      for (auto i : s) hs = (hs * base + (i - 'a' + 1));
      sterge(hs);
      if ((int)s.size() > lim) mp.erase({hs, (int)s.size()});
    } else {
      h[0] = 0;
      for (int i = 1; i <= (int)s.size(); ++i)
        h[i] = (h[i - 1] * base + (s[i - 1] - 'a' + 1));
      long long ans = 0;
      for (int i = 1; i <= (int)s.size(); ++i) {
        for (int j = 1; j <= lim && j <= i; ++j) {
          ans += cauta(find_hsh(i - j + 1, i));
        }
      }
      for (auto &i : mp)
        for (int j = i.first.second; j <= (int)s.size(); ++j)
          ans += find_hsh(j - i.first.second + 1, j) == i.first.first;
      cout << ans << "\n";
      cout.flush();
    }
  }
  return 0;
}
