← Home
package main

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

var lc, rc, segSum, segAdd []int32

func newNode() int32 {
	lc = append(lc, 0)
	rc = append(rc, 0)
	segSum = append(segSum, 0)
	segAdd = append(segAdd, 0)
	return int32(len(segSum) - 1)
}

func apply(p int32, v int32, length int) {
	segSum[p] += int32(int64(v) * int64(length))
	segAdd[p] += v
}

func push(p int32, l, r int) {
	if p == 0 || segAdd[p] == 0 || l == r {
		return
	}
	m := (l + r) >> 1
	if lc[p] == 0 {
		lc[p] = newNode()
	}
	if rc[p] == 0 {
		rc[p] = newNode()
	}
	v := segAdd[p]
	apply(lc[p], v, m-l+1)
	apply(rc[p], v, r-m)
	segAdd[p] = 0
}

func merge(x, y int32, l, r int) int32 {
	if x == 0 {
		return y
	}
	if y == 0 {
		return x
	}
	if l == r {
		segSum[x] += segSum[y]
		segAdd[x] += segAdd[y]
		return x
	}
	m := (l + r) >> 1
	lc[x] = merge(lc[x], lc[y], l, m)
	rc[x] = merge(rc[x], rc[y], m+1, r)
	segSum[x] += segSum[y]
	segAdd[x] += segAdd[y]
	return x
}

func rangeAdd(p int32, ql, qr int, v int32, l, r int) int32 {
	if ql > r || qr < l || v == 0 {
		return p
	}
	if p == 0 {
		p = newNode()
	}
	if ql <= l && r <= qr {
		apply(p, v, r-l+1)
		if segSum[p] == 0 && segAdd[p] == 0 && lc[p] == 0 && rc[p] == 0 {
			return 0
		}
		return p
	}
	push(p, l, r)
	m := (l + r) >> 1
	lc[p] = rangeAdd(lc[p], ql, qr, v, l, m)
	rc[p] = rangeAdd(rc[p], ql, qr, v, m+1, r)
	segSum[p] = segSum[lc[p]] + segSum[rc[p]]
	if segSum[p] == 0 && segAdd[p] == 0 && lc[p] == 0 && rc[p] == 0 {
		return 0
	}
	return p
}

func query(p int32, ql, qr, l, r int, carry int32) int32 {
	if ql > r || qr < l {
		return 0
	}
	if ql <= l && r <= qr {
		return segSum[p] + int32(int64(carry)*int64(r-l+1))
	}
	if l == r {
		return segSum[p] + carry
	}
	carry += segAdd[p]
	m := (l + r) >> 1
	return query(lc[p], ql, qr, l, m, carry) + query(rc[p], ql, qr, m+1, r, carry)
}

func findFirst(p int32, l, r int, need, pref, carry int32) (int, int32, int32) {
	if l == r {
		return l, pref, segSum[p] + carry
	}
	carry += segAdd[p]
	m := (l + r) >> 1
	leftSum := segSum[lc[p]] + int32(int64(carry)*int64(m-l+1))
	if int64(m)+int64(pref)+int64(leftSum) >= int64(need) {
		return findFirst(lc[p], l, m, need, pref, carry)
	}
	return findFirst(rc[p], m+1, r, need, pref+leftSum, carry)
}

