#include <bits/stdc++.h>
using namespace std;
const int segSize = 1 << 19;
const int segArraySize = 2 * segSize - 1;
int seg[segArraySize];
int segQuery(int a, int b, int i = 0, int l = 0, int r = segSize - 1) {
  if (a > r || b < l) return 0;
  if (a <= l && b >= r) return seg[i];
  int m = (l + r) / 2;
  return segQuery(a, b, (2 * (i) + 1), l, m) +
         segQuery(a, b, (2 * (i) + 2), m + 1, r);
}
void segUpdate(int i) {
  seg[i] = seg[(2 * (i) + 1)] + seg[(2 * (i) + 2)];
  if (i != 0) segUpdate((((i)-1) / 2));
}
int n, m;
map<char, vector<int>> tri[400001];
vector<map<char, int>> trie{map<char, int>()};
vector<map<char, int>> fail{map<char, int>()};
vector<int> mark{-1};
vector<string> v;
vector<pair<string, int>> q[400001];
int res[400000];
int getFail(int ac, char c) {
  if (fail[ac].count(c)) return fail[ac][c];
  fail[ac][c] = ac;
  while (trie[fail[ac][c]].count(c) == 0 && fail[ac][c])
    fail[ac][c] = trie[fail[ac][c]]['*'];
  if (trie[fail[ac][c]].count(c)) fail[ac][c] = trie[fail[ac][c]][c];
  return fail[ac][c];
}
void search(int i, int cur) {
  int r = mark[trie[cur]['+']];
  if (r != -1) {
    seg[segSize - 1 + r]++;
    segUpdate((((segSize - 1 + r) - 1) / 2));
  }
  if (i)
    for (auto a : q[i]) {
      string t = a.first;
      int pos = a.second;
      int s = lower_bound(v.begin(), v.end(), t) - v.begin();
      t.back()++;
      int e = lower_bound(v.begin(), v.end(), t) - v.begin() - 1;
      res[pos] = segQuery(s, e);
    }
  for (auto a : tri[i])
    for (int j : a.second) {
      search(j, getFail(cur, a.first));
    }
  if (r != -1) {
    seg[segSize - 1 + r]--;
    segUpdate((((segSize - 1 + r) - 1) / 2));
  }
}
int main() {
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    int t;
    cin >> t;
    if (t == 1) {
      char c;
      cin >> c;
      tri[0][c].push_back(i);
    } else {
      int j;
      char c;
      cin >> j >> c;
      tri[j][c].push_back(i);
    }
  }
  cin >> m;
  for (int i = 0; i < m; ++i) {
    int j;
    string t;
    cin >> j >> t;
    reverse(t.begin(), t.end());
    v.push_back(t);
    q[j].push_back({t, i});
  }
  sort(v.begin(), v.end());
  v.erase(unique(v.begin(), v.end()), v.end());
  for (int i = 0; i < v.size(); ++i) {
    string t = v[i];
    reverse(t.begin(), t.end());
    int cn = 0;
    for (int j = 0; j < t.size(); ++j) {
      if (!trie[cn].count(t[j])) {
        trie[cn][t[j]] = mark.size();
        trie.push_back(map<char, int>());
        fail.push_back(map<char, int>());
        mark.push_back(-1);
      }
      cn = trie[cn][t[j]];
    }
    mark[cn] = i;
  }
  trie[0]['*'] = 0;
  trie[0]['+'] = 0;
  queue<int> q;
  for (auto i : trie[0])
    if (i.first != '*' && i.first != '+') {
      q.push(i.second);
      trie[i.second]['*'] = 0;
    }
  while (!q.empty()) {
    int ac = q.front();
    q.pop();
    for (auto i : trie[ac]) {
      if (i.first == '*' || i.first == '+') continue;
      q.push(i.second);
      int v = trie[ac]['*'];
      while (!trie[v].count(i.first) && v) v = trie[v]['*'];
      trie[i.second]['*'] = trie[v][i.first];
    }
    if (mark[ac] != -1)
      trie[ac]['+'] = ac;
    else
      trie[ac]['+'] = trie[trie[ac]['*']]['+'];
  }
  search(0, 0);
  for (int i = 0; i < m; ++i) cout << res[i] << "\n";
}
