#include <bits/stdc++.h>
using namespace std;
const int RLEN = 1 << 18 | 1;
inline char nc() { return getchar(); }
inline int rd() {
  char ch = nc();
  int i = 0, f = 1;
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    ch = nc();
  }
  while (isdigit(ch)) {
    i = (i << 1) + (i << 3) + ch - '0';
    ch = nc();
  }
  return i * f;
}
inline void W(int x) {
  static int buf[50];
  if (!x) {
    putchar('0');
    return;
  }
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  while (x) {
    buf[++buf[0]] = x % 10;
    x /= 10;
  }
  while (buf[0]) {
    putchar(buf[buf[0]--] + '0');
  }
}
const int mod1 = 998244353, mod2 = 1e9 + 7, L = 19;
inline int add(int x, int y, int mod) {
  return (x + y >= mod) ? (x + y - mod) : (x + y);
}
inline int dec(int x, int y, int mod) {
  return (x - y < 0) ? (x - y + mod) : (x - y);
}
inline int mul(int x, int y, int mod) { return (long long)x * y % mod; }
inline int power(int a, int b, int mod, int rs = 1) {
  for (; b; b >>= 1, a = mul(a, a, mod))
    if (b & 1) rs = mul(rs, a, mod);
  return rs;
}
inline pair<int, int> operator+(const pair<int, int> &a,
                                const pair<int, int> &b) {
  return pair<int, int>(add(a.first, b.first, mod1),
                        add(a.second, b.second, mod2));
}
inline pair<int, int> operator-(const pair<int, int> &a,
                                const pair<int, int> &b) {
  return pair<int, int>(dec(a.first, b.first, mod1),
                        dec(a.second, b.second, mod2));
}
inline pair<int, int> operator*(const pair<int, int> &a,
                                const pair<int, int> &b) {
  return pair<int, int>(mul(a.first, b.first, mod1),
                        mul(a.second, b.second, mod2));
}
inline bool operator==(const pair<int, int> &a, const pair<int, int> &b) {
  return a.first == b.first && a.second == b.second;
}
const pair<int, int> base(31, 61),
    ibase(power(31, mod1 - 2, mod1), power(61, mod2 - 2, mod2));
