#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
using vi = vector<int>;
using ll = long long;
const int N = 1e5, S = 100;
const int LOGN = 20;
mt19937 rng;
struct basicHashing {
  int mod, mul;
  bool prime(int n) {
    for (int d = 2; d * d <= n; d++)
      if (n % d == 0) return false;
    return true;
  }
  void randomize() {
    rng.seed(chrono::steady_clock::now().time_since_epoch().count());
    mod = uniform_int_distribution<>(0, (int)5e8)(rng) + 1e9;
    while (!prime(mod)) mod++;
    mul = uniform_int_distribution<>(2, mod - 2)(rng);
  }
  basicHashing() {
    init();
    randomize();
  }
  vi h, pot;
  void init() {
    h.resize(1), pot.resize(1);
    h[0] = 0, pot[0] = 1;
  }
  void process(const string &s) {
    init();
    h.resize(int((s).size()) + 1);
    pot.resize(int((s).size()) + 1);
    for (int i = int(0); i < int(int((s).size())); i++)
      h[i + 1] = (((ll)h[i] * mul) + s[i]) % mod;
    for (int i = int(0); i < int(int((s).size())); i++)
      pot[i + 1] = (ll)pot[i] * mul % mod;
  }
  int hash(int i, int j) {
    int res = h[j] - (ll)h[i] * pot[j - i] % mod;
    if (res < 0) res += mod;
    return res;
  }
  int hash(const string &s) {
    int res = 0;
    for (char c : s) res = ((ll)res * mul + c) % mod;
    return res;
  }
  void push(char c) {
    h.emplace_back(((ll)h.back() * mul + c) % mod);
    pot.emplace_back((ll)pot.back() * mul % mod);
  }
  void pop() { h.pop_back(), pot.pop_back(); }
};
struct hashing {
  basicHashing h1, h2;
  void process(const string &s) { h1.process(s), h2.process(s); }
  void init() { h1.init(), h2.init(); }
  ll hash(int i, int j) { return ((ll)h1.hash(i, j) << 32) + h2.hash(i, j); }
  ll hash(const string &s) { return ((ll)h1.hash(s) << 32) + h2.hash(s); }
  void push(char c) { h1.push(c), h2.push(c); }
  void pop() { h1.pop(), h2.pop(); }
} h;
struct Query {
  int op, ind;
  ll hash;
  Query(int _op, int _ind, ll _hash) : op(_op), ind(_ind), hash(_hash) {}
};
vector<pair<int, char>> adj[N];
int f[N][LOGN], L[N];
char fch[N];
void dfs(int u = 0, int fa = -1, char fc = 0, int lvl = 0) {
  f[u][0] = fa, fch[u] = fc, L[u] = lvl;
  for (auto [v, c] : adj[u])
    if (v != fa) dfs(v, u, c, lvl + 1);
}
void build() {
  for (int k = int(0); k < int(LOGN - 1); k++)
    for (int i = int(0); i < int(N); i++)
      if (f[i][k] != -1) f[i][k + 1] = f[f[i][k]][k];
}
int climb(int a, int d) {
  if (!d) return a;
  for (int i = int((31 - __builtin_clz(L[a])) + 1 - 1); i >= int(0); i--)
    if (1 << i <= d) a = f[a][i], d -= 1 << i;
  return a;
}
int lca(int a, int b) {
  if (L[a] < L[b]) swap(a, b);
  a = climb(a, L[a] - L[b]);
  if (a == b) return a;
  for (int i = int((31 - __builtin_clz(L[a])) + 1 - 1); i >= int(0); i--)
    if (f[a][i] != f[b][i]) a = f[a][i], b = f[b][i];
  return f[a][0];
}
int dist(int a, int b) { return L[a] + L[b] - 2 * L[lca(a, b)]; }
int ans[N];
vector<Query> queries[N];
unordered_map<ll, int> active;
void go(int u = 0, int p = -1) {
  int sz = L[u];
  for (int k = int(1); k < int(min(sz, S) + 1); k++) {
    ll hash = h.hash(sz - k, sz);
    if (active.count(hash)) active[hash]++;
  }
  for (auto [op, ind, hash] : queries[u]) ans[ind] += op * active[hash];
  for (auto [v, c] : adj[u])
    if (v != p) {
      h.push(c);
      go(v, u);
      h.pop();
    }
  for (int k = int(1); k < int(min(sz, S) + 1); k++) {
    ll hash = h.hash(sz - k, sz);
    if (active.count(hash)) active[hash]--;
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n;
  cin >> n;
  for (int _ = int(0); _ < int(n - 1); _++) {
    int u, v;
    char c;
    cin >> u >> v >> c;
    u--, v--;
    adj[u].emplace_back(v, c);
    adj[v].emplace_back(u, c);
  }
  dfs();
  build();
  int qs;
  cin >> qs;
  for (int q = int(0); q < int(qs); q++) {
    int u, v;
    string s;
    cin >> u >> v >> s;
    u--, v--;
    int m = int((s).size());
    int w = lca(u, v);
    ll y = h.hash(s);
    reverse(s.begin(), s.end());
    ll yr = h.hash(s);
    active[y] = 0;
    active[yr] = 0;
    queries[u].emplace_back(1, q, yr);
    queries[v].emplace_back(1, q, y);
    u = climb(u, max(0, L[u] - (L[w] + m - 1)));
    v = climb(v, max(0, L[v] - (L[w] + m - 1)));
    queries[u].emplace_back(-1, q, yr);
    queries[v].emplace_back(-1, q, y);
    if (w == u || w == v) continue;
    string t;
    while (u != w) {
      t += fch[u];
      u = f[u][0];
    }
    string temp;
    while (v != w) {
      temp += fch[v];
      v = f[v][0];
    }
    reverse(temp.begin(), temp.end());
    t += temp;
    h.process(t);
    for (int i = int(0); i < int(int((t).size()) - m + 1); i++) {
      ll x = h.hash(i, i + m);
      if (x == y) ans[q]++;
    }
  }
  h.init();
  go();
  for (int i = int(0); i < int(qs); i++) cout << ans[i] << '\n';
  return 0;
}
