#include <bits/stdc++.h>
using namespace std;
const int MAXC = 26;
struct Node {
  bool is_terminal = false;
  int parent;
  int parent_char;
  int depth;
  int suffix_link = -1;
  int terminal_link = -1;
  int next[MAXC];
  int go[MAXC];
  Node(int p, int pch, int d) : parent(p), parent_char(pch), depth(d) {
    memset(next, -1, sizeof(next));
    memset(go, -1, sizeof(go));
  }
};
struct Trie {
  vector<Node> nodes;
  Trie(int n) {
    nodes.reserve(n);
    nodes.emplace_back(-1, -1, 0);
  }
  Trie() : Trie(0) {}
  int convert_char(char chr) { return chr - 'a'; }
  int add(const string &word) {
    int id = 0;
    for (char chr : word) {
      int c = convert_char(chr);
      if (nodes[id].next[c] == -1) {
        nodes[id].next[c] = nodes.size();
        nodes.emplace_back(id, c, nodes[id].depth + 1);
      }
      id = nodes[id].next[c];
    }
    nodes[id].is_terminal = true;
    return id;
  }
  void build() {
    queue<int> q;
    q.push(0);
    while (!q.empty()) {
      int id = q.front();
      q.pop();
      if (id == 0 || nodes[id].parent == 0) {
        nodes[id].suffix_link = 0;
      } else {
        nodes[id].suffix_link =
            get_go(get_suffix_link(nodes[id].parent), nodes[id].parent_char);
      }
      for (int c = 0; c < MAXC; c++) {
        if (nodes[id].next[c] != -1) {
          nodes[id].go[c] = nodes[id].next[c];
        } else if (id == 0) {
          nodes[id].go[c] = 0;
        } else {
          nodes[id].go[c] = get_go(get_suffix_link(id), c);
        }
      }
      if (id == 0) {
        nodes[id].terminal_link = -1;
      } else if (nodes[nodes[id].suffix_link].is_terminal) {
        nodes[id].terminal_link = nodes[id].suffix_link;
      } else {
        nodes[id].terminal_link = get_terminal_link(get_suffix_link(id));
      }
      for (int c = 0; c < MAXC; c++) {
        if (nodes[id].next[c] != -1) {
          q.push(nodes[id].next[c]);
        }
      }
    }
  }
  int get_suffix_link(int id) { return nodes[id].suffix_link; }
  int get_go(int id, char chr) { return get_go(id, convert_char(chr)); }
  int get_go(int id, int c) { return nodes[id].go[c]; }
  int get_terminal_link(int id) { return nodes[id].terminal_link; }
};
const int N = 400005, FN = 2 * N;
vector<pair<int, char>> g[N];
int query_ids[N];
vector<int> query_indices[N];
int result[N];
Trie trie(N);
vector<int> g_suffix[N];
int tin[N], tout[N], t = 1, fenwick[FN];
void add(int i, int v) {
  while (i < FN) {
    fenwick[i] += v;
    i |= i + 1;
  }
}
int sum(int i) {
  int result = 0;
  while (i >= 0) {
    result += fenwick[i];
    i = (i & (i + 1)) - 1;
  }
  return result;
}
void dfs_suffix(int u) {
  tin[u] = t++;
  for (int v : g_suffix[u]) {
    dfs_suffix(v);
  }
  tout[u] = t++;
}
void add_to_path(int id, int v) { add(tin[id], v); }
int get_occs(int id) { return sum(tout[id]) - sum(tin[id] - 1); }
void dfs(int song_id, int node_id) {
  add_to_path(node_id, 1);
  for (int i : query_indices[song_id]) {
    result[i] = get_occs(query_ids[i]);
  }
  for (const auto &p : g[song_id]) {
    int next_song_id = p.first;
    char chr = p.second;
    int next_node_id = trie.get_go(node_id, chr);
    dfs(next_song_id, next_node_id);
  }
  add_to_path(node_id, -1);
}
void solve() {
  int n;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    int t, j;
    char c;
    cin >> t;
    if (t == 1) {
      cin >> c;
      j = 0;
    } else {
      cin >> j >> c;
    }
    g[j].emplace_back(i, c);
  }
  int m;
  cin >> m;
  for (int i = 0; i < m; i++) {
    int song_id;
    string query;
    cin >> song_id >> query;
    query_ids[i] = trie.add(query);
    query_indices[song_id].push_back(i);
  }
  trie.build();
  for (int i = 1; i < (int)trie.nodes.size(); i++) {
    g_suffix[trie.nodes[i].suffix_link].push_back(i);
  }
  dfs_suffix(0);
  dfs(0, 0);
  for (int i = 0; i < m; i++) {
    cout << result[i] << "\n";
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  solve();
}
