#include <bits/stdc++.h>
using namespace std;
struct Aho_Corasick {
  static const int AL = 26;
  struct node {
    int next[AL], p, link = -1, leaf = 0, leaflink = -1;
    char pch;
    vector<int> words;
    node(int p = -1, char ch = '$') : p(p), pch(ch) {
      memset(next, -1, sizeof(next));
    }
  };
  vector<node> trie;
  Aho_Corasick() { trie.resize(1); }
  void insert(string s, int idx) {
    int len = s.size(), cur = 0;
    for (int i = 0; i < len; i++) {
      int c = s[i] - 'a';
      if (trie[cur].next[c] == -1) {
        trie[cur].next[c] = trie.size();
        trie.emplace_back(cur, s[i]);
      }
      cur = trie[cur].next[c];
    }
    trie[cur].leaf++;
    trie[cur].words.push_back(idx);
  }
  int go(int v, int c) {
    while (v != -1 and trie[v].next[c] == -1) v = trie[v].link;
    return (v != -1) ? trie[v].next[c] : 0;
  }
  void push_links() {
    queue<int> q;
    q.push(0);
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      for (int i = 0; i < AL; i++) {
        if (trie[u].next[i] == -1) continue;
        int v = trie[u].next[i];
        int linkv = go(trie[u].link, i);
        trie[v].link = linkv;
        q.push(v);
        trie[v].leaf += trie[linkv].leaf;
      }
    }
  }
  int traverse(string s) {
    int len = s.size(), cur = 0, res = 0;
    for (int i = 0; i < len; i++) {
      int c = s[i] - 'a';
      cur = go(cur, c);
      res += trie[cur].leaf;
    }
    return res;
  }
};
struct DynamicAho {
  static const int LOG = 20;
  Aho_Corasick aho[LOG];
  vector<string> strings[LOG];
  DynamicAho() {}
  void insert(string str) {
    int k = 0;
    while (k < LOG and strings[k].size() > 0) k++;
    aho[k].insert(str, 0);
    strings[k].push_back(str);
    for (int i = 0; i < k; i++) {
      aho[i].trie.resize(1);
      for (string s : strings[i]) {
        aho[k].insert(s, 0);
        strings[k].push_back(s);
      }
      strings[i].clear();
      aho[i].trie.clear();
      aho[i].trie.resize(1);
    }
    aho[k].push_links();
  }
  int getCount(string s) {
    int ans = 0;
    for (int i = 0; i < LOG; i++) ans += aho[i].traverse(s);
    return ans;
  }
};
DynamicAho dac[2];
void test_case() {
  int n;
  cin >> n;
  while (n--) {
    int t;
    string s;
    cin >> t >> s;
    if (t == 3)
      cout << dac[0].getCount(s) - dac[1].getCount(s) << endl;
    else
      dac[t - 1].insert(s);
  }
}
int main() {
  int t = 1, cs = 0;
  while (t--) {
    test_case();
  }
  return 0;
}
