#include <bits/stdc++.h>
long long gi() {
  long long x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) f ^= ch == '-', ch = getchar();
  while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
  return f ? x : -x;
}
std::mt19937 rnd(time(NULL));
template <class T>
void cxk(T& a, T b) {
  a = a > b ? a : b;
}
template <class T>
void cnk(T& a, T b) {
  a = a < b ? a : b;
}
namespace tree {
std::vector<int> G[200010];
int DFN;
void dfs(int x, int* dfn, int* end) {
  if (x) ++DFN;
  dfn[x] = DFN;
  for (int i : G[x]) dfs(i, dfn, end);
  end[x] = DFN;
}
void build(int rt, int n, int* fa, int* dfn, int* end) {
  for (int i = rt + 1; i <= n; ++i) G[fa[i]].push_back(i);
  DFN = 0;
  dfs(rt, dfn, end);
  for (int i = rt; i <= n; ++i) G[i].clear();
}
};  // namespace tree
struct bit {
  int t[100010], N;
  bit() { memset(t, 0, sizeof t); }
  void update(int x, int d) {
    while (x <= N) t[x] += d, x += x & -x;
  }
  int query(int x) {
    int r = 0;
    while (x) r += t[x], x -= x & -x;
    return r;
  }
};
struct AC {
  int ch[100010][26], fail[100010], cnt, node[100010], now, dfn[100010],
      end[100010];
  void endt(int i) {
    node[i] = now;
    now = 0;
  }
  void extend(int c) {
    if (!ch[now][c]) ch[now][c] = ++cnt;
    now = ch[now][c];
  }
  int que[100010], hd, tl, trans[100010][26];
  bit s;
  void build() {
    que[tl++] = 0;
    while (hd ^ tl) {
      int x = que[hd++];
      for (int i = 0; i < 26; ++i)
        if (ch[x][i]) {
          trans[x][i] = ch[x][i];
          fail[ch[x][i]] = !x ? 0 : trans[fail[x]][i];
          que[tl++] = ch[x][i];
        } else
          trans[x][i] = trans[fail[x]][i];
    }
    s.N = cnt;
    tree::build(0, cnt, fail, dfn, end);
  }
} AA, AB;
struct SAM {
  int ch[200010][26], len[200010], slink[200010],
      cnt = 1, node[200010], lst = 1, dfn[200010], end[200010];
  void endt(int i) {
    node[i] = lst;
    lst = 1;
  }
  void extend(int c) {
    if (ch[lst][c]) {
      int q = ch[lst][c];
      if (len[q] == len[lst] + 1)
        lst = q;
      else {
        int p = lst, nq = ++cnt;
        len[nq] = len[lst] + 1;
        memcpy(ch[nq], ch[q], 4 * 26);
        slink[nq] = slink[q];
        while (p && ch[p][c] == q) ch[p][c] = nq, p = slink[p];
        slink[q] = lst = nq;
      }
      return;
    }
    int x = ++cnt, p = lst;
    len[x] = len[p] + 1;
    lst = x;
    while (p && !ch[p][c]) ch[p][c] = x, p = slink[p];
    if (!p)
      slink[x] = 1;
    else {
      int q = ch[p][c];
      if (len[q] == len[p] + 1)
        slink[x] = q;
      else {
        int nq = ++cnt;
        memcpy(ch[nq], ch[q], 4 * 26);
        slink[nq] = slink[q];
        len[nq] = len[p] + 1;
        while (p && ch[p][c] == q) ch[p][c] = nq, p = slink[p];
        slink[x] = slink[q] = nq;
      }
    }
  }
  void build() { tree::build(1, cnt, slink, dfn, end); }
  std::vector<int> seg[800010];
  void Push(int x, int l, int r, int L, int R, int d) {
    if (L <= l && r <= R) return seg[x].push_back(d);
    if (L <= ((l + r) >> 1)) Push(x << 1, l, ((l + r) >> 1), L, R, d);
    if (((l + r) >> 1) < R) Push(x << 1 | 1, ((l + r) >> 1) + 1, r, L, R, d);
  }
  void Pop(int x, int l, int r, int L, int R) {
    if (L <= l && r <= R) return seg[x].pop_back();
    if (L <= ((l + r) >> 1)) Pop(x << 1, l, ((l + r) >> 1), L, R);
    if (((l + r) >> 1) < R) Pop(x << 1 | 1, ((l + r) >> 1) + 1, r, L, R);
  }
  int Get(int x, int l, int r, int p) {
    if (l == r) return seg[x].empty() ? 0 : seg[x].back();
    return std::max(seg[x].empty() ? 0 : seg[x].back(),
                    p <= ((l + r) >> 1)
                        ? Get(x << 1, l, ((l + r) >> 1), p)
                        : Get(x << 1 | 1, ((l + r) >> 1) + 1, r, p));
  }
} SA, SB;
int fir[100010], dis[200010], nxt[200010], id, W[200010];
void link(int a, int b, int c) {
  nxt[++id] = fir[a], fir[a] = id, dis[id] = b, W[id] = c;
}
int ans[100010], pl[100010], pr[100010];
int qx[100010], qy[100010], qs[100010];
std::vector<int> vx[100010], vy[100010];
bool vis[100010];
int f[100010], rt, N, siz[100010];
void getrt(int x, int fa = -1) {
  siz[x] = 1;
  f[x] = 0;
  for (int i = fir[x]; i; i = nxt[i]) {
    if (vis[dis[i]] || dis[i] == fa) continue;
    getrt(dis[i], x);
    siz[x] += siz[dis[i]];
    f[x] = std::max(f[x], siz[dis[i]]);
  }
  f[x] = std::max(f[x], N - siz[x]);
  if (f[x] < f[rt]) rt = x;
}
int tAA[100010], tAB[100010], tSA[100010], tSB[100010], from[100010],
    From[100010];
