#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 7, M = 110;
struct edge {
  int la, b;
  char v;
} e[N << 1];
int n, q, tot, hd[N], fa[N][20], dep[N], rt[N], ans[N];
unsigned long long val[N][M], nowv[N];
void add(int from, int to, char val) {
  e[++tot] = (edge){hd[from], to, val};
  hd[from] = tot;
}
void dfs(int pos, int f) {
  dep[pos] = dep[f] + 1;
  for (int i = 2, j = f; i <= 100; ++i, j = fa[j][0])
    val[pos][i] = val[pos][i - 1] * 233 + val[j][1];
  fa[pos][0] = f;
  for (int i = 1; i < 20; ++i) {
    fa[pos][i] = fa[fa[pos][i - 1]][i - 1];
    if (!fa[pos][i]) break;
  }
  for (int i = hd[pos]; i; i = e[i].la)
    if (e[i].b != f) {
      val[e[i].b][1] = e[i].v - 'a';
      dfs(e[i].b, pos);
    }
}
int lca(int x, int y) {
  if (dep[x] < dep[y]) swap(x, y);
  for (int i = 20 - 1; i >= 0; --i)
    if (dep[fa[x][i]] >= dep[y]) x = fa[x][i];
  if (x == y) return x;
  for (int i = 20 - 1; i >= 0; --i)
    if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
  return fa[x][0];
}
int up(int x, int k) {
  for (int i = 19; i >= 0; --i)
    if ((k >> i) & 1) x = fa[x][i];
  return x;
}
string str;
struct data {
  int u, v, id;
  string s;
};
vector<data> vec[M];
vector<unsigned long long> tmp;
struct node {
  int sum, ls, rs;
} t[N * 50];
int cnt, m;
void update(int& x, int y, int p, int lp = 1, int rp = m) {
  x = ++cnt, t[x] = t[y], ++t[x].sum;
  if (lp == rp) return;
  int mid = (lp + rp) >> 1;
  if (p <= mid)
    update(t[x].ls, t[y].ls, p, lp, mid);
  else
    update(t[x].rs, t[y].rs, p, mid + 1, rp);
}
int query(int p, int x, int px, int lp = 1, int rp = m) {
  if (lp == rp) return t[x].sum - t[px].sum;
  int mid = (lp + rp) >> 1;
  if (p <= mid)
    return query(p, t[x].ls, t[px].ls, lp, mid);
  else
    return query(p, t[x].rs, t[px].rs, mid + 1, rp);
}
unsigned long long dval[M], rval[M];
int solve(data que) {
  int ret = 0, z = lca(que.u, que.v), l = que.s.size();
  dval[0] = 0;
  for (int i = 0; i < l; ++i) dval[i + 1] = dval[i] * 233 + que.s[i] - 'a';
  rval[0] = 0;
  for (int i = 0; i < l; ++i)
    rval[i + 1] = rval[i] * 233 + que.s[l - i - 1] - 'a';
  if (dep[que.u] - dep[z] >= l) {
    do {
      int v = lower_bound(tmp.begin(), tmp.end(), dval[l]) - tmp.begin() + 1;
      if (v > m || dval[l] != tmp[v - 1]) break;
      ret += query(v, rt[que.u], rt[up(que.u, dep[que.u] - dep[z] - l + 1)]);
    } while (0);
  }
  if (dep[que.v] - dep[z] >= l) {
    do {
      int v = lower_bound(tmp.begin(), tmp.end(), rval[l]) - tmp.begin() + 1;
      if (v > m || rval[l] != tmp[v - 1]) break;
      ret += query(v, rt[que.v], rt[up(que.v, dep[que.v] - dep[z] - l + 1)]);
    } while (0);
  }
  for (int i = up(que.u, max(0, dep[que.u] - dep[z] - l + 1)), j; i != z;
       i = fa[i][0]) {
    int step = dep[que.v] - dep[z] - (l - (dep[i] - dep[z]));
    if (step < 0) continue;
    j = up(que.v, step);
    if (val[i][dep[i] - dep[z]] == dval[dep[i] - dep[z]] &&
        val[j][dep[j] - dep[z]] == rval[dep[j] - dep[z]])
      ++ret;
  }
  return ret;
}
void fsd(int pos) {
  update(rt[pos], rt[fa[pos][0]], nowv[pos]);
  for (int i = hd[pos]; i; i = e[i].la)
    if (e[i].b != fa[pos][0]) fsd(e[i].b);
}
void work() {
  for (int i = 1; i <= 100; ++i)
    if (vec[i].size()) {
      tmp.clear();
      cnt = 1;
      for (int j = 1; j <= n; ++j) tmp.push_back(val[j][i]);
      sort(tmp.begin(), tmp.end());
      tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
      for (int j = 1; j <= n; ++j)
        nowv[j] =
            lower_bound(tmp.begin(), tmp.end(), val[j][i]) - tmp.begin() + 1;
      m = tmp.size();
      fsd(1);
      for (int j = 0; j < vec[i].size(); ++j)
        ans[vec[i][j].id] = solve(vec[i][j]);
    }
}
int main() {
  scanf("%d", &n);
  char z;
  for (int i = 1, x, y; i < n; ++i)
    scanf("%d%d %c", &x, &y, &z), add(x, y, z), add(y, x, z);
  dfs(1, 0);
  scanf("%d", &q);
  for (int i = 1, x, y; i <= q; ++i) {
    scanf("%d%d", &x, &y);
    cin >> str;
    vec[str.size()].push_back((data){x, y, i, str});
  }
  work();
  for (int i = 1; i <= q; ++i) printf("%d\n", ans[i]);
}
