#include <bits/stdc++.h>
using namespace std;
const int ALPHA = 26, B = 3000;
const int N = 200 * B + 1e5;
int to[N][ALPHA], nxt[N][ALPHA];
int dph[N], sl[N], par[N], pl[N];
int sub_cnt[N];
int tot = 1;
void init() {
  memset(to, 0, sizeof to);
  memset(nxt, 0, sizeof nxt);
  memset(dph, 0, sizeof dph);
  memset(sl, 0, sizeof sl);
  memset(par, 0, sizeof par);
  memset(pl, 0, sizeof pl);
  memset(sub_cnt, 0, sizeof sub_cnt);
  tot = 1;
}
int add_string(string &s) {
  int u = 1;
  for (int i = 0; i < s.size(); i++) {
    int c = s[i] - 'a';
    if (!to[u][c])
      to[u][c] = ++tot, par[tot] = u, dph[tot] = dph[u] + 1, pl[tot] = c;
    u = to[u][c];
  }
  return u;
}
void push_links() {
  queue<int> q;
  q.push(1);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    if (dph[u] <= 1)
      sl[u] = 1;
    else {
      int v = sl[par[u]], l = pl[u];
      while (v > 1 && !to[v][l]) v = sl[v];
      if (to[v][l]) v = to[v][l];
      sl[u] = v;
    }
    for (int i = 0; i < ALPHA; i++)
      if (to[u][i]) q.push(to[u][i]);
  }
}
int jump(int u, int c) {
  if (nxt[u][c]) return nxt[u][c];
  int v = u;
  while (v > 1 && !to[v][c]) v = sl[v];
  if (to[v][c]) v = to[v][c];
  return nxt[u][c] = v;
}
vector<int> prefix_function(string s) {
  int n = (int)s.length();
  vector<int> pi(n);
  for (int i = 1; i < n; ++i) {
    int j = pi[i - 1];
    while (j > 0 && s[i] != s[j]) j = pi[j - 1];
    if (s[i] == s[j]) ++j;
    pi[i] = j;
  }
  return pi;
}
int occ(string s, string t) {
  int n = s.size();
  s = s + "?" + t;
  vector<int> p = prefix_function(s);
  int cnt = 0;
  for (int x : p)
    if (x == n) cnt++;
  return cnt;
}
const int M = 1e5 + 100, LOG = 20;
vector<int> G[M];
vector<char> Let[M];
int Par[M][20];
char Pl[M];
int depth[M];
int res[M];
void dfs(int u, int p, int d, char ch) {
  depth[u] = d;
  Par[u][0] = p;
  Pl[u] = ch;
  for (int k = 1; k < LOG; k++) {
    if (Par[u][k - 1] == -1)
      Par[u][k] = -1;
    else
      Par[u][k] = Par[Par[u][k - 1]][k - 1];
  }
  for (int i = 0; i < G[u].size(); i++) {
    int v = G[u][i];
    if (v == p) continue;
    dfs(v, u, d + 1, Let[u][i]);
  }
}
int kth_par(int u, int kth) {
  for (int k = LOG - 1; k >= 0; k--) {
    if ((kth >> k) & 1) u = Par[u][k];
  }
  return u;
}
int LCA(int u, int v) {
  if (depth[u] < depth[v]) swap(u, v);
  int diff = depth[u] - depth[v];
  u = kth_par(u, diff);
  if (u == v) return u;
  for (int k = LOG - 1; k >= 0; k--) {
    if (Par[u][k] != Par[v][k]) u = Par[u][k], v = Par[v][k];
  }
  return Par[u][0];
}
vector<pair<int, int>> Q[M];
void solve(int u, int p, int cur) {
  int tt = cur;
  while (true) {
    sub_cnt[tt]++;
    if (tt == 1) break;
    tt = sl[tt];
  }
  for (auto t : Q[u]) {
    int node = t.first, idx = t.second >> 1;
    bool f = t.second & 1;
    res[idx] += (f ? +sub_cnt[node] : -sub_cnt[node]);
  }
  for (int i = 0; i < G[u].size(); i++) {
    int v = G[u][i];
    if (v == p) continue;
    char ch = Let[u][i];
    solve(v, u, jump(cur, ch - 'a'));
  }
  tt = cur;
  while (true) {
    sub_cnt[tt]--;
    if (tt == 1) break;
    tt = sl[tt];
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n;
  for (int i = 1; i < n; i++) {
    int u, v;
    char ch;
    cin >> u >> v >> ch;
    G[u].push_back(v);
    G[v].push_back(u);
    Let[u].push_back(ch);
    Let[v].push_back(ch);
  }
  dfs(1, -1, 0, 'a');
  int q;
  cin >> q;
  for (int ii = 1; ii <= q; ii += B) {
    int l = ii, r = min(q, ii + B - 1);
    init();
    for (int i = 1; i <= n; i++) {
      Q[i].clear();
    }
    for (int i = l; i <= r; i++) {
      int u, v;
      string s;
      cin >> u >> v >> s;
      if (u == v) continue;
      int lca = LCA(u, v);
      if (lca == v) {
        if (depth[u] - depth[lca] < s.size()) continue;
        reverse(s.begin(), s.end());
        int state = add_string(s);
        Q[u].push_back({state, (i << 1) | 1});
        int del = kth_par(u, depth[u] - depth[lca] - s.size() + 1);
        Q[del].push_back({state, (i << 1)});
      } else if (lca == u) {
        if (depth[v] - depth[lca] < s.size()) continue;
        int state = add_string(s);
        Q[v].push_back({state, (i << 1) | 1});
        int del = kth_par(v, depth[v] - depth[lca] - s.size() + 1);
        Q[del].push_back({state, (i << 1)});
      } else {
        if (s.size() > 1) {
          int da = depth[u] - depth[lca];
          int uu = kth_par(u, max(0, da - (int)s.size() + 1));
          string L;
          while (uu != lca) {
            L.push_back(Pl[uu]);
            uu = Par[uu][0];
          }
          int db = depth[v] - depth[lca];
          int vv = kth_par(v, max(0, db - (int)s.size() + 1));
          string R;
          while (vv != lca) {
            R.push_back(Pl[vv]);
            vv = Par[vv][0];
          }
          reverse(R.begin(), R.end());
          string mid = L + R;
          res[i] += occ(s, mid);
        }
        if (depth[v] - depth[lca] >= s.size()) {
          int state = add_string(s);
          Q[v].push_back({state, (i << 1) | 1});
          int del = kth_par(v, depth[v] - depth[lca] - s.size() + 1);
          Q[del].push_back({state, (i << 1)});
        }
        if (depth[u] - depth[lca] >= s.size()) {
          reverse(s.begin(), s.end());
          int state = add_string(s);
          Q[u].push_back({state, (i << 1) | 1});
          int del = kth_par(u, depth[u] - depth[lca] - s.size() + 1);
          Q[del].push_back({state, (i << 1)});
        }
      }
    }
    push_links();
    solve(1, -1, 1);
  }
  for (int i = 1; i <= q; i++) {
    cout << res[i] << " ";
  }
}
