#include <bits/stdc++.h>
#pragma GCC target("pclmul")
using ul = std::uint32_t;
using ull = std::uint64_t;
using li = std::int32_t;
using ll = std::int64_t;
using llf = long double;
using uss = std::uint8_t;
const ul maxn = 1e5;
const ul maxm = 1e5;
const ul maxlen = 1e5;
const ul maxq = 1e5;
ul n, m, q;
std::vector<std::pair<ul, ul>> edges[maxn + 1];
char s[maxlen + 2];
class sam_t {
 public:
  ul las;
  class node {
   public:
    ul ch[26];
    ul len = 0;
    ul fa = 0;
    node() { std::memset(ch, 0, sizeof(ch)); }
  };
  std::vector<node> st = std::vector<node>(maxlen + maxlen + 1);
  ul sons[maxlen + maxlen + 1][26];
  ul dfn[maxlen + maxlen + 1];
  ul bdfn[maxlen + maxlen + 1];
  ul tim = 0;
  void search(ul curr) {
    ++tim;
    dfn[curr] = tim;
    for (ul c = 0; c <= 25; ++c) {
      ul next = sons[curr][c];
      if (next) {
        search(next);
      }
    }
    bdfn[curr] = tim;
  }
  void add(ul c) {
    ul p = las;
    ul np = las = st.size();
    st.push_back(node());
    st[np].len = st[p].len + 1;
    for (; p && !st[p].ch[c]; p = st[p].fa) {
      st[p].ch[c] = np;
    }
    if (!p) {
      st[np].fa = 1;
    } else {
      ul q = st[p].ch[c];
      if (st[q].len == st[p].len + 1) {
        st[np].fa = q;
      } else {
        ul nq = st.size();
        st.push_back(node());
        st[nq] = st[q];
        st[nq].len = st[p].len + 1;
        st[q].fa = st[np].fa = nq;
        for (; p && st[p].ch[c] == q; p = st[p].fa) {
          st[p].ch[c] = nq;
        }
      }
    }
  }
  void init() {
    las = 1;
    st.resize(0);
    st.resize(2);
  }
};
class acam_sam_t {
 public:
  std::string str[maxm + 1];
  std::deque<ul> queue;
  ul sz;
  ul las;
  ul acam[maxlen + 2][26];
  ul fail[maxlen + 2];
  std::vector<ul> strtoacam[maxm + 1];
  std::pair<ul, ul> acamtostr[maxlen + 2];
  sam_t sam;
  ul samtoacam[maxlen + maxlen + 1];
  ul acamtosam[maxlen + 2];
  ul ord[maxlen + maxlen + 1];
  std::vector<ul> sons[maxlen + 2];
  ul dfn[maxlen + 2];
  ul bdfn[maxlen + 2];
  ul tim = 0;
  void init() {
    sam.init();
    sz = 1;
    las = 1;
  }
  void add(ul c) {
    if (!acam[las][c]) {
      ++sz;
      acam[las][c] = sz;
    }
    las = acam[las][c];
  }
  void add(char s[], ul it) {
    s[0] = '0';
    str[it] = s;
    strtoacam[it].resize(str[it].size());
    las = 1;
    for (ul i = 1; i != str[it].size(); ++i) {
      add(str[it][i] - 'a');
      strtoacam[it][i] = las;
      acamtostr[las] = std::pair<ul, ul>(it, i);
    }
  }
  void buildacam() {
    for (ul c = 0; c <= 25; ++c) {
      if (acam[1][c]) {
        fail[acam[1][c]] = 1;
        queue.push_back(acam[1][c]);
      } else {
        acam[1][c] = 1;
      }
    }
    while (queue.size()) {
      ul curr = queue.front();
      queue.pop_front();
      sons[fail[curr]].push_back(curr);
      for (ul c = 0; c <= 25; ++c) {
        if (acam[curr][c]) {
          fail[acam[curr][c]] = acam[fail[curr]][c];
          queue.push_back(acam[curr][c]);
        } else {
          acam[curr][c] = acam[fail[curr]][c];
        }
      }
    }
  }
  void buildsam() {
    queue.push_back(1);
    acamtosam[1] = 1;
    samtoacam[1] = 1;
    while (queue.size()) {
      ul curr = queue.front();
      queue.pop_front();
      ul scurr = acamtosam[curr];
      for (ul c = 0; c <= 25; ++c) {
        if (acam[curr][c]) {
          ul next = acam[curr][c];
          sam.las = scurr;
          sam.add(c);
          acamtosam[next] = sam.las;
          samtoacam[sam.las] = next;
          queue.push_back(next);
        }
      }
    }
    for (ul i = 1; i != sam.st.size(); ++i) {
      ord[i] = i;
    }
    std::sort(ord + 1, ord + sam.st.size(),
              [&](ul a, ul b) { return sam.st[a].len < sam.st[b].len; });
    for (ul it = sam.st.size() - 1; it >= 2; --it) {
      ul i = ord[it];
      if (!samtoacam[sam.st[i].fa]) {
        samtoacam[sam.st[i].fa] = samtoacam[i];
      }
      const auto& p = acamtostr[samtoacam[i]];
      sam.sons[sam.st[i].fa]
              [str[p.first][p.second - sam.st[sam.st[i].fa].len] - 'a'] = i;
    }
  }
  void search(ul curr) {
    ++tim;
    dfn[curr] = tim;
    for (ul next : sons[curr]) {
      search(next);
    }
    bdfn[curr] = tim;
  }
  void onestep(std::pair<ul, ul>& curr, ul c) {
    if (!~curr.second) {
      return;
    }
    if (sam.st[curr.first].len != curr.second) {
      const auto& p = acamtostr[samtoacam[curr.first]];
      if (c != str[p.first][p.second - curr.second]) {
        curr.first = sam.st[curr.first].fa;
        curr.second = ~ul(0);
      } else {
        ++curr.second;
      }
    } else {
      ul q = sam.sons[curr.first][c - 'a'];
      if (q) {
        curr.first = q;
        ++curr.second;
      } else {
        curr.second = ~ul(0);
      }
    }
  }
};
acam_sam_t ltr;
acam_sam_t rtl;
ul rk[maxn + 1];
ul getsz(ul curr, ul prev) {
  ul ret = 1;
  for (const auto& e : edges[curr]) {
    ul next = e.first;
    if (rk[next] || next == prev) {
      continue;
    }
    ret += getsz(next, curr);
  }
  return ret;
}
ul getcen(ul curr, ul prev, ul& mnmxsz, ul& cen, ul& sz, ul all) {
  ul ret = 0;
  sz = 1;
  ul mxsz = 0;
  for (const auto& e : edges[curr]) {
    ul next = e.first;
    if (rk[next]) {
      if (!ret || rk[next] < rk[ret]) {
        ret = next;
      }
      continue;
    }
    if (next == prev) {
      continue;
    }
    ul nsz;
    ul tmp = getcen(next, curr, mnmxsz, cen, nsz, all);
    if (ret == 0 || tmp != 0 && rk[tmp] < rk[ret]) {
      ret = tmp;
    }
    sz += nsz;
    mxsz = std::max(mxsz, nsz);
  }
  mxsz = std::max(mxsz, all - sz);
  if (mnmxsz > mxsz) {
    mnmxsz = mxsz;
    cen = curr;
  }
  return ret;
}
ul cfa[maxn + 1];
ul treetim;
class node {
 public:
  ul lc = 0;
  ul rc = 0;
  ul sum = 0;
};
node tree[maxn * 18 * 2 + maxlen * 4 * 19 + 1];
void change(ul pos, ul nl, ul nr, ul& nid, ul v = 1) {
  ++treetim;
  tree[treetim] = tree[nid];
  nid = treetim;
  tree[nid].sum += v;
  if (nl == nr) {
    return;
  }
  ul midl = nl + nr >> 1;
  ul midr = midl + 1;
  if (pos <= midl) {
    change(pos, nl, midl, tree[nid].lc, v);
  } else {
    change(pos, midr, nr, tree[nid].rc, v);
  }
}
ul query(ul l, ul r, ul nl, ul nr, ul nid) {
  if (l <= nl && r >= nr) {
    return tree[nid].sum;
  }
  ul ret = 0;
  ul midl = nl + nr >> 1;
  ul midr = midl + 1;
  if (l <= midl && tree[nid].lc) {
    ret += query(l, r, nl, midl, tree[nid].lc);
  }
  if (r >= midr && tree[nid].rc) {
    ret += query(l, r, midr, nr, tree[nid].rc);
  }
  return ret;
}
std::deque<ul> queue;
ul al[maxn + 1];
ul ltrroot[maxn + 1];
ul rtlroot[maxn + 1];
ul ltrstate[maxn + 1];
ul rtlstate[maxn + 1];
std::pair<ul, ul> ltrsamstate[maxn + 1];
std::pair<ul, ul> rtlsamstate[maxn + 1];
std::vector<std::pair<ul, ul>> root[maxm + 1];
std::vector<std::pair<std::pair<ul, ul>, ul>> vvv;
ul lca(ul x, ul y) {
  while (x != y) {
    if (rk[x] > rk[y]) {
      y = cfa[y];
    } else {
      x = cfa[x];
    }
  }
  return x;
}
ul xs[maxq + 1];
ul ys[maxq + 1];
ul ks[maxq + 1];
ul anss[maxq + 1];
std::vector<ul> qid[maxn + 1];
int main() {
  std::scanf("%u%u%u", &n, &m, &q);
  for (ul i = 1; i <= n - 1; ++i) {
    ul u, v;
    std::scanf("%u%u%s", &u, &v, s + 1);
    edges[u].push_back(std::pair<ul, ul>(v, s[1]));
    edges[v].push_back(std::pair<ul, ul>(u, s[1]));
  }
  ltr.init();
  rtl.init();
  for (ul it = 1; it <= m; ++it) {
    std::scanf("%s", s + 1);
    ltr.add(s, it);
    std::reverse(s + 1, s + std::strlen(s + 1) + 1);
    rtl.add(s, it);
  }
  ltr.buildsam();
  rtl.buildsam();
  ltr.buildacam();
  rtl.buildacam();
  ltr.search(1);
  rtl.search(1);
  ltr.sam.search(1);
  rtl.sam.search(1);
  for (ul it = 1; it <= m; ++it) {
    vvv.resize(0);
    vvv.resize(1);
    for (ul l = 1, r = ltr.str[it].size() - 2; r >= 1; ++l, --r) {
      ul lr = ltr.acamtosam[ltr.strtoacam[it][l]];
      ul rl = rtl.acamtosam[rtl.strtoacam[it][r]];
      vvv.push_back(std::pair<std::pair<ul, ul>, ul>(
          std::pair<ul, ul>(ltr.sam.dfn[lr], rtl.sam.dfn[rl]), 1));
      if (rtl.sam.bdfn[rl] != rtl.sam.st.size() - 1) {
        vvv.push_back(std::pair<std::pair<ul, ul>, ul>(
            std::pair<ul, ul>(ltr.sam.dfn[lr], rtl.sam.bdfn[rl] + 1), -1));
      }
      if (ltr.sam.bdfn[lr] != ltr.sam.st.size() - 1) {
        vvv.push_back(std::pair<std::pair<ul, ul>, ul>(
            std::pair<ul, ul>(ltr.sam.bdfn[lr] + 1, rtl.sam.dfn[rl]), -1));
      }
      if (rtl.sam.bdfn[rl] != rtl.sam.st.size() - 1 &&
          ltr.sam.bdfn[lr] != ltr.sam.st.size() - 1) {
        vvv.push_back(std::pair<std::pair<ul, ul>, ul>(
            std::pair<ul, ul>(ltr.sam.bdfn[lr] + 1, rtl.sam.bdfn[rl] + 1), 1));
      }
    }
    std::sort(vvv.begin(), vvv.end());
    root[it].resize(vvv.size());
    for (ul i = 1; i != vvv.size(); ++i) {
      root[it][i].second = root[it][i - 1].second;
      root[it][i].first = vvv[i].first.first;
      change(vvv[i].first.second, 1, rtl.sam.st.size() - 1, root[it][i].second,
             vvv[i].second);
    }
  }
  for (ul i = 1; i <= n; ++i) {
    while (!rk[i]) {
      ul all = getsz(i, 0);
      ul cen;
      ul mnmxsz = 1e9;
      ul sz;
      ul tmp = getcen(i, 0, mnmxsz, cen, sz, all);
      rk[cen] = all;
      cfa[cen] = tmp;
    }
  }
  ul sptreetim = treetim;
  for (ul Case = 1; Case <= q; ++Case) {
    std::scanf("%u%u%u", &xs[Case], &ys[Case], &ks[Case]);
    qid[lca(xs[Case], ys[Case])].push_back(Case);
  }
  for (ul c = 1; c <= n; ++c) {
    if (qid[c].empty()) {
      continue;
    }
    treetim = sptreetim;
    queue.push_back(c);
    al[c] = c;
    ltrstate[c] = 1;
    rtlstate[c] = 1;
    ltrsamstate[c] = std::pair<ul, ul>(1, 0);
    rtlsamstate[c] = std::pair<ul, ul>(1, 0);
    ltrroot[c] = 0;
    rtlroot[c] = 0;
    while (queue.size()) {
      ul curr = queue.front();
      queue.pop_front();
      for (const auto& e : edges[curr]) {
        ul next = e.first;
        if (rk[next] > rk[c] || al[next] == c) {
          continue;
        }
        al[next] = c;
        queue.push_back(next);
        ltrstate[next] = ltr.acam[ltrstate[curr]][e.second - 'a'];
        ltrroot[next] = ltrroot[curr];
        change(ltr.dfn[ltrstate[next]], 1, ltr.sz, ltrroot[next]);
        rtlstate[next] = rtl.acam[rtlstate[curr]][e.second - 'a'];
        rtlroot[next] = rtlroot[curr];
        change(rtl.dfn[rtlstate[next]], 1, rtl.sz, rtlroot[next]);
        ltrsamstate[next] = ltrsamstate[curr];
        ltr.onestep(ltrsamstate[next], e.second);
        rtlsamstate[next] = rtlsamstate[curr];
        rtl.onestep(rtlsamstate[next], e.second);
      }
    }
    for (ul t : qid[c]) {
      ul x = xs[t];
      ul y = ys[t];
      ul k = ks[t];
      ul ans = 0;
      ans += query(ltr.dfn[ltr.strtoacam[k][ltr.str[k].size() - 1]],
                   ltr.bdfn[ltr.strtoacam[k][ltr.str[k].size() - 1]], 1, ltr.sz,
                   ltrroot[y]);
      ans += query(rtl.dfn[rtl.strtoacam[k][rtl.str[k].size() - 1]],
                   rtl.bdfn[rtl.strtoacam[k][rtl.str[k].size() - 1]], 1, rtl.sz,
                   rtlroot[x]);
      ul lrx =
          ltr.sam
              .dfn[ltrsamstate[x].second >= ltr.sam.st[ltrsamstate[x].first].len
                       ? ltrsamstate[x].first
                       : ltr.sam.st[ltrsamstate[x].first].fa];
      ul rly =
          rtl.sam
              .dfn[rtlsamstate[y].second >= rtl.sam.st[rtlsamstate[y].first].len
                       ? rtlsamstate[y].first
                       : rtl.sam.st[rtlsamstate[y].first].fa];
      ans += query(1, rly, 1, rtl.sam.st.size() - 1,
                   std::prev(std::upper_bound(root[k].begin(), root[k].end(),
                                              std::pair<ul, ul>(lrx, 1e9)))
                       ->second);
      anss[t] = ans;
    }
  }
  for (ul Case = 1; Case <= q; ++Case) {
    std::printf("%u\n", anss[Case]);
  }
  return 0;
}
