← Home
```go
package main

import (
	"bufio"
	"fmt"
	"io"
	"math"
	"os"
)

func parseAll(data []byte) []int {
	n := len(data)
	res := make([]int, 0, 2500000)
	i := 0
	for i < n {
		for i < n && (data[i] < '0' || data[i] > '9') {
			i++
		}
		if i >= n {
			break
		}
		x := 0
		for i < n && data[i] >= '0' && data[i] <= '9' {
			x = x*10 + int(data[i]-'0')
			i++
		}
		res = append(res, x)
	}
	return res
}

func min64(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	nums := parseAll(data)
	p := 0
	nextInt := func() int { x := nums[p]; p++; return x }

	n := nextInt()
	q := nextInt()

	parent := make([]int, n+1)
	weight := make([]int64, n+1)
	depth := make([]int64, n+1)
	children := make([][]int, n+1)

	for i := 2; i <= n; i++ {
		pi := nextInt()
		wi := int64(nextInt())
		parent[i] = pi
		weight[i] = wi
		depth[i] = depth[pi] + wi
		children[pi] = append(children[pi], i)
	}

	isLeaf := make([]bool, n+1)
	for i := 1; i <= n; i++ {
		if len(children[i]) == 0 {
			isLeaf[i] = true
		}
	}

	leafIdx := make([]int, n+1)
	for i := range leafIdx {
		leafIdx[i] = -1
	}
	leafNode := make([]int, 0, n)
	for i := 1; i <= n; i++ {
		if isLeaf[i] {
			leafIdx[i] = len(leafNode)
			leafNode = append(leafNode, i)
		}
	}
	M := len(leafNode)

	leafStart := make([]int, n+1)
	leafEnd := make([]int, n+1)
	for i := 1; i <= n; i++ {
		leafStart[i] = M
		leafEnd[i] = -1
	}
	for i := 1; i <= n; i++ {
		if isLeaf[i] {
			idx := leafIdx[i]
			leafStart[i] = idx
			leafEnd[i] = idx
		}
	}
	for i := n; i >= 2; i-- {
		prt := parent[i]
		if leafStart[i] < leafStart[prt] {
			leafStart[prt] = leafStart[i]
		}
		if leafEnd[i] > leafEnd[prt] {
			leafEnd[prt] = leafEnd[i]
		}
	}

	lowerBound := func(arr []int, x int) int {
		lo, hi := 0, len(arr)
		for lo < hi {
			mid := (lo + hi) / 2
			if arr[mid] < x {
				lo = mid + 1
			} else {
				hi = mid
			}
		}
		return lo
	}
	upperBound := func(arr []int, x int) int {
		lo, hi := 0, len(arr)
		for lo < hi {
			mid := (lo + hi) / 2
			if arr[mid] <= x {
				lo = mid + 1
			} else {
				hi = mid
			}
		}
		return lo
	}

	type queryInfo struct {
		L, R int
		idx  int
	}
	queriesAt := make([][]queryInfo, n+1)
	for i := 0; i < q; i++ {
		v := nextInt()
		l := nextInt()
		r := nextInt()
		L := lowerBound(leafNode, l)
		R := upperBound(leafNode, r) - 1
		if L <= R {
			queriesAt[v] = append(queriesAt[v], queryInfo{L, R, i})
		}
	}

	N := 1
	H := 0
	for N < M {
		N <<= 1
		H++
	}
	tree := make([]int64, 2*N)
	lazy := make([]int64, N+1)
	for i := 0; i < M; i++ {
		tree[N+i] = depth[leafNode[i]]
	}
	for i := M; i < N; i++ {
		tree[N+i] = math.MaxInt64
	}
	for i := N - 1; i > 0; i-- {
		tree[i] = min64(tree[i<<1], tree[i<<1|1])
	}

	apply := func(p int, delta int64) {
		tree[p] += delta
		if p < N {
			lazy[p] += delta
		}
	}
	push := func(p int) {
		for s := H; s > 0; s-- {
			i := p >> s
			if lazy[i] != 0 {
				apply(i<<1, lazy[i])
				apply(i<<1|1, lazy[i])
				lazy[i] = 0
			}
		}
	}
	pull := func(p int) {
		for p >>= 1; p > 0; p >>= 1 {
			tree[p] = min64(tree[p<<1], tree[p<<1|1]) + lazy[p]
		}
	}
	rangeAdd := func(l, r int, delta int64) {
		l += N
		r += N + 1
		l0, r0 := l, r
		push(l0)
		push(r0 - 1)
		for l < r {
			if l&1 == 1 {
				apply(l, delta)
				l++
			}
			if r&1 == 1 {
				r--
				apply(r, delta)
			}
			l >>= 1
			r >>= 1
		}
		pull(l0)
		pull(r0 - 1)
	}
	rangeMin := func(l, r int) int64 {
		l += N
		r += N + 1
		push(l)
		push(r - 1)
		res := int64(math.MaxInt64)
		for l < r {
			if l&1 == 1 {
				res = min64(res, tree[l])
				l++
			}
			if r&1 == 1 {
				r--
				res = min64(res, tree[r])
			}
			l >>= 1
			r >>= 1
		}
		return res
	}

	type Task struct {
		Type  byte
		Node  int
		L, R  int
		Delta int64
	}
	ans := make([]int64, q)
	stack := make([]Task, 0, 3*n)
	stack = append(stack, Task{Type: 0, Node: 1})
	for len(stack) > 0 {
		t := stack[len(stack)-1]
		stack = stack[:len(stack)-1]
		if t.Type == 0 {
			u := t.Node
			for _, qr := range queriesAt[u] {
				ans[qr.idx] = depth[u] + rangeMin(qr.L, qr.R)
			}
			ch := children[u]
			for i := len(ch) - 1; i >= 0; i-- {
				c := ch[i]
				l := leafStart[c]
				r := leafEnd[c]
				w := weight[c]
				stack = append(stack, Task{Type: 1, L: l, R: r, Delta: 2 * w})
				stack = append(stack, Task{Type: 0, Node: c})
				stack = append(stack, Task{Type: 1, L: l, R: r, Delta: -2 * w})
			}
		} else {
			rangeAdd(t.L, t.R, t.Delta)
		}
	}

	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	for i := 0; i < q; i++ {
		fmt.Fprintln(out, ans[i])
	}
	out.Flush()
}
```