#include <bits/stdc++.h>
using namespace std;
void doRoutine() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  srand(322179);
}
struct str {
  str *cl, *cr;
  int lb, rb;
  int val;
  str(int l, int r) {
    lb = l, rb = r;
    cl = cr = nullptr;
    val = 0;
    if (l + 1 < r) {
      int m = (l + r) / 2;
      cl = new str(l, m);
      cr = new str(m, r);
    }
  }
  void add(int l, int r, int x) {
    if (l == lb && r == rb) {
      val += x;
    } else {
      int mb = (lb + rb) / 2;
      if (r <= mb) {
        cl->add(l, r, x);
      } else if (l >= mb) {
        cr->add(l, r, x);
      } else {
        cl->add(l, mb, x);
        cr->add(mb, r, x);
      }
    }
  }
  int get(int i) {
    if (lb + 1 == rb) {
      return val;
    } else {
      int mb = (lb + rb) / 2;
      int res = val;
      if (i < mb) {
        res += cl->get(i);
      } else {
        res += cr->get(i);
      }
      return res;
    }
  }
};
const int MAXV = 400005;
const int LOGV = 20;
const int A = 26;
char backc[MAXV];
int parent[MAXV];
int trie[MAXV][A];
int trie_sz;
int vertex[MAXV];
vector<int> queries[MAXV];
int query_str_id[MAXV];
int ans_to_query[MAXV];
void init_trie() {
  for (int v = 0; v < MAXV; ++v) {
    for (int i = 0; i < A; ++i) {
      trie[v][i] = -1;
    }
  }
  trie_sz = 1;
}
int add_vertex(int par, char c) {
  trie[par][c - 'a'] = trie_sz;
  backc[trie_sz] = c;
  parent[trie_sz] = par;
  ++trie_sz;
  return trie_sz - 1;
}
int aho[MAXV][A];
int aho_parent[MAXV];
char aho_backc[MAXV];
int go[MAXV][A];
int suflink[MAXV];
bool is_terminal[MAXV];
int aho_vertex[MAXV];
int aho_sz;
void init_aho(vector<string> &ts, unordered_map<string, int> &tcomp) {
  for (int i = 0; i < MAXV; ++i) {
    for (int j = 0; j < A; ++j) {
      aho[i][j] = go[i][j] = -1;
    }
    is_terminal[i] = false;
    suflink[i] = -1;
  }
  aho_sz = 1;
  for (auto &t : ts) {
    int v = 0;
    for (auto ch : t) {
      if (aho[v][ch - 'a'] == -1) {
        aho[v][ch - 'a'] = aho_sz;
        aho_backc[aho_sz] = ch;
        aho_parent[aho_sz] = v;
        v = aho_sz;
        ++aho_sz;
      } else {
        v = aho[v][ch - 'a'];
      }
    }
    is_terminal[v] = true;
    aho_vertex[tcomp[t]] = v;
  }
  queue<int> q;
  q.push(0);
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    if (v == 0) {
      suflink[v] = 0;
    } else if (aho_parent[v] == 0) {
      suflink[v] = 0;
    } else {
      suflink[v] = go[suflink[aho_parent[v]]][aho_backc[v] - 'a'];
    }
    for (int c = 0; c < A; ++c) {
      if (aho[v][c] != -1) {
        go[v][c] = aho[v][c];
        q.push(aho[v][c]);
      } else {
        if (v == 0) {
          go[v][c] = 0;
        } else {
          go[v][c] = go[suflink[v]][c];
        }
      }
    }
  }
}
vector<vector<int> > paths;
vector<str> structs;
int sz[MAXV];
int path_id[MAXV], index_in_path[MAXV];
vector<int> linkg[MAXV];
void dfs_sz(int v) {
  sz[v] = 1;
  for (auto u : linkg[v]) {
    dfs_sz(u);
    sz[v] += sz[u];
  }
}
void dfs_hld(int v, int cur_path_id = -1) {
  if (cur_path_id == -1) {
    cur_path_id = paths.size();
    paths.push_back(vector<int>());
  }
  index_in_path[v] = paths[cur_path_id].size();
  path_id[v] = cur_path_id;
  paths[cur_path_id].push_back(v);
  int max_u = -1, max_sz = -1;
  for (auto u : linkg[v]) {
    if (sz[u] > max_sz) {
      max_sz = sz[u];
      max_u = u;
    }
  }
  for (auto u : linkg[v]) {
    if (u == max_u) {
      dfs_hld(u, cur_path_id);
    } else {
      dfs_hld(u, -1);
    }
  }
}
void init_hld() {
  for (int v = 1; v < aho_sz; ++v) {
    linkg[suflink[v]].push_back(v);
  }
  dfs_sz(0);
  dfs_hld(0, -1);
  for (int i = 0; i < paths.size(); ++i) {
    structs.push_back(str(0, paths[i].size()));
  }
}
void addval(int v, int x) {
  if (0) cerr << "add " << v << " " << x << endl;
  while (v != 0) {
    structs[path_id[v]].add(0, index_in_path[v] + 1, x);
    v = suflink[paths[path_id[v]][0]];
  }
}
int getval(int v) { return structs[path_id[v]].get(index_in_path[v]); }
void dfs_ans(int v, int av) {
  if (0) cerr << av << endl;
  for (int qid : queries[v]) {
    if (qid == 8) {
      if (0) cerr << "!" << endl;
    }
    int ahov = aho_vertex[query_str_id[qid]];
    ans_to_query[qid] = getval(ahov);
  }
  for (int c = 0; c < A; ++c) {
    if (trie[v][c] != -1) {
      int new_av = go[av][c];
      addval(new_av, 1);
      dfs_ans(trie[v][c], new_av);
      addval(new_av, -1);
    }
  }
}
signed main() {
  doRoutine();
  init_trie();
  int n;
  cin >> n;
  for (int i = 0; i < n; ++i) {
    int dec;
    cin >> dec;
    if (dec == 1) {
      char c;
      cin >> c;
      if (trie[0][c - 'a'] == -1) {
        vertex[i] = add_vertex(0, c);
      } else {
        vertex[i] = trie[0][c - 'a'];
      }
    } else {
      int j;
      char c;
      cin >> j >> c;
      --j;
      int v = vertex[j];
      if (trie[v][c - 'a'] == -1) {
        vertex[i] = add_vertex(v, c);
      } else {
        vertex[i] = trie[v][c - 'a'];
      }
    }
  }
  int q;
  cin >> q;
  unordered_map<string, int> tcomp;
  vector<string> ts;
  for (int i = 0; i < q; ++i) {
    int j;
    string t;
    cin >> j >> t;
    --j;
    int v = vertex[j];
    if (!tcomp.count(t)) {
      tcomp[t] = ts.size();
      query_str_id[i] = ts.size();
      ts.push_back(t);
    } else {
      query_str_id[i] = tcomp[t];
    }
    queries[v].push_back(i);
  }
  init_aho(ts, tcomp);
  init_hld();
  dfs_ans(0, 0);
  for (int i = 0; i < q; ++i) {
    cout << ans_to_query[i] << endl;
  }
  return 0;
}
