#include <bits/stdc++.h>
using namespace std;
const int K = 26;
const int N = 400005;
const int M = 3 * N + 45;
map<char, int> nxt[M];
int triePos[N], ans[N], pref[N];
int sptr, tptr, trie[N][K], fck[M];
int len[M], link[M];
vector<int> g[M], qq[N], chr[N];
string str[N];
int dptr, st[M], en[M], f[M];
inline int insert(int last, int ch) {
  int p = last;
  if (nxt[p].count(ch)) {
    int q = nxt[p][ch];
    if (len[p] + 1 == len[q]) {
      return q;
    }
    int nq = sptr++;
    nxt[nq] = nxt[q];
    len[nq] = len[p] + 1;
    link[nq] = link[q];
    while (p != -1 && nxt[p][ch] == q) {
      if (fck[p] != -1 && fck[q] != -1 && fck[p] + 1 == fck[q]) {
        fck[nq] = fck[q];
        pref[fck[nq]] = nq;
        fck[q] = -1;
      }
      nxt[p][ch] = nq;
      p = link[p];
    }
    return link[q] = nq;
  }
  int cur = sptr++;
  len[cur] = len[last] + 1;
  while (p != -1 && !nxt[p].count(ch)) {
    nxt[p][ch] = cur;
    p = link[p];
  }
  if (p == -1) {
    link[cur] = 0;
  } else {
    int q = nxt[p][ch];
    if (len[p] + 1 == len[q]) {
      link[cur] = q;
    } else {
      int nq = sptr++;
      nxt[nq] = nxt[q];
      len[nq] = len[p] + 1;
      link[nq] = link[q];
      while (p != -1 && nxt[p][ch] == q) {
        if (fck[p] != -1 && fck[q] != -1 && fck[p] + 1 == fck[q]) {
          fck[nq] = fck[q];
          pref[fck[nq]] = nq;
          fck[q] = -1;
        }
        nxt[p][ch] = nq;
        p = link[p];
      }
      link[q] = link[cur] = nq;
    }
  }
  return cur;
}
inline int trieInsert(int v, int ch) {
  if (trie[v][ch] == -1) {
    trie[v][ch] = tptr++;
    chr[v].push_back(ch);
  }
  return trie[v][ch];
}
void buildSAM(int last, int v, int dep) {
  pref[dep] = last;
  fck[last] = dep;
  for (int i : chr[v]) {
    buildSAM(insert(pref[dep], i), trie[v][i], dep + 1);
  }
}
void dfs(int v) {
  st[v] = dptr++;
  for (int u : g[v]) {
    dfs(u);
  }
  en[v] = dptr;
}
inline void update(int i, int x, int n) {
  while (i <= n) {
    f[i] += x;
    i += i & (-i);
  }
}
inline int query(int i) {
  int ret = 0;
  while (i) {
    ret += f[i];
    i &= (i - 1);
  }
  return ret;
}
inline void compute(int ind) {
  int rt = 0;
  for (auto ch : str[ind]) {
    if (!nxt[rt].count(ch - 'a')) return;
    rt = nxt[rt][ch - 'a'];
  }
  ans[ind] = query(en[rt] - 1) - query(st[rt] - 1);
}
void tzuyu(int v, int rt) {
  if (rt) update(st[rt], 1, sptr);
  for (int qind : qq[v]) {
    compute(qind);
  }
  for (int i : chr[v]) {
    tzuyu(trie[v][i], nxt[rt][i]);
  }
  if (rt) update(st[rt], -1, sptr);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cout << setprecision(32);
  memset(trie, -1, sizeof(trie));
  memset(link, -1, sizeof(link));
  memset(len, 0, sizeof(len));
  int n;
  cin >> n;
  sptr = tptr = 1;
  for (int i = 1; i <= n; i++) {
    int t, j;
    char ch;
    cin >> t;
    if (t == 1) {
      cin >> ch;
      triePos[i] = trieInsert(0, ch - 'a');
    } else {
      cin >> j >> ch;
      triePos[i] = trieInsert(triePos[j], ch - 'a');
    }
  }
  memset(fck, -1, sizeof(fck));
  buildSAM(0, 0, 0);
  int m;
  cin >> m;
  for (int i = 1; i <= m; i++) {
    int quind;
    cin >> quind >> str[i];
    qq[triePos[quind]].push_back(i);
  }
  for (int i = 1; i < sptr; i++) {
    g[link[i]].push_back(i);
  }
  dptr = 1;
  dfs(0);
  memset(f, 0, sizeof(f));
  memset(ans, 0, sizeof(ans));
  tzuyu(0, 0);
  for (int i = 1; i <= m; i++) {
    cout << ans[i] << '\n';
  }
  return 0;
}