const int N = 1e5 + 50;
int n, m, q, len[N], ans[N], cnt[N];
string ori_s[N], rev_s[N];
struct query {
  int u, id, v;
  query(int u = 0, int id = 0, int v = 0) : u(u), id(id), v(v) {}
} tq[N];
struct ac_auto {
  vector<int> edge[N];
  queue<int> q;
  int pos[N], dfn[N], sze[N], fail[N], son[N][27], tot = 1, ind;
  inline void dfs(int x) {
    sze[x] = 1;
    dfn[x] = ++ind;
    for (auto v : edge[x]) dfs(v), sze[x] += sze[v];
  }
  inline void init(string *s) {
    for (int j = 1; j <= 26; j++) son[0][j] = 1;
    for (int i = 1; i <= m; i++) {
      int p = 1;
      for (int j = 1; j <= len[i]; j++) {
        int c = s[i][j] - 'a' + 1;
        if (!son[p][c]) son[p][c] = ++tot;
        p = son[p][c];
      }
      pos[i] = p;
    }
    q.push(1);
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      for (int j = 1; j <= 26; j++) {
        int w = son[u][j], v = fail[u];
        while (!son[v][j]) v = fail[v];
        if (w)
          fail[w] = son[v][j], q.push(w);
        else
          son[u][j] = son[v][j];
      }
    }
    for (int i = 2; i <= tot; i++) edge[fail[i]].push_back(i);
    dfs(1);
  }
} ori_a, rev_a;
struct _tree {
  vector<pair<int, int> > edge[N];
  vector<query> qry[N];
  int fa[N][L], dep[N], num[N];
  int bit1[N], bit2[N];
  pair<int, int> d[N], pw[N], ipw[N];
  inline pair<int, int> gd(int x, int f) { return (d[x] - d[f]) * ipw[dep[f]]; }
  inline void inc(int *bit, int i, int v, int lim) {
    for (; i <= lim; i += (i & (-i))) bit[i] += v;
  }
  inline int ask(int *bit, int i, int lim, int v = 0) {
    for (; i; i -= (i & (-i))) v += bit[i];
    return v;
  }
  inline int up(int x, int d) {
    for (int i = L - 1; ~i; i--)
      if (d & (1 << i)) x = fa[x][i];
    return x;
  }
  inline int lca(int x, int y) {
    if (dep[x] < dep[y]) swap(x, y);
    if (dep[x] > dep[y]) x = up(x, dep[x] - dep[y]);
    if (x == y) return x;
    for (int i = L - 1; ~i; i--)
      if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
    return fa[x][0];
  }
  inline void dfs(int x, int f, int c) {
    fa[x][0] = f;
    dep[x] = dep[f] + 1;
    num[x] = c;
    for (int i = 1; i < L; i++) fa[x][i] = fa[fa[x][i - 1]][i - 1];
    d[x] = d[f] + pair<int, int>(c, c) * pw[dep[x]];
    for (auto v : edge[x]) {
      if (v.first == f) continue;
      dfs(v.first, x, v.second);
    }
  }
  inline void init() {
    pw[0] = ipw[0] = pair<int, int>(1, 1);
    for (int i = 1; i <= n; i++)
      pw[i] = pw[i - 1] * base, ipw[i] = ipw[i - 1] * ibase;
    for (int i = 1; i < n; i++) {
      int x = rd(), y = rd(), c = nc() - 'a' + 1;
      edge[x].push_back(make_pair(y, c));
      edge[y].push_back(make_pair(x, c));
    }
    dfs(1, 0, 1);
  }
  inline void init_ans(int x, int f, int c, int p1, int p2) {
    p1 = ori_a.son[p1][c], p2 = rev_a.son[p2][c];
    inc(bit1, ori_a.dfn[p1], 1, ori_a.tot);
    inc(bit2, rev_a.dfn[p2], 1, rev_a.tot);
    for (auto v : qry[x]) {
      int rs = 0;
      if (abs(v.u) == 1) {
        rs =
            ask(bit1, ori_a.dfn[ori_a.pos[v.v]] + ori_a.sze[ori_a.pos[v.v]] - 1,
                ori_a.tot) -
            ask(bit1, ori_a.dfn[ori_a.pos[v.v]] - 1, ori_a.tot);
      } else {
        rs =
            ask(bit2, rev_a.dfn[rev_a.pos[v.v]] + rev_a.sze[rev_a.pos[v.v]] - 1,
                rev_a.tot) -
            ask(bit2, rev_a.dfn[rev_a.pos[v.v]] - 1, rev_a.tot);
      }
      ans[v.id] += ((v.u > 0) ? 1 : -1) * rs;
    }
    for (auto v : edge[x]) {
      if (v.first == f) continue;
      init_ans(v.first, x, v.second, p1, p2);
    }
    inc(bit1, ori_a.dfn[p1], -1, ori_a.tot);
    inc(bit2, rev_a.dfn[p2], -1, rev_a.tot);
  }
} tr;
struct kmp {
  int nn, **fail, *diff, *slink;
  inline void init(string &s, int id) {
    nn = len[id];
    fail = new int *[nn + 5]();
    for (int i = 0; i <= nn; i++) fail[i] = new int[L]();
    diff = new int[nn + 5]();
    slink = new int[nn + 5]();
    diff[1] = 1;
    for (int i = 2, j = 0; i <= nn; ++i) {
      while (j && s[i] != s[j + 1]) j = fail[j][0];
      if (s[i] == s[j + 1]) ++j;
      fail[i][0] = j;
      diff[i] = i - j;
      for (int j = 1; j < L; j++) fail[i][j] = fail[fail[i][j - 1]][j - 1];
      slink[i] = (diff[i] == diff[j]) ? slink[j] : j;
    }
  }
} ori_k[N], rev_k[N];
struct sa {
  int nn, m, *a, *sa, *sa2, *rk;
  pair<int, int> *hv;
  inline pair<int, int> gv(int l, int r) {
    return (hv[r] - hv[l - 1]) * tr.ipw[l - 1];
  }
  inline void Rsort() {
    for (int i = 1; i <= m; ++i) cnt[i] = 0;
    for (int i = 1; i <= nn; ++i) ++cnt[rk[i]];
    for (int i = 1; i <= m; i++) cnt[i] += cnt[i - 1];
    for (int i = nn; i >= 1; i--) sa[cnt[rk[sa2[i]]]--] = sa2[i];
  }
  inline void init(string &s, int id) {
    nn = len[id];
    a = new int[nn * 2 + 5]();
    sa = new int[nn * 2 + 5]();
    sa2 = new int[nn * 2 + 5]();
    rk = new int[nn * 2 + 5]();
    hv = new pair<int, int>[nn * 2 + 5]();
    for (int i = 1; i <= nn; i++) {
      a[i] = s[i] - 'a' + 1;
      hv[i] = hv[i - 1] + pair<int, int>(a[i], a[i]) * tr.pw[i];
    }
    for (int i = 1; i <= nn; i++) sa2[i] = i, rk[i] = a[i];
    m = 26;
    Rsort();
    for (int w = 1, p = 0;; w <<= 1) {
      for (int i = nn - w + 1; i <= nn; i++) sa2[++p] = i;
      for (int i = 1; i <= nn; i++)
        if (sa[i] > w) sa2[++p] = sa[i] - w;
      Rsort();
      swap(rk, sa2);
      rk[sa[1]] = p = 1;
      for (int i = 2; i <= nn; i++)
        rk[sa[i]] = (sa2[sa[i]] == sa2[sa[i - 1]] &&
                     sa2[sa[i] + w] == sa2[sa[i - 1] + w])
                        ? p
                        : ++p;
      if (p == nn) break;
      m = p;
      p = 0;
    }
  }
  inline int lcp(int mid, int u, int lca) {
    if (u == lca) return 0;
    int x = u, len = nn - sa[mid] + 1;
    mid = sa[mid];
    for (int i = L - 1; ~i; i--)
      if (tr.dep[x] - tr.dep[lca] > (1 << i)) {
        if ((len < tr.dep[x] - tr.dep[lca] - (1 << i)) ||
            (tr.gd(tr.fa[x][i], lca) !=
             gv(mid, mid + tr.dep[x] - tr.dep[lca] - (1 << i) - 1)))
          x = tr.fa[x][i];
      }
    int p1 = mid + tr.dep[x] - tr.dep[lca] - 1;
    return tr.dep[x] - tr.dep[lca] - (p1 > nn || tr.num[x] != a[p1]);
  }
  inline bool check(int mid, int u, int lca) {
    int len = lcp(mid, u, lca);
    if (len == nn) return false;
    if (len == nn - sa[mid] + 1) return true;
    if (len == tr.dep[u] - tr.dep[lca]) return false;
    return a[sa[mid] + len] <
           tr.num[tr.up(u, tr.dep[u] - tr.dep[lca] - len - 1)];
  }
  inline int find(int u, int lca, kmp &rev_kmp) {
    int l = 1, r = nn, ans = 0;
    while (l <= r) {
      int mid = (l + r) >> 1;
      if (check(mid, u, lca))
        ans = mid, l = mid + 1;
      else
        r = mid - 1;
    }
    if (!ans) return 0;
    int len = lcp(ans, u, lca);
    if (len == nn - sa[ans] + 1) return nn - sa[ans] + 1;
    ans = sa[ans];
    for (int i = L - 1; ~i; i--)
      if (rev_kmp.fail[nn - ans + 1][i] > len)
        ans = nn - rev_kmp.fail[nn - ans + 1][i] + 1;
    ans = nn - rev_kmp.fail[nn - ans + 1][0] + 1;
    return nn - ans + 1;
  }
} ori_sa[N], rev_sa[N];
long long xl, yl;
inline long long gcd(long long x, long long y) { return y ? gcd(y, x % y) : x; }
inline void exgcd(long long a, long long b, long long &x, long long &y) {
  b ? (exgcd(b, a % b, y, x), y -= a / b * x) : (x = 1, y = 0);
}
inline void fix(long long &a, long long b, long long c) {
  if (a < b) {
    long long t = (b - a) / c;
    a += t * c;
  }
  if (a > b) {
    long long t = (a - b) / c;
    a -= t * c;
  }
  while (a > b) a -= c;
  while (a < b) a += c;
}
inline int common(int l1, int r1, int d1, int l2, int r2, int d2) {
  if (l1 > l2) swap(l1, l2), swap(r1, r2), swap(d1, d2);
  if (l2 > r1) return 0;
  int D = l2 - l1, g = gcd(d1, d2);
  if (D % g) return 0;
  D /= g;
  int k1 = d1 / g, k2 = d2 / g;
  exgcd(k1, k2, xl, yl);
  xl *= D;
  yl *= D;
  long long r = xl * d1 + l1;
  fix(r, l2, d1 * d2 / g);
  if (r > r1 || r > r2) return false;
  return (min(r1, r2) - r) / (d1 * d2 / g) + 1;
}
int main() {
  n = rd(), m = rd(), q = rd();
  tr.init();
  for (int i = 1; i <= m; i++) {
    static char ch[N];
    scanf("%s", ch + 1);
    len[i] = strlen(ch + 1);
    ori_s[i] += ' ';
    rev_s[i] += ' ';
    for (int j = 1; j <= len[i]; j++) ori_s[i] += ch[j];
    for (int j = len[i]; j; j--) rev_s[i] += ch[j];
  }
  ori_a.init(ori_s);
  rev_a.init(rev_s);
  for (int i = 1; i <= q; i++) {
    int u = rd(), v = rd(), p = rd();
    int f = tr.lca(u, v);
    tq[i] = query(u, p, v);
    if (tr.dep[u] - tr.dep[f] >= len[p]) {
      tr.qry[u].push_back(query(2, i, p));
      tr.qry[tr.up(u, tr.dep[u] - tr.dep[f] - len[p] + 1)].push_back(
          query(-2, i, p));
    }
    if (tr.dep[v] - tr.dep[f] >= len[p]) {
      tr.qry[v].push_back(query(1, i, p));
      tr.qry[tr.up(v, tr.dep[v] - tr.dep[f] - len[p] + 1)].push_back(
          query(-1, i, p));
    }
  }
  tr.init_ans(1, 0, 1, 0, 0);
  for (int i = 1; i <= m; i++)
    ori_sa[i].init(ori_s[i], i), rev_sa[i].init(rev_s[i], i),
        ori_k[i].init(ori_s[i], i), rev_k[i].init(rev_s[i], i);
  for (int i = 1; i <= q; i++) {
    int u = tq[i].u, v = tq[i].v, p = tq[i].id;
    int f = tr.lca(u, v);
    int fL = rev_sa[p].find(u, f, ori_k[p]);
    int fR = ori_sa[p].find(v, f, rev_k[p]);
    for (int j = fL; j; j = ori_k[p].slink[j])
      for (int k = fR; k; k = rev_k[p].slink[k]) {
        int l1 = ori_k[p].slink[j] + ori_k[p].diff[j], r1 = j,
            l2 = rev_k[p].slink[k] + rev_k[p].diff[k], r2 = k;
        if (!l1) l1 += ori_k[p].diff[j];
        if (!l2) l2 += rev_k[p].diff[k];
        ans[i] += common(l1, r1, ori_k[p].diff[j], len[p] - r2, len[p] - l2,
                         rev_k[p].diff[k]);
      }
  }
  for (int i = 1; i <= q; i++) W(ans[i]), putchar('\n');
}
