#include <bits/stdc++.h>
using namespace std;
bool debug = 0;
int n, m, k;
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
string direc = "RDLU";
long long ln, lk, lm;
void etp(bool f = 0) {
  puts(f ? "YES" : "NO");
  exit(0);
}
void addmod(int &x, int y, int mod = 1000000007) {
  x += y;
  if (x >= mod) x -= mod;
}
void et() {
  puts("0");
  exit(0);
}
string S[2][300105];
int cnt[2];
const int maxn = 300105;
struct Aca {
  int left, right, SZ;
  vector<vector<int>> next;
  vector<int> fail;
  vector<int> end;
  int root, L;
  int newNode() {
    next[L].resize(26, -1);
    end[L++] = 0;
    return L - 1;
  }
  void init(int sz) {
    SZ = sz;
    L = 0;
    left = 0;
    right = 0;
    next.resize(SZ + 10);
    fail.resize(SZ + 10);
    end.resize(SZ + 10);
    root = newNode();
  }
  void clr() {
    left = 0;
    right = 0;
    next.clear();
    fail.clear();
    end.clear();
    L = 0;
  }
  void insert(string &str) {
    int now = root;
    int len = str.length();
    for (int i = 0; i < len; i++) {
      int temp = str[i] - 'a';
      if (next[now][temp] == -1) {
        next[now][temp] = newNode();
      }
      now = next[now][temp];
    }
    end[now] += 1;
  }
  void build() {
    queue<int> que;
    fail[root] = root;
    for (int i = 0; i < 26; i++) {
      if (next[root][i] == -1) {
        next[root][i] = root;
      } else {
        fail[next[root][i]] = root;
        que.push(next[root][i]);
      }
    }
    while (!que.empty()) {
      int now = que.front();
      que.pop();
      end[now] += end[fail[now]];
      for (int i = 0; i < 26; i++) {
        int t = next[now][i];
        if (t == -1) {
          next[now][i] = next[fail[now]][i];
        } else {
          fail[t] = next[fail[now]][i];
          que.push(t);
        }
      }
    }
  }
  long long qy(string &p) {
    int rt = 0;
    int N = p.length();
    long long ans = 0;
    for (int(i) = 0; (i) < (int)(N); (i)++) {
      int num = p[i] - 'a';
      rt = next[rt][num];
      ans += end[rt];
    }
    return ans;
  }
} ac[2][20];
void cal(int id) {
  int l = cnt[id], r = l;
  int sz = S[id][l].size();
  for (int(j) = 0; (j) < (int)(20); (j)++) {
    if (ac[id][j].L == 0) {
      ac[id][j].init(sz);
      ac[id][j].left = l;
      ac[id][j].right = r;
      for (int k = l; k <= r; k++) ac[id][j].insert(S[id][k]);
      ac[id][j].build();
      break;
    }
    l = ac[id][j].left;
    sz += ac[id][j].SZ;
    ac[id][j].clr();
  }
}
string Q;
long long qy(int id) {
  long long ans = 0;
  for (int(j) = 0; (j) < (int)(20); (j)++)
    if (ac[id][j].L != 0) {
      ans += ac[id][j].qy(Q);
    }
  return ans;
}
void fmain() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  for (int i = 1, t; i <= n; i++) {
    cin >> t;
    if (t <= 2) {
      cin >> S[t - 1][++cnt[t - 1]];
      cal(t - 1);
    } else {
      cin >> Q;
      cout << qy(0) - qy(1) << endl;
    }
  }
}
int main() {
  fmain();
  return 0;
}