void DFS(int x, int fa = -1) {
  for (int i = fir[x]; i; i = nxt[i]) {
    if (vis[dis[i]] || dis[i] == fa) continue;
    from[dis[i]] = from[x] ? from[x] : dis[i];
    From[dis[i]] = From[x];
    tAA[dis[i]] = AA.trans[tAA[x]][W[i]];
    tAB[dis[i]] = AB.trans[tAB[x]][W[i]];
    int A = tSA[x], B = tSB[x];
    while (A && !SA.ch[tSA[x]][W[i]]) A = SA.slink[A];
    while (B && !SB.ch[tSB[x]][W[i]]) B = SB.slink[B];
    tSA[dis[i]] = SA.ch[A][W[i]];
    tSB[dis[i]] = SB.ch[B][W[i]];
    DFS(dis[i], x);
  }
}
void DFS2(int x, int len, int fa = -1) {
  if (~fa) {
    if (tAA[x]) AA.s.update(AA.dfn[tAA[x]], 1);
    if (tSA[x]) SA.Push(1, 1, SA.cnt, SA.dfn[tSA[x]], SA.end[tSA[x]], len);
    if (tAB[x]) AB.s.update(AB.dfn[tAB[x]], 1);
    if (tSB[x]) SB.Push(1, 1, SB.cnt, SB.dfn[tSB[x]], SB.end[tSB[x]], len);
  }
  for (int i : vx[x])
    if (from[qy[i]] != from[x] && From[qy[i]] == From[x]) {
      ans[i] += AB.s.query(AB.end[AB.node[qs[i]]]) -
                AB.s.query(AB.dfn[AB.node[qs[i]]] - 1);
      pl[i] = SB.Get(1, 1, SB.cnt, SB.dfn[SB.node[qs[i]]]);
    }
  for (int i : vy[x])
    if (from[qx[i]] != from[x] && From[qx[i]] == From[x]) {
      ans[i] += AA.s.query(AA.end[AA.node[qs[i]]]) -
                AA.s.query(AA.dfn[AA.node[qs[i]]] - 1);
      pr[i] = SA.Get(1, 1, SA.cnt, SA.dfn[SA.node[qs[i]]]);
    }
  for (int i = fir[x]; i; i = nxt[i]) {
    if (vis[dis[i]] || dis[i] == fa) continue;
    DFS2(dis[i], len + 1, x);
  }
  if (~fa) {
    if (tAA[x]) AA.s.update(AA.dfn[tAA[x]], -1);
    if (tSA[x]) SA.Pop(1, 1, SA.cnt, SA.dfn[tSA[x]], SA.end[tSA[x]]);
    if (tAB[x]) AB.s.update(AB.dfn[tAB[x]], -1);
    if (tSB[x]) SB.Pop(1, 1, SB.cnt, SB.dfn[tSB[x]], SB.end[tSB[x]]);
  }
}
void solve(int x) {
  vis[x] = 1;
  from[x] = 0, From[x] = x, tAA[x] = tAB[x] = 0, tSA[x] = tSB[x] = 1, DFS(x);
  DFS2(x, 0);
  for (int i = fir[x]; i; i = nxt[i])
    if (!vis[dis[i]]) N = siz[dis[i]], rt = 0, getrt(dis[i]), solve(rt);
}
std::vector<int> vd[100010], GA[100010];
int failA[100010], failB[100010], db[100010], eb[100010], L;
std::string str[100010];
char S[100010], SR[100010];
void getkmp(char* S, int* nxt, int n) {
  nxt[0] = nxt[1] = 0;
  for (int i = 2; i <= n; ++i) {
    int p = nxt[i - 1];
    while (p && S[i] != S[p + 1]) p = nxt[p];
    if (S[i] == S[p + 1]) ++p;
    nxt[i] = p;
  }
}
bit T;
void DFS3(int x) {
  if (x && x < L) T.update(db[L - x], 1), T.update(eb[L - x] + 1, -1);
  for (int i : vd[x]) ans[i] += T.query(db[pr[i]]);
  for (int i : GA[x]) DFS3(i);
  if (x && x < L) T.update(db[L - x], -1), T.update(eb[L - x] + 1, 1);
}
int main() {
  int n = gi(), m = gi(), q = gi(), a, b;
  char ch;
  for (int i = 1; i < n; ++i)
    a = gi(), b = gi(), ch = getchar() - 'a', link(a, b, ch), link(b, a, ch);
  for (int i = 1; i <= m; ++i) {
    std::cin >> str[i];
    int len = str[i].size();
    for (int j = 0; j < len; ++j)
      AA.extend(str[i][j] - 'a'), SA.extend(str[i][j] - 'a');
    for (int j = len - 1; ~j; --j)
      AB.extend(str[i][j] - 'a'), SB.extend(str[i][j] - 'a');
    AA.endt(i), SA.endt(i);
    AB.endt(i), SB.endt(i);
  }
  AA.build(), SA.build(), AB.build(), SB.build();
  for (int i = 1; i <= q; ++i)
    qx[i] = gi(), qy[i] = gi(), qs[i] = gi(), vx[qx[i]].push_back(i),
    vy[qy[i]].push_back(i);
  N = n, f[0] = 1e9, rt = 0, getrt(1), solve(rt);
  static std::vector<int> vc[100010];
  for (int i = 1; i <= q; ++i)
    if (pl[i] && pr[i]) vc[qs[i]].push_back(i);
  for (int i = 1; i <= m; ++i) {
    int len = str[i].size();
    L = len;
    for (int j = 1; j <= len; ++j) S[j] = SR[len - j + 1] = str[i][j - 1];
    for (int j = 0; j <= len; ++j) vd[j].clear(), GA[j].clear();
    getkmp(S, failA, len), getkmp(SR, failB, len);
    tree::build(0, L, failB, db, eb);
    for (int j = 1; j <= len; ++j) GA[failA[j]].push_back(j);
    for (int j : vc[i]) vd[pl[j]].push_back(j);
    T.N = L, DFS3(0);
  }
  for (int i = 1; i <= q; ++i) printf("%d\n", ans[i]);
  return 0;
}
