#include <bits/stdc++.h>
using namespace std;
const long double eps = 1e-10;
const long double pi = acos(-1);
inline int dcmp(long double x) {
  if (x < -eps) return -1;
  if (x > eps) return 1;
  return 0;
}
const int maxn = 4e5 + 5;
struct {
  int to, nxt;
} e[maxn];
int tot;
int head[maxn];
char c[maxn];
void ae(int u, int v) {
  e[tot] = {v, head[u]};
  head[u] = tot++;
}
struct node {
  int to[26], fail;
} a[maxn];
int cnt = 0;
int newnode() {
  memset((a[cnt].to), 0, sizeof((a[cnt].to)));
  a[cnt].fail = 0;
  return cnt++;
}
void init() {
  cnt = 0;
  newnode();
  tot = 0;
  memset((head), -1, sizeof((head)));
}
int add(char s[]) {
  int n = strlen(s);
  int now = 0;
  for (int i = 0; i < n; ++i) {
    int k = s[i] - 'a';
    if (!a[now].to[k]) a[now].to[k] = newnode();
    now = a[now].to[k];
  }
  return now;
}
void build() {
  queue<int> q;
  a[0].fail = 0;
  for (int i = 0; i < 26; ++i)
    if (a[0].to[i]) {
      a[a[0].to[i]].fail = 0;
      q.push(a[0].to[i]);
    }
  while (!q.empty()) {
    int now = q.front();
    q.pop();
    for (int i = 0; i < 26; ++i) {
      int son = a[now].to[i];
      if (son) {
        a[son].fail = a[a[now].fail].to[i];
        q.push(son);
      } else
        a[now].to[i] = a[a[now].fail].to[i];
    }
  }
}
struct ed {
  int to, nxt;
} ed[maxn];
int hd[maxn];
int tt;
int fa[maxn], dep[maxn], siz[maxn], son[maxn], rk[maxn], top[maxn], id[maxn];
int cc, N;
int t[maxn << 2];
int lzy[maxn << 2];
void init1() {
  memset((hd), -1, sizeof((hd)));
  tt = 0;
  cc = 0;
}
void aed(int u, int v) {
  ed[tt] = {v, hd[u]};
  hd[u] = tt++;
}
void dfs1(int u) {
  dep[u] = dep[fa[u]] + 1;
  siz[u] = 1;
  for (int i = hd[u]; ~i; i = ed[i].nxt) {
    int v = ed[i].to;
    fa[v] = u;
    dfs1(v);
    siz[u] += siz[v];
    if (siz[v] > siz[son[u]]) son[u] = v;
  }
}
void dfs2(int u, int t) {
  top[u] = t;
  id[u] = ++cc;
  rk[cc] = u;
  if (!son[u]) return;
  dfs2(son[u], t);
  for (int i = hd[u]; ~i; i = ed[i].nxt) {
    int v = ed[i].to;
    if (v != son[u]) dfs2(v, v);
  }
}
void bd(int l, int r, int rt) {
  lzy[rt] = 0;
  if (l == r) {
    t[rt] = 0;
    return;
  }
  int m = (l + r) >> 1;
  bd(l, m, (rt << 1));
  bd(m + 1, r, (rt << 1) | 1);
  t[rt] = (t[(rt << 1)] + t[(rt << 1) | 1]);
}
void pushdown(int l, int r, int rt) {
  if (lzy[rt]) {
    int m = (l + r) >> 1;
    (lzy[(rt << 1)] += lzy[rt]);
    (lzy[(rt << 1) | 1] += lzy[rt]);
    (t[(rt << 1)] += lzy[rt] * (m - l + 1));
    (t[(rt << 1) | 1] += lzy[rt] * (r - m));
    lzy[rt] = 0;
  }
}
void update(int L, int R, long long k, int l, int r, int rt) {
  if (L <= l && r <= R) {
    t[rt] += k * (r - l + 1);
    lzy[rt] += k;
    return;
  }
  pushdown(l, r, rt);
  int m = (l + r) >> 1;
  if (m >= R)
    update(L, R, k, l, m, (rt << 1));
  else if (m < L)
    update(L, R, k, m + 1, r, (rt << 1) | 1);
  else {
    update(L, m, k, l, m, (rt << 1));
    update(m + 1, R, k, m + 1, r, (rt << 1) | 1);
  }
  t[rt] = (t[(rt << 1)] + t[(rt << 1) | 1]);
}
long long query(int L, int R, int l, int r, int rt) {
  if (L <= l && r <= R) return t[rt];
  pushdown(l, r, rt);
  int m = (l + r) >> 1;
  if (m >= R)
    return query(L, R, l, m, (rt << 1));
  else if (m < L)
    return query(L, R, m + 1, r, (rt << 1) | 1);
  else
    return (query(L, m, l, m, (rt << 1)) +
            query(m + 1, R, m + 1, r, (rt << 1) | 1));
}
long long sum(int x, int y) {
  long long ans = 0;
  int fx = top[x], fy = top[y];
  while (fx != fy) {
    if (dep[fx] >= dep[fy]) {
      (ans += query(id[fx], id[x], 1, N, 1));
      x = fa[fx];
    } else {
      (ans += query(id[fy], id[y], 1, N, 1));
      y = fa[fy];
    }
    fx = top[x];
    fy = top[y];
  }
  if (id[x] <= id[y])
    (ans += query(id[x], id[y], 1, N, 1));
  else
    (ans += query(id[y], id[x], 1, N, 1));
  return ans;
}
void update_t(int x, int y, long long v) {
  int fx = top[x], fy = top[y];
  while (fx != fy) {
    if (dep[fx] >= dep[fy]) {
      update(id[fx], id[x], v, 1, N, 1);
      x = fa[fx];
    } else {
      update(id[fy], id[y], v, 1, N, 1);
      y = fa[fy];
    }
    fx = top[x];
    fy = top[y];
  }
  if (id[x] <= id[y])
    update(id[x], id[y], v, 1, N, 1);
  else
    update(id[y], id[x], v, 1, N, 1);
}
char s[maxn];
int res[maxn];
vector<pair<int, int> > que[maxn];
void go(int u, int p) {
  for (auto i : que[u]) res[i.first] = sum(i.second + 1, i.second + 1);
  for (int i = head[u]; ~i; i = e[i].nxt) {
    int v = e[i].to;
    int now = a[p].to[c[v] - 'a'];
    update_t(1, now + 1, 1);
    go(v, now);
    update_t(1, now + 1, -1);
  }
}
int main() {
  int n;
  while (~scanf("%d", &n)) {
    init();
    for (int i = 1; i <= n; ++i) {
      que[i].clear();
      int t, f;
      scanf("%d", &t);
      if (t == 1) {
        scanf("%s", s);
        c[i] = s[0];
        ae(0, i);
      } else {
        scanf("%d", &f);
        scanf("%s", s);
        c[i] = s[0];
        ae(f, i);
      }
    }
    int m;
    scanf("%d", &m);
    for (int i = 1; i <= m; ++i) {
      int u;
      scanf("%d%s", &u, s);
      int id = add(s);
      que[u].push_back({i, id});
    }
    build();
    init1();
    for (int i = 0; i < cnt; ++i)
      if (i != a[i].fail) aed(a[i].fail + 1, i + 1);
    N = cnt;
    bd(1, N, 1);
    dfs1(1);
    dfs2(1, 1);
    go(0, 0);
    for (int i = 1; i <= m; ++i) printf("%d\n", res[i]);
  }
}
