```go
package main
import (
"bufio"
"io"
"os"
)
const MAXN = 400010
var acNext [MAXN][26]int32
var fail [MAXN]int32
var failHead [MAXN]int32
var in [MAXN]int32
var out [MAXN]int32
var textHead [MAXN]int32
var queryHead [MAXN]int32
var bit [MAXN]int32
var ans [MAXN]int32
var failTo []int32
var failNext []int32
var textTo []int32
var textNext []int32
var textChar []byte
var queryId []int32
var queryMatch []int32
var queryNext []int32
var acNodes int32 = 1
var timer int32
var buf []byte
var pos int
func nextInt() int32 {
for pos < len(buf) && buf[pos] <= ' ' {
pos++
}
if pos >= len(buf) {
return 0
}
res := int32(0)
for pos < len(buf) && buf[pos] > ' ' {
res = res*10 + int32(buf[pos]-'0')
pos++
}
return res
}
func nextChar() byte {
for pos < len(buf) && buf[pos] <= ' ' {
pos++
}
if pos >= len(buf) {
return 0
}
c := buf[pos]
pos++
return c
}
func insertString() int32 {
for pos < len(buf) && buf[pos] <= ' ' {
pos++
}
if pos >= len(buf) {
return 1
}
u := int32(1)
for pos < len(buf) && buf[pos] > ' ' {
c := int32(buf[pos] - 'a')
if acNext[u][c] == 0 {
acNodes++
acNext[u][c] = acNodes
}
u = acNext[u][c]
pos++
}
return u
}
func addFailEdge(u, v int32) {
failTo = append(failTo, v)
failNext = append(failNext, failHead[u])
failHead[u] = int32(len(failTo) - 1)
}
func addTextEdge(u, v int32, c byte) {
textTo = append(textTo, v)
textChar = append(textChar, c)
textNext = append(textNext, textHead[u])
textHead[u] = int32(len(textTo) - 1)
}
func addQuery(u, id, match int32) {
queryId = append(queryId, id)
queryMatch = append(queryMatch, match)
queryNext = append(queryNext, queryHead[u])
queryHead[u] = int32(len(queryId) - 1)
}
func buildAC() {
q := make([]int32, 0, acNodes)
fail[1] = 1
for c := int32(0); c < 26; c++ {
if acNext[1][c] != 0 {
fail[acNext[1][c]] = 1
q = append(q, acNext[1][c])
} else {
acNext[1][c] = 1
}
}
for head := 0; head < len(q); head++ {
u := q[head]
for c := int32(0); c < 26; c++ {
if acNext[u][c] != 0 {
fail[acNext[u][c]] = acNext[fail[u]][c]
q = append(q, acNext[u][c])
} else {
acNext[u][c] = acNext[fail[u]][c]
}
}
}
}
func buildFailTreeEuler() {
type state struct {
u int32
e int32
}
stack := make([]state, 0, acNodes)
stack = append(stack, state{1, failHead[1]})
timer++
in[1] = timer
for len(stack) > 0 {
top := len(stack) - 1
u := stack[top].u
e := stack[top].e
if e != 0 {
v := failTo[e]
stack[top].e = failNext[e]
timer++
in[v] = timer
stack = append(stack, state{v, failHead[v]})
} else {
out[u] = timer
stack = stack[:top]
}
}
}
func add(idx, val int32) {
for ; idx <= timer; idx += idx & -idx {
bit[idx] += val
}
}
func query(idx int32) int32 {
sum := int32(0)
for ; idx > 0; idx -= idx & -idx {
sum += bit[idx]
}
return sum
}
func solveText(n int32) {
type state struct {
u int32
acState int32
e int32
}
stack := make([]state, 0, n+1)
stack = append(stack, state{0, 1, textHead[0]})
add(in[1], 1)
for len(stack) > 0 {
top := len(stack) - 1
u := stack[top].u
acState := stack[top].acState
e := stack[top].e
if e == textHead[u] {
for qe := queryHead[u]; qe != 0; qe = queryNext[qe] {
id := queryId[qe]
match := queryMatch[qe]
ans[id] = query(out[match]) - query(in[match]-1)
}
}
if e != 0 {
v := textTo[e]
c := textChar[e] - 'a'
stack[top].e = textNext[e]
nxtAc := acNext[acState][c]
add(in[nxtAc], 1)
stack = append(stack, state{v, nxtAc, textHead[v]})
} else {
add(in[acState], -1)
stack = stack[:top]
}
}
}
func writeInt(w *bufio.Writer, n int32) {
if n == 0 {
w.WriteByte('0')
w.WriteByte('\n')
return
}
var buf [12]byte
i := 11
for n > 0 {
buf[i] = byte(n%10 + '0')
n /= 10
i--
}
w.Write(buf[i+1:])
w.WriteByte('\n')
}
func main() {
buf, _ = io.ReadAll(os.Stdin)
failTo = make([]int32, 1, MAXN)
failNext = make([]int32, 1, MAXN)
textTo = make([]int32, 1, MAXN)
textNext = make([]int32, 1, MAXN)
textChar = make([]byte, 1, MAXN)
queryId = make([]int32, 1, MAXN)
queryMatch = make([]int32, 1, MAXN)
queryNext = make([]int32, 1, MAXN)
n := nextInt()
if n == 0 {
return
}
for i := int32(1); i <= n; i++ {
typ := nextInt()
if typ == 1 {
c := nextChar()
addTextEdge(0, i, c)
} else {
j := nextInt()
c := nextChar()
addTextEdge(j, i, c)
}
}
m := nextInt()
for i := int32(1); i <= m; i++ {
v := nextInt()
match := insertString()
addQuery(v, i, match)
}
buildAC()
for u := int32(2); u <= acNodes; u++ {
addFailEdge(fail[u], u)
}
buildFailTreeEuler()
solveText(n)
outBuf := bufio.NewWriterSize(os.Stdout, 65536)
for i := int32(1); i <= m; i++ {
writeInt(outBuf, ans[i])
}
outBuf.Flush()
}
```