func cutPrefix(p int32, keep, l, r int) int32 {
	if p == 0 || keep <= 0 {
		return 0
	}
	if r <= keep {
		return p
	}
	if l > keep {
		return 0
	}
	if l == r {
		return p
	}
	m := (l + r) >> 1
	if segAdd[p] != 0 {
		v := segAdd[p]
		segAdd[p] = 0
		if keep <= m {
			if lc[p] == 0 {
				lc[p] = newNode()
			}
			apply(lc[p], v, m-l+1)
			rc[p] = 0
			lc[p] = cutPrefix(lc[p], keep, l, m)
		} else {
			if lc[p] == 0 {
				lc[p] = newNode()
			}
			if rc[p] == 0 {
				rc[p] = newNode()
			}
			apply(lc[p], v, m-l+1)
			apply(rc[p], v, r-m)
			rc[p] = cutPrefix(rc[p], keep, m+1, r)
		}
	} else {
		if keep <= m {
			rc[p] = 0
			lc[p] = cutPrefix(lc[p], keep, l, m)
		} else {
			rc[p] = cutPrefix(rc[p], keep, m+1, r)
		}
	}
	segSum[p] = segSum[lc[p]] + segSum[rc[p]]
	if segSum[p] == 0 && segAdd[p] == 0 && lc[p] == 0 && rc[p] == 0 {
		return 0
	}
	return p
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	idx := 0
	nextInt := func() int {
		for idx < len(data) && (data[idx] < '0' || data[idx] > '9') {
			idx++
		}
		val := 0
		for idx < len(data) && data[idx] >= '0' && data[idx] <= '9' {
			val = val*10 + int(data[idx]-'0')
			idx++
		}
		return val
	}

	n := nextInt()
	head := make([]int, n+1)
	to := make([]int, 2*n+5)
	nxt := make([]int, 2*n+5)
	ec := 0
	addEdge := func(u, v int) {
		ec++
		to[ec] = v
		nxt[ec] = head[u]
		head[u] = ec
	}
	for i := 0; i < n-1; i++ {
		u := nextInt()
		v := nextInt()
		addEdge(u, v)
		addEdge(v, u)
	}

	q := nextInt()
	qHead := make([]int, n+1)
	qNext := make([]int, q+1)
	qK := make([]int, q+1)
	qId := make([]int, q+1)
	for i := 1; i <= q; i++ {
		v := nextInt()
		k := nextInt()
		qK[i] = k
		qId[i] = i - 1
		qNext[i] = qHead[v]
		qHead[v] = i
	}

	parent := make([]int, n+1)
	childCount := make([]int, n+1)
	order := make([]int, 0, n)
	stack := make([]int, 0, n)
	stack = append(stack, 1)
	for len(stack) > 0 {
		v := stack[len(stack)-1]
		stack = stack[:len(stack)-1]
		order = append(order, v)
		for e := head[v]; e != 0; e = nxt[e] {
			u := to[e]
			if u == parent[v] {
				continue
			}
			parent[u] = v
			childCount[v]++
			stack = append(stack, u)
		}
	}

	lc = make([]int32, 1, 8000000)
	rc = make([]int32, 1, 8000000)
	segSum = make([]int32, 1, 8000000)
	segAdd = make([]int32, 1, 8000000)

	dp := make([]int32, n+1)
	ans := make([]int, q)
	N := n

	for i := n - 1; i >= 0; i-- {
		v := order[i]
		var root int32
		for e := head[v]; e != 0; e = nxt[e] {
			u := to[e]
			if parent[u] != v {
				continue
			}
			cr := dp[u]
			if segSum[root] < segSum[cr] {
				root, cr = cr, root
			}
			root = merge(root, cr, 1, N)
		}

		for qi := qHead[v]; qi != 0; qi = qNext[qi] {
			extra := int32(0)
			k := qK[qi]
			if k < N {
				extra = query(root, k+1, N, 1, N, 0)
			}
			ans[qId[qi]] = childCount[v] + int(extra)
		}

		if childCount[v] == 0 {
			dp[v] = 0
			continue
		}

		C := int32(childCount[v]-1) + segSum[root]
		if C <= 0 {
			dp[v] = 0
			continue
		}

		pos, prefBefore, cur := findFirst(root, 1, N, C, 0, 0)
		root = cutPrefix(root, pos, 1, N)
		if pos > 1 {
			root = rangeAdd(root, 1, pos-1, 1, 1, N)
		}
		val := C - int32(pos-1) - prefBefore
		diff := val - cur
		if diff != 0 {
			root = rangeAdd(root, pos, pos, diff, 1, N)
		}
		dp[v] = root
	}

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