#include <bits/stdc++.h>
using namespace std;
const int N = 44444, mod2 = 998244353, mod1 = 1000000009;
vector<int> s[N], w[N], pl[N];
vector<int> A[N], B[N], S1[N], S2[N];
vector<pair<int, int> > S[N];
long long SUM = 0, len = 0;
int xl[N], dep[N], d[N], fir[N], pll[N][22];
int sz1[N], sz2[N];
int Len[N], W[N], deep[N], up[N][22], fa[N], powa[N], powb[N], inva[N], invb[N],
    hsh1_A[N], hsh1_B[N], hsh2_A[N], hsh2_B[N], Log[N], up2[N][20], Z[N],
    top[N];
int cntt, PL, sz[N], z[N], vis[N];
void jiantu(int x, int y, int l) {
  s[x].push_back(y), s[y].push_back(x);
  w[x].push_back(l), w[y].push_back(l);
  cntt++;
  pl[x].push_back(cntt), pl[y].push_back(cntt);
}
int ksm(int w, int x, int INF) {
  int ans = 1;
  while (x) {
    if (x & 1) ans = (long long)ans * w % INF;
    x >>= 1;
    w = (long long)w * w % INF;
  }
  return ans;
}
int lca(int x, int y) {
  if (!x || !y) return 0;
  int l, r, tmp;
  l = fir[x], r = fir[y];
  if (l > r) swap(l, r);
  if (l == r) return pll[l][0];
  tmp = Log[r - l + 1];
  if (up[l][tmp] < up[r - (1 << tmp) + 1][tmp]) return pll[l][tmp];
  return pll[r - (1 << tmp) + 1][tmp];
}
int get_hsh1(int x, int y) {
  return (long long)(hsh2_A[x] - hsh2_A[y] + mod1) * inva[deep[y]] % mod1;
}
int get_hsh2(int x, int y) {
  swap(x, y);
  return (hsh1_A[x] - (long long)hsh1_A[y] * powa[deep[x] - deep[y]] % mod1 +
          mod1) %
         mod1;
}
int get_dis(int x, int y) {
  int L = lca(x, y);
  return deep[x] - deep[L] + deep[y] - deep[L];
}
int get_hsh(int x, int y) {
  int L = lca(x, y);
  int tmp1, tmp2;
  tmp1 = get_hsh1(x, L);
  tmp2 = get_hsh2(L, y);
  return ((long long)tmp1 * powa[deep[y] - deep[L]] + tmp2) % mod1;
}
void dfs(int x) {
  int c, i, y;
  c = s[x].size();
  xl[++len] = x, fir[x] = len, dep[len] = deep[x];
  for (i = 0; i < c; i++) {
    y = s[x][i];
    if (fa[x] == y) continue;
    fa[y] = x, up[y][0] = x;
    deep[y] = deep[x] + 1;
    W[y] = w[x][i];
    hsh1_A[y] = ((long long)hsh1_A[x] * 233 % mod1 + w[x][i]) % mod1;
    hsh2_A[y] = ((long long)w[x][i] * powa[deep[y] - 1] + hsh2_A[x]) % mod1;
    dfs(y);
    xl[++len] = x, dep[len] = deep[x];
  }
}
int jump(int x, int w) {
  if (!x) return 0;
  if (w == 0) return x;
  int tmp = Log[w], D, pl;
  D = deep[x] - w;
  if (D < 0) return 0;
  pl = top[up2[x][tmp]];
  if (D < deep[pl]) return S2[pl][deep[pl] - D];
  return S1[pl][D - deep[pl]];
}
int go(int x, int y, int L, int w) {
  if (deep[x] - deep[L] >= w) return jump(x, w);
  return jump(y, deep[x] + deep[y] - deep[L] - deep[L] - w);
}
int check(int x, int y, int xx, int yy) {
  int pl1, pl2, pl3, pl4, w1, w2;
  int dis1 = get_dis(x, y), dis2 = get_dis(xx, yy);
  int l = 0, r = min(dis1, dis2);
  int L1 = lca(x, y), L2 = lca(xx, yy);
  while (l <= r) {
    int mid = l + r >> 1;
    pl1 = go(x, y, L1, mid), pl2 = go(xx, yy, L2, mid);
    if (get_hsh(x, pl1) == get_hsh(xx, pl2))
      l = mid + 1;
    else
      r = mid - 1;
  }
  if (r == dis1 && r == dis2) return 0;
  if (r == dis1) return -1;
  if (r == dis2) return 1;
  pl1 = go(x, y, L1, r), pl2 = go(xx, yy, L2, r);
  L1 = lca(pl1, y), L2 = lca(pl2, yy);
  pl3 = go(pl1, y, L1, 1), pl4 = go(pl2, yy, L2, 1);
  if (deep[pl1] > deep[pl3])
    w1 = W[pl1];
  else
    w1 = W[pl3];
  if (deep[pl2] > deep[pl4])
    w2 = W[pl2];
  else
    w2 = W[pl4];
  if (w1 < w2) return -1;
  if (w1 > w2) return 1;
  return 0;
}
bool cmp(int x, int y) {
  int w = check(PL, x, PL, y);
  if (w < 0) return 1;
  if (w > 0) return 0;
  return x < y;
}
void dfs1(int x) {
  int c, i, y, mx = 0;
  z[x] = 0, sz[x] = 1;
  c = s[x].size();
  for (i = 0; i < c; i++) {
    y = s[x][i];
    if (fa[x] == y || vis[y]) continue;
    fa[y] = x;
    dfs1(y);
    sz[x] += sz[y];
    if (sz[y] > mx) mx = sz[y], z[x] = y;
  }
  fa[x] = 0;
}
int find_zx(int x, int n) {
  while (sz[z[x]] > n / 2) x = z[x];
  return x;
}
void dfs2(int x, int rt) {
  int c, i, y;
  c = s[x].size();
  A[rt].push_back(x);
  for (i = 0; i < c; i++) {
    y = s[x][i];
    if (fa[x] == y || vis[y]) continue;
    fa[y] = x;
    dfs2(y, rt);
  }
  fa[x] = 0;
}
void dfs3(int x, int rt, int zx) {
  int c, i, y;
  sz2[rt]++;
  c = s[x].size();
  B[rt].push_back(x);
  for (i = 0; i < c; i++) {
    y = s[x][i];
    if (fa[x] == y || vis[y]) continue;
    fa[y] = x;
    dfs3(y, rt, zx);
  }
  S[x].push_back(make_pair(zx, rt));
  fa[x] = 0;
}
void dfz(int x) {
  int c, i, y, zx;
  dfs1(x);
  zx = find_zx(x, sz[x]);
  vis[zx] = 1;
  dfs2(zx, zx);
  sz1[zx] = sz[x];
  PL = zx;
  sort(A[zx].begin(), A[zx].end(), cmp);
  c = s[zx].size();
  for (i = 0; i < c; i++) {
    y = s[zx][i];
    if (vis[y]) continue;
    dfs3(y, pl[zx][i], zx);
    PL = zx;
    sort(B[pl[zx][i]].begin(), B[pl[zx][i]].end(), cmp);
    dfz(y);
  }
}
int solve(int rt, int xx, int yy) {
  int l, r;
  l = 0, r = A[rt].size() - 1;
  while (l <= r) {
    int mid = l + r >> 1;
    if (check(rt, A[rt][mid], xx, yy) < 0)
      l = mid + 1;
    else
      r = mid - 1;
  }
  return r + 1;
}
int solve2(int x, int rt, int xx, int yy) {
  int l, r;
  l = 0, r = B[rt].size() - 1;
  while (l <= r) {
    int mid = l + r >> 1;
    if (check(x, B[rt][mid], xx, yy) < 0)
      l = mid + 1;
    else
      r = mid - 1;
  }
  return r + 1;
}
int query(int x, int y) {
  int i, ans, dis1, dis2, pl1, pl2, pll, W;
  ans = 0;
  ans += solve(x, x, y);
  for (i = 0; i < S[x].size(); i++) {
    pl1 = S[x][i].first, pl2 = S[x][i].second;
    dis1 = get_dis(x, pl1), dis2 = get_dis(x, y);
    if (dis1 <= dis2) {
      int L = lca(x, y);
      pll = go(x, y, L, dis1);
    } else
      pll = y;
    W = check(x, pl1, x, pll);
    if (W < 0)
      ans = ans + sz1[pl1] - sz2[pl2];
    else if (W > 0)
      continue;
    else {
      ans = ans + solve(pl1, pll, y);
      ans = ans - solve2(pl1, pl2, pll, y);
    }
  }
  return ans;
}
void DFS(int x) {
  int c, i, y, mx = 0;
  c = s[x].size();
  for (i = 0; i < c; i++) {
    y = s[x][i];
    if (fa[x] == y) continue;
    fa[y] = x;
    DFS(y);
    Len[x] = max(Len[x], Len[y] + 1);
    if (Len[y] + 1 > mx) mx = Len[y] + 1, Z[x] = y;
  }
}
void DFS2(int x) {
  int c, i, y, sum = 0, tmp2, tmp;
  c = s[x].size();
  if (Z[fa[x]] == x)
    top[x] = top[fa[x]];
  else
    top[x] = x;
  if (Z[x]) sum++, DFS2(Z[x]);
  for (i = 0; i < c; i++) {
    y = s[x][i];
    if (fa[x] == y || Z[x] == y) continue;
    fa[y] = x;
    sum++;
    DFS2(y);
  }
  if (sum == 0) {
    tmp = top[x];
    S1[tmp].resize(deep[x] - deep[tmp] + 1);
    S2[tmp].resize(deep[x] - deep[tmp] + 1);
    tmp2 = x;
    while (1) {
      S1[tmp][deep[tmp2] - deep[tmp]] = tmp2;
      if (tmp2 == tmp) break;
      tmp2 = fa[tmp2];
    }
    tmp2 = tmp;
    for (i = 0; i <= deep[x] - deep[tmp]; i++) {
      S2[tmp][i] = tmp2;
      tmp2 = fa[tmp2];
    }
  }
}
int main() {
  char a[10];
  int n, q, inv233, inv133, i, j, x, y, ans;
  scanf("%d%d", &n, &q);
  for (i = 2; i <= n * 2; i++) Log[i] = Log[i >> 1] + 1;
  inv233 = ksm(233, mod1 - 2, mod1), inv133 = ksm(133, mod2 - 2, mod2);
  powa[0] = powb[0] = 1, inva[0] = invb[0] = 1;
  for (i = 1; i <= n; i++) {
    powa[i] = (long long)powa[i - 1] * 233 % mod1;
    inva[i] = (long long)inva[i - 1] * inv233 % mod1;
  }
  for (i = 1; i < n; i++) {
    scanf("%d%d", &x, &y);
    scanf("%s", a + 1);
    jiantu(x, y, a[1] - 'a' + 1);
  }
  dfs(1);
  for (i = 1; i <= n; i++) up2[i][0] = fa[i];
  for (j = 1; j <= 17; j++)
    for (i = 1; i <= n; i++) up2[i][j] = up2[up2[i][j - 1]][j - 1];
  DFS(1);
  DFS2(1);
  for (i = 1; i <= len; i++) up[i][0] = dep[i], pll[i][0] = xl[i];
  for (j = 1; j <= 17; j++)
    for (i = 1; i + (1 << j) - 1 <= len; i++)
      up[i][j] = min(up[i + (1 << j - 1)][j - 1], up[i][j - 1]),
      pll[i][j] = (up[i][j] == up[i][j - 1] ? pll[i][j - 1]
                                            : pll[i + (1 << j - 1)][j - 1]);
  dfz(1);
  for (i = 1; i <= q; i++) {
    scanf("%d%d", &x, &y);
    ans = query(x, y);
    if (x != y) ans--;
    printf("%d\n", ans);
  }
  return 0;
}
