← Home
package main

import (
	"bufio"
	"io"
	"os"
	"strconv"
)

const (
	B1 uint64 = 911382323
	B2 uint64 = 972663749
)

type H struct {
	a uint64
	b uint64
}

type FastScanner struct {
	data []byte
	idx  int
}

func NewFastScanner() *FastScanner {
	data, _ := io.ReadAll(os.Stdin)
	return &FastScanner{data: data}
}

func (fs *FastScanner) skip() {
	for fs.idx < len(fs.data) && fs.data[fs.idx] <= ' ' {
		fs.idx++
	}
}

func (fs *FastScanner) Int() int {
	fs.skip()
	x := 0
	for fs.idx < len(fs.data) {
		c := fs.data[fs.idx]
		if c < '0' || c > '9' {
			break
		}
		x = x*10 + int(c-'0')
		fs.idx++
	}
	return x
}

func (fs *FastScanner) Bytes() []byte {
	fs.skip()
	start := fs.idx
	for fs.idx < len(fs.data) && fs.data[fs.idx] > ' ' {
		fs.idx++
	}
	return fs.data[start:fs.idx]
}

var (
	n        int
	logN     int
	head     []int
	to       []int
	nxt      []int
	lab      []byte
	edgeCnt  int
	up       [][]int
	depth    []int
	parLabel []byte
	pow1     [101]uint64
	pow2     [101]uint64
	patMaps  []map[H]int
	currCnt  []int
)

func addEdge(u, v int, c byte) {
	to[edgeCnt] = v
	lab[edgeCnt] = c
	nxt[edgeCnt] = head[u]
	head[u] = edgeCnt
	edgeCnt++
}

func kthAncestor(v, k int) int {
	i := 0
	for k > 0 {
		if k&1 == 1 {
			v = up[i][v]
		}
		k >>= 1
		i++
	}
	return v
}

func lca(u, v int) int {
	if depth[u] < depth[v] {
		u, v = v, u
	}
	diff := depth[u] - depth[v]
	i := 0
	for diff > 0 {
		if diff&1 == 1 {
			u = up[i][u]
		}
		diff >>= 1
		i++
	}
	if u == v {
		return u
	}
	for i = logN - 1; i >= 0; i-- {
		if up[i][u] != up[i][v] {
			u = up[i][u]
			v = up[i][v]
		}
	}
	return up[0][u]
}

func hashBytes(b []byte) H {
	var x, y uint64
	for _, c := range b {
		v := uint64(c-'a') + 1
		x = x*B1 + v
		y = y*B2 + v
	}
	return H{x, y}
}

func hashBytesRev(b []byte) H {
	var x, y uint64
	for i := len(b) - 1; i >= 0; i-- {
		v := uint64(b[i]-'a') + 1
		x = x*B1 + v
		y = y*B2 + v
	}
	return H{x, y}
}

func getPID(m int, h H) int {
	if patMaps[m] == nil {
		patMaps[m] = make(map[H]int)
	}
	if id, ok := patMaps[m][h]; ok {
		return id
	}
	id := len(currCnt)
	patMaps[m][h] = id
	currCnt = append(currCnt, 0)
	return id
}

func countCross(u, v, a int, s []byte) int {
	m := len(s)
	if m <= 1 {
		return 0
	}
	lenU := depth[u] - depth[a]
	lenD := depth[v] - depth[a]
	if lenU == 0 || lenD == 0 {
		return 0
	}
	l1 := lenU
	if l1 > m-1 {
		l1 = m - 1
	}
	l2 := lenD
	if l2 > m-1 {
		l2 = m - 1
	}
	if l1+l2 < m {
		return 0
	}

	parent := up[0]
	var t [200]byte

	x := kthAncestor(u, lenU-l1)
	for i := 0; i < l1; i++ {
		t[i] = parLabel[x]
		x = parent[x]
	}

	x = kthAncestor(v, lenD-l2)
	for i := l2 - 1; i >= 0; i-- {
		t[l1+i] = parLabel[x]
		x = parent[x]
	}

	var pi [101]int
	for i := 1; i < m; i++ {
		j := pi[i-1]
		for j > 0 && s[i] != s[j] {
			j = pi[j-1]
		}
		if s[i] == s[j] {
			j++
		}
		pi[i] = j
	}

	tLen := l1 + l2
	j := 0
	cnt := 0
	for i := 0; i < tLen; i++ {
		c := t[i]
		for j > 0 && c != s[j] {
			j = pi[j-1]
		}
		if c == s[j] {
			j++
		}
		if j == m {
			start := i - m + 1
			if start < l1 && i >= l1 {
				cnt++
			}
			j = pi[j-1]
		}
	}
	return cnt
}

