#include <bits/stdc++.h>
using namespace std;
const int MAXN = 300000 + 10;
const int CASE_SIZE = 26;
const int S_SIZE = 1000;
const int B_SIZE = MAXN / S_SIZE + 10;
struct Trie {
  int child[MAXN][CASE_SIZE], value[MAXN], trieN, root;
  void init() {
    trieN = root = 0;
    value[root] = 0;
    memset(child[root], -1, sizeof(child[root]));
  }
  int newnode() {
    trieN++;
    value[trieN] = 0;
    memset(child[trieN], -1, sizeof(child[trieN]));
    return trieN;
  }
  void insert(char *s, int val) {
    int x = root;
    for (int i = 0; s[i]; i++) {
      int d = s[i] - 'a';
      if (child[x][d] == -1) {
        child[x][d] = newnode();
      }
      x = child[x][d];
    }
    value[x] += val;
  }
  int search(char *s) {
    int sum = 0, x = root;
    for (int i = 0; s[i]; i++) {
      int d = s[i] - 'a';
      if (child[x][d] == -1) {
        break;
      }
      x = child[x][d];
      sum += value[x];
    }
    return sum;
  }
} trie;
struct KMP {
  int Next[MAXN];
  void getNext(string s, int len) {
    memset(Next, 0, sizeof(Next));
    int i = 0, j = -1;
    Next[0] = -1;
    while (i < len) {
      if (j == -1 || s[i] == s[j]) {
        ++i;
        ++j;
        Next[i] = j;
      } else {
        j = Next[j];
      }
    }
  }
  int search(string s, char *str) {
    int sum = 0, j = 0, lens = s.length(), lenstr = strlen(str);
    getNext(s, s.length());
    for (int i = 0; i < lenstr; i++) {
      while (j > 0 && s[j] != str[i]) {
        j = Next[j];
      }
      if (s[j] == str[i]) {
        j++;
      }
      if (j == lens) {
        sum++;
        j = Next[j];
      }
    }
    return sum;
  }
} kmp;
string Bstr[B_SIZE];
char str[MAXN];
int cnt, Bvalue[B_SIZE];
int main() {
  int t, m, len, val;
  while (~scanf("%d", &m)) {
    trie.init();
    cnt = 0;
    memset(Bvalue, 0, sizeof(Bvalue));
    for (int i = 1; i <= m; i++) {
      scanf("%d%s", &t, str);
      len = strlen(str);
      if (t == 1 || t == 2) {
        val = (t == 1 ? 1 : -1);
        if (len <= S_SIZE) {
          trie.insert(str, val);
        } else {
          Bstr[cnt] = string(str);
          Bvalue[cnt++] = val;
        }
      } else {
        long long int ans = 0;
        for (int i = 0; i < len; i++) {
          ans += trie.search(str + i);
        }
        for (int i = 0; i < cnt; i++) {
          if (Bstr[i].length() > len) {
            continue;
          }
          ans += kmp.search(Bstr[i], str) * Bvalue[i];
        }
        printf("%I64d\n", ans);
        fflush(stdout);
      }
    }
  }
  return 0;
}
