#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int gi() {
  int x = 0, o = 1;
  char ch = getchar();
  while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
  if (ch == '-') o = -1, ch = getchar();
  while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
  return x * o;
}
int n, m, q, siz[N], mn, all, rt, len[N], qu[N], qv[N], qs[N], from[N], tim,
    tag[N], lenu[N], lenv[N], cur_len, ans[N], to[N], nxt[N], h[N];
bool vis[N];
vector<int> E[N], qryu[N], qryv[N], qryt[N], qryc[N];
char s[N], ww[N], *str[N];
void adde(int u, int v, char w) {
  static int tt = 1;
  to[++tt] = v;
  ww[tt] = w;
  nxt[tt] = h[u];
  h[u] = tt;
  to[++tt] = u;
  ww[tt] = w;
  nxt[tt] = h[v];
  h[v] = tt;
}
struct AC {
  int ch[N][26], fa[N], len[N], dfn[N], low[N], tim, n, c[N], id, pos[N];
  vector<int> E[N];
  void clear() {
    for (int i = 0; i <= n; i++) {
      memset(ch[i], 0, sizeof(ch[i]));
      fa[i] = len[i] = dfn[i] = low[i] = 0;
      E[i].clear();
    }
    for (int i = 1; i <= id; i++) pos[i] = 0;
    n = tim = id = 0;
  }
  void insert(char *s) {
    int len = strlen(s + 1), u = 0;
    for (int i = 1; i <= len; i++) {
      if (!ch[u][s[i] - 'a']) ch[u][s[i] - 'a'] = ++n;
      u = ch[u][s[i] - 'a'];
    }
    pos[++id] = u;
  }
  void dfs(int u) {
    dfn[u] = ++tim;
    for (auto v : E[u]) dfs(v);
    low[u] = tim;
  }
  void build() {
    queue<int> q;
    for (int i = 0; i < 26; i++)
      if (ch[0][i]) q.push(ch[0][i]);
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      for (int i = 0; i < 26; i++) {
        if (ch[u][i])
          fa[ch[u][i]] = ch[fa[u]][i], q.push(ch[u][i]);
        else
          ch[u][i] = ch[fa[u]][i];
      }
    }
    for (int i = 1; i <= n; i++) E[fa[i]].push_back(i);
    dfs(0);
  }
  void _modify(int p, int v) {
    while (p <= n + 1) c[p] += v, p += p & -p;
  }
  int _query(int p) {
    int ret = 0;
    while (p) ret += c[p], p -= p & -p;
    return ret;
  }
  void modify(int u, int v) { _modify(dfn[u], v); }
  int query(int u) {
    u = pos[u];
    return _query(low[u]) - _query(dfn[u] - 1);
  }
  void modify2(int u, int v) {
    _modify(dfn[u], v);
    _modify(low[u] + 1, -v);
  }
  int query2(int u) { return _query(dfn[u]); }
  void solve(int u, AC &A) {
    if (u && u < cur_len) A.modify2(cur_len - u, 1);
    for (auto i : qryc[u]) ans[i] += A.query2(lenv[i]);
    for (auto v : E[u]) solve(v, A);
    if (u && u < cur_len) A.modify2(cur_len - u, -1);
  }
} ac1, ac2, kmp1, kmp2;
struct SAM {
  int ch[N][26], fa[N], len[N], n = 1, lst = 1, dfn[N], low[N], tim, id, pos[N];
  vector<int> E[N], tr[N << 2];
  void extend(int c) {
    int p = lst;
    if (ch[p][c]) {
      int q = ch[p][c];
      if (len[p] + 1 == len[q])
        lst = q;
      else {
        int nq = ++n;
        len[nq] = len[p] + 1;
        lst = nq;
        memcpy(ch[nq], ch[q], sizeof(ch[q]));
        fa[nq] = fa[q];
        fa[q] = nq;
        for (; ch[p][c] == q; p = fa[p]) ch[p][c] = nq;
      }
    } else {
      int np = ++n;
      lst = np;
      len[np] = len[p] + 1;
      for (; p && !ch[p][c]; p = fa[p]) ch[p][c] = np;
      if (!p)
        fa[np] = 1;
      else {
        int q = ch[p][c];
        if (len[p] + 1 == len[q])
          fa[np] = q;
        else {
          int nq = ++n;
          len[nq] = len[p] + 1;
          memcpy(ch[nq], ch[q], sizeof(ch[q]));
          fa[nq] = fa[q];
          fa[q] = fa[np] = nq;
          for (; ch[p][c] == q; p = fa[p]) ch[p][c] = nq;
        }
      }
    }
  }
  void insert(char *s) {
    int len = strlen(s + 1);
    lst = 1;
    for (int i = 1; i <= len; i++) extend(s[i] - 'a');
    pos[++id] = lst;
  }
  void dfs(int u) {
    dfn[u] = ++tim;
    for (auto v : E[u]) dfs(v);
    low[u] = tim;
  }
  void build() {
    for (int i = 2; i <= n; i++) E[fa[i]].push_back(i);
    dfs(1);
  }
  void _modify(int L, int R, int v, int x, int l, int r) {
    if (L <= l && r <= R) {
      v >= 0 ? tr[x].push_back(v) : tr[x].pop_back();
      return;
    }
    int mid = (l + r) >> 1;
    if (L <= mid) _modify(L, R, v, (x << 1), l, mid);
    if (R > mid) _modify(L, R, v, (x << 1 | 1), mid + 1, r);
  }
  int _query(int p, int x, int l, int r) {
    if (l == r) return tr[x].empty() ? 0 : tr[x].back();
    int mid = (l + r) >> 1;
    return max(tr[x].empty() ? 0 : tr[x].back(),
               p <= mid ? _query(p, (x << 1), l, mid)
                        : _query(p, (x << 1 | 1), mid + 1, r));
  }
  void modify(int u, int v) {
    if (u) _modify(dfn[u], low[u], v, 1, 1, n);
  }
  int query(int u) {
    u = pos[u];
    return _query(dfn[u], 1, 1, n);
  }
} sam1, sam2;
void getrt(int u, int fa) {
  siz[u] = 1;
  int mx = 0;
  for (int i = h[u], v; v = to[i], i; i = nxt[i])
    if (!vis[v] && v != fa) {
      getrt(v, u);
      siz[u] += siz[v];
      mx = max(mx, siz[v]);
    }
  mx = max(mx, all - siz[u]);
  if (mx < mn) mn = mx, rt = u;
}
void dfs1(int u, int fa, int fr) {
  from[u] = fr;
  tag[u] = tim;
  for (int i = h[u], v; v = to[i], i; i = nxt[i])
    if (v != fa && !vis[v]) dfs1(v, u, fr);
}
void dfs2(int u, int fa, int ac1p, int ac2p, int sam1p, int sam2p, int dep) {
  ac1.modify(ac1p, 1);
  ac2.modify(ac2p, 1);
  sam1.modify(sam1p, dep);
  sam2.modify(sam2p, dep);
  for (auto i : qryv[u])
    if (tag[qu[i]] == tag[qv[i]] && from[qu[i]] != from[qv[i]]) {
      ans[i] += ac1.query(qs[i]);
      lenv[i] = sam1.query(qs[i]);
    }
  for (auto i : qryu[u])
    if (tag[qu[i]] == tag[qv[i]] && from[qu[i]] != from[qv[i]]) {
      ans[i] += ac2.query(qs[i]);
      lenu[i] = sam2.query(qs[i]);
    }
  for (int i = h[u], v; v = to[i], i; i = nxt[i])
    if (v != fa && !vis[v])
      dfs2(v, u, ac1.ch[ac1p][ww[i] - 'a'], ac2.ch[ac2p][ww[i] - 'a'],
           sam1.ch[sam1p][ww[i] - 'a'], sam2.ch[sam2p][ww[i] - 'a'], dep + 1);
  ac1.modify(ac1p, -1);
  ac2.modify(ac2p, -1);
  sam1.modify(sam1p, -1);
  sam2.modify(sam2p, -1);
}
void solve(int u) {
  getrt(u, 0);
  all = siz[u];
  mn = 1e9;
  getrt(u, 0);
  vis[u = rt] = 1;
  from[u] = u;
  tag[u] = ++tim;
  for (int i = h[u], v; v = to[i], i; i = nxt[i])
    if (!vis[v]) dfs1(v, u, v);
  dfs2(u, 0, 0, 0, 1, 1, 0);
  for (int i = h[u], v; v = to[i], i; i = nxt[i])
    if (!vis[v]) solve(v);
}
int main() {
  cin >> n >> m >> q;
  for (int i = 1, u, v; i < n; i++) {
    u = gi(), v = gi();
    char w[5];
    scanf("%s", w + 1);
    adde(u, v, w[1]);
  }
  for (int i = 1; i <= m; i++) {
    scanf("%s", s + 1);
    len[i] = strlen(s + 1);
    ac1.insert(s);
    sam1.insert(s);
    reverse(s + 1, s + len[i] + 1);
    ac2.insert(s);
    sam2.insert(s);
    reverse(s + 1, s + len[i] + 1);
    str[i] = new char[len[i] + 10];
    for (int j = 1; j <= len[i]; j++) str[i][j] = s[j];
    str[i][len[i] + 1] = '\0';
  }
  ac1.build();
  ac2.build();
  sam1.build();
  sam2.build();
  for (int i = 1; i <= q; i++) {
    qu[i] = gi();
    qv[i] = gi();
    qs[i] = gi();
    qryu[qu[i]].push_back(i);
    qryv[qv[i]].push_back(i);
  }
  solve(1);
  for (int i = 1; i <= q; i++) qryt[qs[i]].push_back(i);
  for (int i = 1; i <= m; i++) {
    kmp1.clear();
    kmp2.clear();
    kmp1.insert(str[i]);
    reverse(str[i] + 1, str[i] + len[i] + 1);
    kmp2.insert(str[i]);
    kmp1.build();
    kmp2.build();
    reverse(str[i] + 1, str[i] + len[i] + 1);
    for (int j = 0; j <= len[i]; j++) qryc[j].clear();
    for (auto t : qryt[i]) qryc[lenu[t]].push_back(t);
    cur_len = len[i];
    kmp1.solve(0, kmp2);
  }
  for (int i = 1; i <= q; i++) cout << ans[i] << '\n';
  return 0;
}