func main() {
	fs := NewFastScanner()

	pow1[0] = 1
	pow2[0] = 1
	for i := 1; i <= 100; i++ {
		pow1[i] = pow1[i-1] * B1
		pow2[i] = pow2[i-1] * B2
	}

	n = fs.Int()
	head = make([]int, n+1)
	for i := 1; i <= n; i++ {
		head[i] = -1
	}
	to = make([]int, 2*(n-1))
	nxt = make([]int, 2*(n-1))
	lab = make([]byte, 2*(n-1))

	for i := 0; i < n-1; i++ {
		u := fs.Int()
		v := fs.Int()
		c := fs.Bytes()[0]
		addEdge(u, v, c)
		addEdge(v, u, c)
	}

	logN = 0
	for (1 << logN) <= n {
		logN++
	}
	up = make([][]int, logN)
	for i := 0; i < logN; i++ {
		up[i] = make([]int, n+1)
	}
	depth = make([]int, n+1)
	parLabel = make([]byte, n+1)

	stack0 := make([]int, 0, n)
	stack0 = append(stack0, 1)
	for len(stack0) > 0 {
		v := stack0[len(stack0)-1]
		stack0 = stack0[:len(stack0)-1]
		for e := head[v]; e != -1; e = nxt[e] {
			w := to[e]
			if w == up[0][v] {
				continue
			}
			up[0][w] = v
			parLabel[w] = lab[e]
			depth[w] = depth[v] + 1
			stack0 = append(stack0, w)
		}
	}

	for j := 1; j < logN; j++ {
		prev := up[j-1]
		cur := up[j]
		for v := 1; v <= n; v++ {
			p := prev[v]
			if p != 0 {
				cur[v] = prev[p]
			}
		}
	}

	q := fs.Int()
	ans := make([]int64, q)

	reqHead := make([]int, n+1)
	for i := 1; i <= n; i++ {
		reqHead[i] = -1
	}
	reqPid := make([]int, 4*q)
	reqQ := make([]int, 4*q)
	reqNext := make([]int, 4*q)
	reqSign := make([]int8, 4*q)
	reqCnt := 0

	addReq := func(node, pid, qi int, sign int8) {
		reqPid[reqCnt] = pid
		reqQ[reqCnt] = qi
		reqSign[reqCnt] = sign
		reqNext[reqCnt] = reqHead[node]
		reqHead[node] = reqCnt
		reqCnt++
	}

	patMaps = make([]map[H]int, 101)
	currCnt = make([]int, 1)

	for qi := 0; qi < q; qi++ {
		u := fs.Int()
		v := fs.Int()
		s := fs.Bytes()
		a := lca(u, v)
		m := len(s)

		if m == 0 {
			ans[qi] = int64(depth[u] + depth[v] - 2*depth[a] + 1)
			continue
		}

		hS := hashBytes(s)
		hR := hashBytesRev(s)
		pidS := getPID(m, hS)
		pidR := getPID(m, hR)

		ans[qi] += int64(countCross(u, v, a, s))

		du := depth[u] - depth[a]
		if du >= m {
			z := kthAncestor(u, du-m+1)
			addReq(u, pidR, qi, 1)
			addReq(z, pidR, qi, -1)
		}

		dv := depth[v] - depth[a]
		if dv >= m {
			z := kthAncestor(v, dv-m+1)
			addReq(v, pidS, qi, 1)
			addReq(z, pidS, qi, -1)
		}
	}

	activeLens := make([]int, 0, 100)
	for m := 1; m <= 100; m++ {
		if patMaps[m] != nil {
			activeLens = append(activeLens, m)
		}
	}

	pref1 := make([]uint64, n+1)
	pref2 := make([]uint64, n+1)
	parent := up[0]

	stack := make([]int, 0, 2*n)
	stack = append(stack, 1)

	for len(stack) > 0 {
		x := stack[len(stack)-1]
		stack = stack[:len(stack)-1]

		if x > 0 {
			v := x
			if v != 1 {
				d := depth[v]
				val := uint64(parLabel[v]-'a') + 1
				pref1[d] = pref1[d-1]*B1 + val
				pref2[d] = pref2[d-1]*B2 + val
				for _, m := range activeLens {
					if m > d {
						break
					}
					h := H{
						pref1[d] - pref1[d-m]*pow1[m],
						pref2[d] - pref2[d-m]*pow2[m],
					}
					if pid, ok := patMaps[m][h]; ok {
						currCnt[pid]++
					}
				}
			}

			for i := reqHead[v]; i != -1; i = reqNext[i] {
				ans[reqQ[i]] += int64(reqSign[i]) * int64(currCnt[reqPid[i]])
			}

			stack = append(stack, -v)
			for e := head[v]; e != -1; e = nxt[e] {
				w := to[e]
				if w == parent[v] {
					continue
				}
				stack = append(stack, w)
			}
		} else {
			v := -x
			if v != 1 {
				d := depth[v]
				for _, m := range activeLens {
					if m > d {
						break
					}
					h := H{
						pref1[d] - pref1[d-m]*pow1[m],
						pref2[d] - pref2[d-m]*pow2[m],
					}
					if pid, ok := patMaps[m][h]; ok {
						currCnt[pid]--
					}
				}
			}
		}
	}

	out := make([]byte, 0, q*8)
	for i := 0; i < q; i++ {
		out = strconv.AppendInt(out, ans[i], 10)
		out = append(out, '\n')
	}
	w := bufio.NewWriterSize(os.Stdout, 1<<20)
	w.Write(out)
	w.Flush()
}