#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("avx,avx2,fma")
using namespace std;
struct SegTree {
  struct Node {
    long long second;
    Node(long long second = 0) : second(second) {}
    Node operator+(const Node &n) { return Node(second + n.second); }
  };
  vector<Node> st;
  int n;
  SegTree(int n) : n(n) { st.resize(2 * n); }
  void update(int u, int l, int r, int kth, int val) {
    if (l == r) {
      st[u].second += val;
      return;
    }
    if (kth <= (l + r) / 2)
      update((u + 1), l, (l + r) / 2, kth, val);
    else
      update((u + (((l + r) / 2 - l + 1) << 1)), (l + r) / 2 + 1, r, kth, val);
    st[u] = st[(u + 1)] + st[(u + (((l + r) / 2 - l + 1) << 1))];
  }
  long long query(int u, int l, int r, int ll, int rr) {
    if (l > r or r < ll or l > rr) return 0;
    if (ll <= l and r <= rr) return st[u].second;
    return query((u + 1), l, (l + r) / 2, ll, rr) +
           query((u + (((l + r) / 2 - l + 1) << 1)), (l + r) / 2 + 1, r, ll,
                 rr);
  }
};
struct vertex {
  map<char, int> next, go;
  int p, link, shortLink;
  char pch;
  bool leaf;
  vertex(int p = -1, char pch = -1)
      : p(p), pch(pch), link(-1), shortLink(-1), leaf(false) {}
};
vector<vertex> t;
vector<long long> qq;
void aho_init() {
  t.clear();
  t.push_back(vertex());
}
int add_string(string &second) {
  int v = 0;
  for (char c : second) {
    if (!t[v].next.count(c)) {
      t[v].next[c] = (int)(t.size());
      t.push_back(vertex(v, c));
    }
    v = t[v].next[c];
  }
  t[v].leaf = true;
  return v;
}
int go(int v, char c);
int get_link(int v) {
  if (t[v].link < 0) {
    if (!v or !t[v].p)
      t[v].link = 0;
    else
      t[v].link = go(get_link(t[v].p), t[v].pch);
  }
  return t[v].link;
}
int go(int v, char c) {
  if (!t[v].go.count(c)) {
    if (t[v].next.count(c))
      t[v].go[c] = t[v].next[c];
    else
      t[v].go[c] = (v == 0 ? 0 : go(get_link(v), c));
  }
  return t[v].go[c];
}
int makeShortLink(int u) {
  if (u == 0) t[u].shortLink = 0;
  if (t[u].shortLink != -1) return t[u].shortLink;
  int v = get_link(u);
  makeShortLink(v);
  t[u].shortLink = ((t[v].leaf) ? v : t[v].shortLink);
  return t[u].shortLink;
}
int getShortLink(int u) {
  if (t[u].shortLink != -1) return t[u].shortLink;
  t[u].shortLink = (u == 0 ? 0 : makeShortLink(u));
  return t[u].shortLink;
}
const int MAXN = 4e5 + 5;
vector<pair<char, int>> graph[MAXN];
vector<int> queries[MAXN];
vector<int> ans(MAXN);
vector<vector<int>> linkTree;
vector<int> in;
vector<int> out;
vector<int> eulerPath;
vector<bool> vis;
vector<long long> queryState;
SegTree segtree(0);
void dfsTree(int u) {
  if (vis[u]) return;
  vis[u] = true;
  int nxt = getShortLink(u);
  linkTree[nxt].push_back(u);
  dfsTree(nxt);
}
void dfsEulerPath(int u) {
  if (in[u] == -1) in[u] = (int)(eulerPath.size());
  eulerPath.push_back(u);
  for (auto it : linkTree[u]) dfsEulerPath(it);
  if (out[u] == -1) out[u] = (int)(eulerPath.size());
  eulerPath.push_back(u);
}
void init() {
  int sz = (int)(t.size());
  vis.assign(sz, false);
  linkTree.resize(sz);
  vis[0] = true;
  for (int i(1), ThkMk(sz); i < ThkMk; ++i) dfsTree(i);
  in.assign(sz, -1);
  out.assign(sz, -1);
  dfsEulerPath(0);
  segtree = SegTree((int)(eulerPath.size()));
}
void dfs(int u, int ahoState) {
  segtree.update(0, 0, (int)(eulerPath.size()), in[ahoState], 1);
  for (int it : queries[u])
    ans[it] = segtree.query(0, 0, (int)(eulerPath.size()), in[queryState[it]],
                            out[queryState[it]]);
  for (auto it : graph[u]) {
    int nwState = go(ahoState, it.first);
    dfs(it.second, nwState);
  }
  segtree.update(0, 0, (int)(eulerPath.size()), in[ahoState], -1);
}
int main() {
  aho_init();
  long long n, q;
  cin >> n;
  int u, v;
  char c;
  string second;
  for (int i(1), ThkMk(n + 1); i < ThkMk; ++i) {
    cin >> u;
    if (u == 1) {
      cin >> c;
      graph[0].push_back({c, i});
    } else {
      cin >> u >> c;
      graph[u].push_back({c, i});
    }
  }
  cin >> q;
  queryState.resize(q);
  for (int i(0), ThkMk(q); i < ThkMk; ++i) {
    cin >> u >> second;
    int x = add_string(second);
    queries[u].push_back(i);
    queryState[i] = x;
  }
  init();
  dfs(0, 0);
  for (int i(0), ThkMk(q); i < ThkMk; ++i) cout << ans[i] << '\n';
  return 0;
}
