#include <bits/stdc++.h>
using namespace std;
int nwnode[300002][26], cnt[300002], id = 1, dp[300002], backnode[300002],
                                     dirnode[300002][26], track[300002][26],
                                     casio = 1, vc[300002], vis[300002];
;
int newnode() {
  id++;
  assert(id < 300002);
  return id;
}
void build() {
  int root = 1, p;
  queue<int> q;
  for (int i = 0; i <= 25; i++) {
    if (dirnode[root][i] == 0) {
      nwnode[root][i] = root;
      track[root][i] = casio;
    } else {
      nwnode[root][i] = dirnode[root][i];
      q.push(nwnode[root][i]);
      track[root][i] = casio;
      backnode[nwnode[root][i]] = 1;
    }
  }
  int u, v, w, c;
  while (!q.empty()) {
    u = q.front();
    q.pop();
    for (int i = 0; i <= 25; i++) {
      if (dirnode[u][i] == 0) {
        nwnode[u][i] = nwnode[backnode[u]][i];
        track[u][i] = casio;
        continue;
      }
      w = backnode[u];
      v = dirnode[u][i];
      nwnode[u][i] = v;
      track[u][i] = casio;
      while (track[w][i] != casio) {
        w = backnode[w];
      }
      int c = nwnode[w][i];
      backnode[v] = w = c;
      vc[v] = w;
      q.push(v);
    }
  }
}
char str[300002];
void realinsert(int add) {
  int mul = 1;
  for (int i = 0; str[i]; i++) {
    int p = str[i] - 97;
    if (dirnode[mul][p] == 0) dirnode[mul][p] = newnode();
    mul = dirnode[mul][p];
  }
  cnt[mul] += add;
}
int dp_func(int v) {
  if (vis[v] == casio) return dp[v];
  vis[v] = casio;
  dp[v] = cnt[v];
  if (vc[v]) dp[v] += dp_func(vc[v]);
  return dp[v];
}
int main() {
  int i, j, k, l, m, n, ty, sq = 600;
  scanf("%d", &n);
  while (n--) {
    scanf("%d%s", &ty, str);
    if (ty == 1) {
      realinsert(1);
      continue;
    }
    if (ty == 2) {
      realinsert(-1);
      continue;
    }
    int len = strlen(str);
    if (len <= sq) {
      int sum = 0;
      for (int i = 0; str[i]; i++) {
        int root = 1;
        for (int j = i; str[j]; j++) {
          int p = str[j] - 97;
          if (dirnode[root][p] == 0) break;
          root = dirnode[root][p];
          sum += cnt[root];
        }
      }
      printf("%d\n", sum);
      fflush(stdout);
      continue;
    }
    casio++;
    for (int i = 1; i <= id; i++) {
      dp[i] = -1;
    }
    build();
    for (int i = 1; i <= id; i++) dp_func(i);
    int root = 1, sum = 0;
    for (int j = 0; str[j]; j++) {
      int p = str[j] - 97;
      root = nwnode[root][p];
      sum += dp[root];
    }
    printf("%d\n", sum);
    fflush(stdout);
  }
}
