package main
import ."fmt"

// github.com/EndlessCheng/codeforces-go
func main() {
	f := [1001][1001]int{}
	var T, n, k int
	for Scan(&T); T > 0; T-- {
		Scan(&n, &k)
		for i := 1; i <= k; i++ {
			f[i][0] = 1
			for j := 1; j <= n; j++ {
				f[i][j] = (f[i][j-1] + f[i-1][n-j]) % (1e9 + 7)
			}
		}
		Println(f[k][n])
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	const mod = 1000000007
	defer out.Flush()
	var t int
	fmt.Fscan(in,&t)
	for c:=1;c<=t;c++{
		var n, k int
		fmt.Fscan(in,&n,&k)
		a := make([]int,n+5)
		cnt:=0
		ans:=0
		for i:=k;i>=1;i--{
			cnt++
			if i==k{
				ans += 1
				for j:=1;j<=n;j++{
					a[j]=1
				}
				continue
			}
			if cnt%2==0{
				pre := 0
				for j:=n;j>=1;j--{
					ans = (ans%(mod) + a[j]%(mod))%(mod)
					temp := a[j]
					a[j] = pre
					pre = (pre%(mod) + temp%(mod))%(mod)
				}
			}else{
				pre := 0
				for j:=1;j<=n;j++{
					ans = (ans%(mod) + a[j]%(mod))%(mod)
					temp := a[j]
					a[j] = pre
					pre = (pre%(mod) + temp%(mod))%(mod)
				}
			}
		}
		fmt.Fprintln(out,ans%mod)
	}
}

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	tc := readNum(reader)

	var buf bytes.Buffer

	for tc > 0 {
		tc--
		n, k := readTwoNums(reader)
		res := solve(n, k)
		buf.WriteString(fmt.Sprintf("%d\n", res))
	}

	fmt.Print(buf.String())
}

func readInt(bytes []byte, from int, val *int) int {
	i := from
	sign := 1
	if bytes[i] == '-' {
		sign = -1
		i++
	}
	tmp := 0
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + int(bytes[i]-'0')
		i++
	}
	*val = tmp * sign
	return i
}

func readNum(reader *bufio.Reader) (a int) {
	bs, _ := reader.ReadBytes('\n')
	readInt(bs, 0, &a)
	return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
	res := readNNums(reader, 2)
	a, b = res[0], res[1]
	return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
	res := readNNums(reader, 3)
	a, b, c = res[0], res[1], res[2]
	return
}

func readNNums(reader *bufio.Reader, n int) []int {
	res := make([]int, n)
	x := 0
	bs, _ := reader.ReadBytes('\n')
	for i := 0; i < n; i++ {
		for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
			x++
		}
		x = readInt(bs, x, &res[i])
	}
	return res
}

func readUint64(bytes []byte, from int, val *uint64) int {
	i := from

	var tmp uint64
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + uint64(bytes[i]-'0')
		i++
	}
	*val = tmp

	return i
}

const MOD = 1000000007

func modAdd(a *int, b int) {
	*a += b
	if *a >= MOD {
		*a -= MOD
	}
}

func solve(n, k int) int {
	dp := make([][]int, n)
	for i := 0; i < n; i++ {
		dp[i] = make([]int, k+1)
	}

	for j := 1; j <= k; j++ {

		if j > 2 {
			var sum int
			for i := 0; i < n-1; i++ {
				modAdd(&sum, dp[i][j-2])
				dp[i][j] = sum
			}
		}
		dp[n-1][j] = 1
		for i := n - 2; i >= 0; i-- {
			// go right and go down with j - 1
			modAdd(&dp[i][j], dp[i+1][j])
			if j > 1 {
				// go left with j - 1
				modAdd(&dp[i][j], 1)
			}
		}
	}

	if k > 1 {
		modAdd(&dp[0][k], 1)
	}

	return dp[0][k]
}

package main

import (
	"bufio"
	. "fmt"
	"os"
)

const N = 1e3 + 7
const mod = 1e9 + 7

var ps [N][N]int

func solve() {
	var n, k int
	Scan(&n, &k)
	ans := 1
	if k > 1 {
		ans += n
		for i := 1; i <= n; i++ {
			ps[k-1][i] = 1
		}
	}
	turn := 0
	for i := k - 2; i > 0; i-- {
		if turn == 0 {
			for j := n - 1; j > 0; j-- {
				ps[i][j] = ps[i][j+1] + ps[i+1][j+1]
				ps[i][j] %= mod
				ans += ps[i][j]
				ans %= mod
			}
		} else {
			for j := 2; j <= n; j++ {
				ps[i][j] = ps[i][j-1] + ps[i+1][j-1]
				ps[i][j] %= mod
				ans += ps[i][j]
				ans %= mod
			}
		}
		turn = 1 - turn
	}
	Println(ans)
	for i := 1; i <= k; i++ {
		for j := 0; j <= n; j++ {
			ps[i][j] = 0
		}
	}
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	var T int
	Scan(&T)
	for ; T > 0; T-- {
		solve()
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

const N int = 1e3 + 5
var stdIn = bufio.NewReader(os.Stdin)
var stdOut = bufio.NewWriter(os.Stdout)
type ll int64
const mod ll = 1e9 + 7
func main() {
	defer stdOut.Flush()
	var t int
	fmt.Fscan(stdIn, &t)
	a := [N][N]ll{}

	for t > 0{
		var n, k int
		fmt.Fscan(stdIn, &n ,&k)
		for i := 0; i <= n; i ++ {
			a[1][i] = 1
		}

		for age := 2; age <= k; age ++ {
			a[age][0] = 1
			for plane := 1; plane <= n; plane ++ {
				a[age][plane] =(a[age][plane - 1] + a[age - 1][n - plane]) % mod
				//fmt.Fprintf(stdOut, "%d , %d : ", age, plane)
				//fmt.Fprintln(stdOut, a[age][plane])
			}
		}
		fmt.Fprintln(stdOut, a[k][n])
		t --
	}

}

package main

import (
	"bufio"
	"fmt"
	"os"
)

var reader *bufio.Reader = bufio.NewReader(os.Stdin)
var writer *bufio.Writer = bufio.NewWriter(os.Stdout)
var scanner *bufio.Scanner = bufio.NewScanner(reader)

const mod = 1000000007

func scanf(f string, args ...interface{})  { fmt.Fscanf(reader, f, args...) }
func printf(f string, args ...interface{}) { fmt.Fprintf(writer, f, args...) }

func toInt(buf []byte) (n int) {
	for _, v := range buf {
		n = (n * 10) + int(v-'0')
	}
	return
}

type Pair struct {
	a, b int
}

type Pairs []Pair

func (a Pairs) Len() int           { return len(a) }
func (a Pairs) Less(i, j int) bool { return a[i].a < a[j].a }
func (a Pairs) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }

func gcd(a, b int64) int64 {
	if b != 0 {
		return gcd(b, a%b)
	} else {
		return a
	}
}

//define constants here
const (
	N = 1001
	K = 1001
)

//define global variables here
var (
	dp   = [N][K][2]int{}
	n, k int
)

//Write your code from here

func solve(cur, k, dir int) int {

	if k == 1 {
		return 1
	}

	if dp[cur][k][dir] != -1 {
		return dp[cur][k][dir]
	}

	ans := 2 //me and my copy
	//dir are two make copy forward and one backward
	if dir == 1 {

		if cur < n {
			ans += solve(cur+1, k, dir) - 1
		}
		ans %= mod
		if cur > 1 {
			ans += solve(cur-1, k-1, 1-dir) - 1
		}

		ans %= mod
		dp[cur][k][dir] = ans

	} else {

		if cur > 1 {
			ans += solve(cur-1, k, dir) - 1
		}
		ans %= mod
		if cur < n {
			ans += solve(cur+1, k-1, 1-dir) - 1
		}
		ans %= mod
		dp[cur][k][dir] = ans
	}
	return ans

}

func main() {
	defer writer.Flush()
	var t int
	scanf("%d\n", &t)

	for t > 0 {
		scanf("%d %d\n", &n, &k)

		for i := 0; i < 1001; i++ {
			for j := 0; j < 1001; j++ {
				dp[i][j][0] = -1
				dp[i][j][1] = -1
			}
		}
		printf("%d\n", solve(1, k, 1))
		t--
	}

}


package main

import (
	"strconv"
	"bufio"
	"os"
	"fmt"
)

func main() {
	sc := NewScanner()
	N := sc.NextInt()
	S := sc.NextLine()

	mp := map[byte]int{}
	mx := N / 4

	for _, v := range S {
		if v == '?' {
			continue
		}
		mp[byte(v)]++
		if mp[byte(v)] > mx {
			fmt.Println("===")
			return
		}
	}
	ans := make([]byte, 0)

	for _, v := range S {
		if v == '?' {
			a := byte(' ')
			for _, c := range "AGCT" {
				if mp[byte(c)] < mx {
					mp[byte(c)]++
					a = byte(c)
					break
				}
			}
			if a == ' ' {
				fmt.Println("===")
				return
			}
			ans = append(ans, a)

		} else {
			ans = append(ans, byte(v))
		}
	}
	fmt.Println(string(ans))

}

type Scanner struct {
	r   *bufio.Reader
	buf []byte
	p   int
}

func NewScanner() *Scanner {
	rdr := bufio.NewReaderSize(os.Stdin, 1000)
	return &Scanner{r:rdr}
}
func (s *Scanner) Next() string {
	s.pre()
	start := s.p
	for ; s.p < len(s.buf); s.p++ {
		if s.buf[s.p] == ' ' {
			break
		}
	}
	result := string(s.buf[start:s.p])
	s.p++
	return result
}
func (s *Scanner) NextLine() string {
	s.pre()
	start := s.p
	s.p = len(s.buf)
	return string(s.buf[start:])
}
func (s *Scanner) NextInt() int {
	v, _ := strconv.Atoi(s.Next())
	return v
}
func (s *Scanner) NextInt64() int64 {
	v, _ := strconv.ParseInt(s.Next(), 10, 64)
	return v
}

func (s *Scanner) NextIntArray() []int {
	s.pre()
	start := s.p
	result := []int{}
	for ; s.p < len(s.buf) + 1; s.p++ {
		if s.p == len(s.buf) || s.buf[s.p] == ' ' {
			v, _ := strconv.ParseInt(string(s.buf[start:s.p]), 10, 0)
			result = append(result, int(v))
			start = s.p + 1
		}
	}

	return result
}
func (s *Scanner) NextInt64Array() []int64 {
	s.pre()
	start := s.p
	result := []int64{}
	for ; s.p < len(s.buf) + 1; s.p++ {
		if s.p == len(s.buf) || s.buf[s.p] == ' ' {
			v, _ := strconv.ParseInt(string(s.buf[start:s.p]), 10, 64)
			result = append(result, v)
			start = s.p + 1
		}
	}
	return result
}

func (s *Scanner) NextMap() map[int]bool {
	s.pre()
	start := s.p
	mp := map[int]bool{}
	for ; s.p < len(s.buf); s.p++ {
		if s.buf[s.p] == ' ' {
			v, _ := strconv.Atoi(string(s.buf[start:s.p]))
			mp[v] = true
			start = s.p + 1
		}
	}
	v, _ := strconv.Atoi(string(s.buf[start:s.p]))
	mp[v] = true

	return mp
}

func (s *Scanner) pre() {
	if s.p >= len(s.buf) {
		s.readLine()
		s.p = 0
	}
}
func (s *Scanner) readLine() {
	s.buf = make([]byte, 0)
	for {
		l, p, e := s.r.ReadLine()
		if e != nil {
			panic(e)
		}
		s.buf = append(s.buf, l...)
		if !p {
			break
		}
	}
}

package main

import "fmt"

func main() {
	var n int
	fmt.Scanln(&n)

	var s string
	fmt.Scan(&s)

	var afreq, cfreq, gfreq, tfreq, qfreq int
	for _, c := range s {
		switch c {
		case 'A':
			afreq++
		case 'G':
			gfreq++
		case 'C':
			cfreq++
		case 'T':
			tfreq++
		case '?':
			qfreq++
		}
	}

	var ss = []byte(s)

	for i := range s {
		if s[i] == '?' {
			if gfreq < cfreq || gfreq < tfreq || gfreq < afreq {
				ss[i] = 'G'
				gfreq++
			} else if cfreq < gfreq || cfreq < tfreq || cfreq < afreq {
				ss[i] = 'C'
				cfreq++
			} else if tfreq < cfreq || tfreq < gfreq || tfreq < afreq {
				ss[i] = 'T'
				tfreq++
			} else {
				ss[i] = 'A'
				afreq++
			}
		}
	}

	if afreq == gfreq && afreq == cfreq && afreq == tfreq {
		fmt.Println(string(ss))
	} else {
		fmt.Println("===")
	}
}

package main

import (
	"fmt"
)

func max(x int, y int) int {
	if (x > y) {
		return x
	}
	return y
}

func main() {

	var n int
	fmt.Scanf("%d\n", &n)

	var str string
	fmt.Scanf("%s", &str)

	s := []rune(str)

	var cnt[5] int

	for i:=0; i<n; i++ {

		if (s[i]=='A') {
			cnt[0]++;
		} else if (s[i]=='C') {
			cnt[1]++;
		} else if (s[i]=='G') {
			cnt[2]++;
		} else if (s[i]=='T') {
			cnt[3]++;
		}

	}

	var x int

	x = max(max(cnt[0], cnt[1]), max(cnt[2], cnt[3]))

	for i:=0; i<4; i++ {
		cnt[i] -= x
	}

	for i:=0; i<n; i++ {
		if (s[i]=='?') {
			if (cnt[0] < 0) {
				s[i] = 'A'
				cnt[0]++
			} else if (cnt[1] < 0) {
				s[i] = 'C'
				cnt[1]++
			} else if (cnt[2] < 0) {
				s[i] = 'G'
				cnt[2]++
			} else if (cnt[3] < 0) {
				s[i] = 'T'
				cnt[3]++
			} else {
				for j:=0; j<4; j++ {
					cnt[j]--
				}
				s[i] = 'A'
				cnt[0]++
			}
		}
	}

	if (cnt[0]==0 && cnt[1]==0 && cnt[2] == 0 && cnt[3] == 0) {
		fmt.Printf("%s", string(s))
	} else {
		fmt.Printf("===")
	}
}

package main

import (
	"fmt"
)

func main() {
	var s string
	var n int

	fmt.Scanf("%d\n", &n)
	fmt.Scanf("%s\n", &s)

	if n%4 != 0 {
		fmt.Println("===")
		return
	}

	counts := map[rune]int{
		'A': 0,
		'C': 0,
		'G': 0,
		'T': 0,
	}
	for _, c := range s {
		if c == '?' {
			continue
		}
		counts[c]++
	}

	for _, count := range counts {
		if count > n/4 {
			fmt.Println("===")
			return
		}
	}

	out := make([]byte, len(s))
	for i, c := range s {
		if c != '?' {
			out[i] = byte(c)
			continue
		}

		var replace rune
		// fmt.Println(counts)
		for c, count := range counts {
			if count >= n/4 {
				continue
			}
			replace = c
			counts[c]++
			break
		}

		out[i] = byte(replace)
	}

	fmt.Println(string(out))
}

package main

import(
	"fmt"
	"os"
)

func main() {
	var a, c, g, t int = 0, 0, 0, 0
	var n int
	var s string

	fmt.Fscanf(os.Stdin, "%d\n%s\n", &n, &s)

	S := []rune(s)

	div := n / 4.0

	for _, r := range S {
		switch r {
		case 'A':
			a++
		case 'C':
			c++
		case 'G':
			g++
		case 'T':
			t++
		}
	}

	if n % 4 == 0 && a <= div && c <= div && g <= div && t <= div {
		for i, r := range S {
			if r != '?' {
				continue
			}
			if a < div {
				S[i] = 'A'
				a++
				continue
			}
			if c < div {
				S[i] = 'C'
				c++
				continue
			}
			if g < div {
				S[i] = 'G'
				g++
				continue
			}
			if t < div {
				S[i] = 'T'
				t++
				continue
			}
		}
	}

	if a == div && c == div && g == div && t == div {
		fmt.Println(string(S))
	} else {
		fmt.Println("===")
	}
}

package main

import (
	"fmt"
)

func main() {
	var s string
	var n int

	fmt.Scanf("%d\n", &n)
	fmt.Scanf("%s\n", &s)

	if n%4 != 0 {
		fmt.Println("===")
		return
	}

	counts := map[rune]int{
		'A': 0,
		'C': 0,
		'G': 0,
		'T': 0,
	}
	for _, c := range s {
		if c == '?' {
			continue
		}
		counts[c]++
	}

	for _, count := range counts {
		if count > n/4 {
			fmt.Println("===")
			return
		}
	}

	out := make([]byte, len(s))
	for i, c := range s {
		if c != '?' {
			out[i] = byte(c)
			continue
		}

		var replace rune
		for c, count := range counts {
			if count > n/4 {
				continue
			}
			replace = c
			counts[c]++
			break
		}

		out[i] = byte(replace)
	}

	fmt.Println(string(out))
}


package main

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
	"sort"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	var buf bytes.Buffer

	tc := readNum(reader)

	for tc > 0 {
		tc--
		n := readNum(reader)
		P := readNNums(reader, n-1)
		A := readNNums(reader, n-1)
		res := solve(n, P, A)
		buf.WriteString(fmt.Sprintf("%d\n", res))
	}

	fmt.Print(buf.String())
}

func readInt(bytes []byte, from int, val *int) int {
	i := from
	sign := 1
	if bytes[i] == '-' {
		sign = -1
		i++
	}
	tmp := 0
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + int(bytes[i]-'0')
		i++
	}
	*val = tmp * sign
	return i
}

func readNum(reader *bufio.Reader) (a int) {
	bs, _ := reader.ReadBytes('\n')
	readInt(bs, 0, &a)
	return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
	res := readNNums(reader, 2)
	a, b = res[0], res[1]
	return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
	res := readNNums(reader, 3)
	a, b, c = res[0], res[1], res[2]
	return
}

func readNNums(reader *bufio.Reader, n int) []int {
	res := make([]int, n)
	x := 0
	bs, _ := reader.ReadBytes('\n')
	for i := 0; i < n; i++ {
		for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
			x++
		}
		x = readInt(bs, x, &res[i])
	}
	return res
}

func readUint64(bytes []byte, from int, val *uint64) int {
	i := from

	var tmp uint64
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + uint64(bytes[i]-'0')
		i++
	}
	*val = tmp

	return i
}

const N_INF = -(1 << 59)

func solve(n int, P []int, A []int) int64 {

	pp := make([]int, n)
	copy(pp[1:], P)

	g := NewGraph(n, n+10)

	for i := 1; i < n; i++ {
		pp[i]--
		g.AddEdge(pp[i], i)
	}

	D := make([]int, n)
	var mx int
	var dfs func(u int)
	dfs = func(u int) {
		mx = max(mx, D[u])
		for i := g.nodes[u]; i > 0; i = g.next[i] {
			v := g.to[i]
			D[v] = D[u] + 1
			dfs(v)
		}
	}
	dfs(0)
	mx++
	C := make([]int, mx)
	for i := 0; i < n; i++ {
		C[D[i]]++
	}
	L := make([][]Pair, mx)
	for i := 0; i < mx; i++ {
		L[i] = make([]Pair, 0, C[i])
	}
	for i := 1; i < n; i++ {
		L[D[i]] = append(L[D[i]], Pair{A[i-1], i})
	}

	for i := 0; i < mx; i++ {
		sort.Sort(Pairs(L[i]))
	}
	dp := make([]int64, n)

	for i := 1; i < mx; i++ {
		cur := L[i]
		// if place blue at j'th node in this level, find another best red
		// because all nodes before j < A[j], so the best is A[j] - A[k] + dp[P[k]]
		// let best is dp[P[k]] - A[k]
		var best int64 = N_INF
		for _, p := range cur {
			j := p.second
			dp[j] = max2(dp[j], best+int64(A[j-1]))
			best = max2(best, dp[pp[j]]-int64(A[j-1]))
		}
		// A[k] - A[j] + dp[pp[k]]
		best = N_INF
		for k := len(cur) - 1; k >= 0; k-- {
			p := cur[k]
			j := p.second
			dp[j] = max2(dp[j], best-int64(A[j-1]))
			best = max2(best, int64(A[j-1])+dp[pp[j]])
		}
		// a0 or an is blue
		a0 := cur[0].first
		an := cur[len(cur)-1].first
		for _, p := range cur {
			j := p.second
			//if make j as red, then it's parent has to be red
			dp[j] = max2(dp[j], int64(p.first-a0)+dp[pp[j]])
			dp[j] = max2(dp[j], int64(an-p.first)+dp[pp[j]])
		}
	}

	var res int64

	for _, p := range L[mx-1] {
		res = max2(res, dp[p.second])
	}

	return res
}

type Pair struct {
	first, second int
}

type Pairs []Pair

func (this Pairs) Len() int {
	return len(this)
}

func (this Pairs) Less(i, j int) bool {
	return this[i].first < this[j].first
}

func (this Pairs) Swap(i, j int) {
	this[i], this[j] = this[j], this[i]
}

func max(a, b int) int {
	if a >= b {
		return a
	}
	return b
}

func max2(a, b int64) int64 {
	if a >= b {
		return a
	}
	return b
}

type Graph struct {
	nodes []int
	next  []int
	to    []int
	cur   int
}

func NewGraph(n int, e int) *Graph {
	nodes := make([]int, n)
	next := make([]int, e)
	to := make([]int, e)
	return &Graph{nodes, next, to, 0}
}

func (g *Graph) AddEdge(u, v int) {
	g.cur++
	g.next[g.cur] = g.nodes[u]
	g.nodes[u] = g.cur
	g.to[g.cur] = v
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type node struct {
	index  int
	parent int
	edges  []int
	data   int64
	// min, max int64
	f   int64
	vis bool
}

type bv struct {
	b, v int64
}

func calcParent(p *node, data, min, max int64) int64 {
	v1, v2 := data-min, max-data
	if v1 < v2 {
		return v2 + p.f
	}
	return v1 + p.f
}

func calc(nodes []*node, lt, gt []bv, index int, min, max int64) int64 {
	now := nodes[index]
	if now.parent == index {
		if index != 0 {
			panic("corrupted")
		}
		return 0
	}

	res := calcParent(nodes[now.parent], now.data, min, max)
	//fmt.Println(index, "parent", res)

	// Search returns the smallest i that func(i) is true
	// which means the tightest range that contains now.data
	pl := sort.Search(len(lt), func(i int) bool {
		return now.data <= lt[i].b
	})
	// actually given that we have <= in the test, it is impossible for
	// it to be out of range
	if pl < len(lt) {
		if v := lt[pl].v - now.data; v > res {
			res = v
		}
		//fmt.Println(index, "lt", lt[pl], lt[pl].v-now.data)
	}
	pg := sort.Search(len(gt), func(i int) bool {
		return now.data >= gt[i].b
	})
	if pg < len(gt) {
		if v := gt[pg].v + now.data; v > res {
			res = v
		}
		//fmt.Println(index, "gt", gt[pg], gt[pg].v+now.data)
	}
	return res
}

// warning: squash is destructive
// although this looks like o(n*n), it is actually o(n), as every elem is only
// pushed into the stack once and popped at most once.
func squash(x []bv) []bv {
	//fmt.Println("squash")
	//fmt.Println(x)
	var top int = 0
	for i := 1; i < len(x); i++ {
		if x[i].b == x[top].b {
			continue
			// save us some trouble as we already sort v in decreasing order
		}
		for top >= 0 && x[top].v <= x[i].v {
			top--
		}
		top++
		x[top] = x[i]
	}
	//fmt.Println(top, x[:top+1])
	return x[:top+1]
}

func solve(nodes []*node) {
	var (
		queue, next      []int
		lt, gt           []bv //less than, greater than
		nextLt, nextGt   []bv
		res              int64 = -1
		min, max         int64
		nextMin, nextMax int64
		count            int
	)

	queue = []int{0}
	nodes[0].vis = true

	for len(queue) != 0 {
		/*fmt.Println("=====================")
		fmt.Println(lt)
		fmt.Println(gt)*/
		nextMin, nextMax = 1e9+1, 0
		for _, nowIndex := range queue {
			var nowMin, nowMax int64 = 1e9 + 1, 0
			now := nodes[nowIndex]
			now.vis = true
			for _, index := range now.edges {
				n := nodes[index]
				if n.vis {
					continue
				}
				if n.data < nowMin {
					nowMin = n.data
				}
				if n.data > nowMax {
					nowMax = n.data
				}
				n.parent = nowIndex
				next = append(next, index)
			}
			now.f = calc(nodes, lt, gt, nowIndex, min, max)
			//fmt.Println(nowIndex, "f:", now.f)
			if res < now.f {
				res = now.f
			}
			//fmt.Println("lt", bv{b: nowMax, v: nowMax + now.f})
			//fmt.Println("gt", bv{b: nowMin, v: now.f - nowMin})
			nextLt = append(nextLt, bv{b: nowMax, v: nowMax + now.f})
			nextGt = append(nextGt, bv{b: nowMin, v: now.f - nowMin})

			if nowMin < nextMin {
				nextMin = nowMin
			}
			if nowMax > nextMax {
				nextMax = nowMax
			}
			count++
		}
		// sort the nextLt/nextGt into an order that the smallest range is at the first,
		// and v in dereasing order
		sort.Slice(nextLt, func(i, j int) bool {
			if nextLt[i].b == nextLt[j].b {
				return nextLt[i].v > nextLt[j].v
			}
			return nextLt[i].b < nextLt[j].b
		})
		sort.Slice(nextGt, func(i, j int) bool {
			if nextGt[i].b == nextGt[j].b {
				return nextGt[i].v > nextGt[j].v
			}
			return nextGt[i].b > nextGt[j].b
		})
		lt, gt = squash(nextLt), squash(nextGt)
		nextLt, nextGt = []bv{}, []bv{}
		//fmt.Println(queue, next)
		//fmt.Scanf("\n")
		queue, next = next, queue[:0]
		min, max = nextMin, nextMax
	}
	fmt.Println(res)
	if len(nodes) != count {
		fmt.Println(len(nodes), count)
		panic("not all visited")
	}
}

func main() {
	input := bufio.NewReader(os.Stdin)
	var t int
	fmt.Fscanln(input, &t)
	for ; t > 0; t-- {
		var n int
		_, err := fmt.Fscanln(input, &n)
		if err != nil {
			panic(err)
		}
		nodes := make([]*node, n)
		for i := range nodes {
			nodes[i] = new(node)
			nodes[i].parent = i // set parent = self, means uninitialized
		}
		for i := 1; i < n; i++ {
			var x int
			fmt.Fscan(input, &x)
			x--
			nodes[i].edges = append(nodes[i].edges, x)
			nodes[x].edges = append(nodes[x].edges, i)
		}
		/*for i := 0; i < n; i++ {
			fmt.Printf("%d: %v\n", i, nodes[i].edges)
		}*/
		fmt.Fscanf(input, "\n")
		for i := 1; i < n; i++ {
			fmt.Fscan(input, &nodes[i].data)
			if nodes[i].data > 1e9 {
				panic("invalid input")
			}
		}
		fmt.Fscanf(input, "\n")
		solve(nodes)
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
)

type node struct {
	index  int
	parent int
	edges  []int
	data   int64
	// min, max int64
	f   int64
	vis bool
}

func calcParent(p *node, data, min, max int64) int64 {
	v1, v2 := data-min, max-data
	if v1 < v2 {
		return v2 + p.f
	}
	return v1 + p.f
}

func calc(nodes []*node, lt, gt int64, index int, min, max int64) int64 {
	now := nodes[index]
	if now.parent == index {
		if index != 0 {
			panic("corrupted")
		}
		return 0
	}

	res := calcParent(nodes[now.parent], now.data, min, max)
	// fmt.Printf("%d - parent value: %d\n", index, res)

	if v := lt - now.data; v > res {
		// fmt.Printf("%d - lt value: %d\n", index, v)
		res = v
	}
	if v := now.data + gt; v > res {
		// fmt.Printf("%d - gt value: %d\n", index, v)
		res = v
	}

	return res
}

func solve(nodes []*node) {
	var (
		queue, next      []int
		maxLt, maxGt     int64
		res              int64 = -1
		min, max         int64
		nextMin, nextMax int64
		count            int
	)

	queue = []int{0}
	nodes[0].vis = true

	for len(queue) != 0 {
		// fmt.Println("=====================")
		// fmt.Printf("maxLt&Gt: %d, %d\n", maxLt, maxGt)
		nextMin, nextMax = 1e9+1, 0
		var nextMaxGt, nextMaxLt int64 = -1e9 - 1, -1e9 - 1
		for _, nowIndex := range queue {
			var nowMin, nowMax int64 = 1e9 + 1, 0
			now := nodes[nowIndex]
			now.vis = true
			for _, index := range now.edges {
				n := nodes[index]
				if n.vis {
					continue
				}
				if n.data < nowMin {
					nowMin = n.data
				}
				if n.data > nowMax {
					nowMax = n.data
				}
				n.parent = nowIndex
				next = append(next, index)
			}
			now.f = calc(nodes, maxLt, maxGt, nowIndex, min, max)
			// fmt.Println(nowIndex, "f:", now.f)
			if res < now.f {
				res = now.f
			}

			if v := nowMax + now.f; v > nextMaxLt {
				nextMaxLt = v
			}

			if v := now.f - nowMin; v > nextMaxGt {
				nextMaxGt = v
			}

			if nowMin < nextMin {
				nextMin = nowMin
			}
			if nowMax > nextMax {
				nextMax = nowMax
			}
			count++
		}
		maxLt, maxGt = nextMaxLt, nextMaxGt

		queue, next = next, queue[:0]
		min, max = nextMin, nextMax
	}
	fmt.Println(res)
	if len(nodes) != count {
		fmt.Println(len(nodes), count)
		panic("not all visited")
	}
}

func main() {
	input := bufio.NewReader(os.Stdin)
	var t int
	fmt.Fscanln(input, &t)
	for ; t > 0; t-- {
		var n int
		_, err := fmt.Fscanln(input, &n)
		if err != nil {
			panic(err)
		}
		nodes := make([]*node, n)
		for i := range nodes {
			nodes[i] = new(node)
			nodes[i].parent = i // set parent = self, means uninitialized
		}
		for i := 1; i < n; i++ {
			var x int
			fmt.Fscan(input, &x)
			x--
			nodes[i].edges = append(nodes[i].edges, x)
			nodes[x].edges = append(nodes[x].edges, i)
		}
		/*for i := 0; i < n; i++ {
			fmt.Printf("%d: %v\n", i, nodes[i].edges)
		}*/
		fmt.Fscanf(input, "\n")
		for i := 1; i < n; i++ {
			fmt.Fscan(input, &nodes[i].data)
			if nodes[i].data > 1e9 {
				panic("invalid input")
			}
		}
		fmt.Fscanf(input, "\n")
		solve(nodes)
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type node struct {
	index  int
	parent int
	edges  []int
	data   int64
	// min, max int64
	f   int64
	vis bool
}

type bv struct {
	b, v int64
}

func calcParent(p *node, data, min, max int64) int64 {
	v1, v2 := data-min, max-data
	if v1 < v2 {
		return v2 + p.f
	}
	return v1 + p.f
}

func calc(nodes []*node, lt, gt []bv, index int, min, max int64) int64 {
	now := nodes[index]
	if now.parent == index {
		return 0
	}

	res := calcParent(nodes[now.parent], now.data, min, max)
	//fmt.Println(index, "parent", res)

	// Search returns the smallest i that f(i) is true
	// which means the tightest range that contains now.data
	pl := sort.Search(len(lt), func(i int) bool {
		return now.data <= lt[i].b
	})
	// actually given that we have <= in the test, it is impossible for
	// it to be out of range
	if pl < len(lt) {
		if v := lt[pl].v - now.data; v > res {
			res = v
		}
		//fmt.Println(index, "lt", lt[pl], lt[pl].v-now.data)
	}
	pg := sort.Search(len(gt), func(i int) bool {
		return now.data >= gt[i].b
	})
	if pg < len(gt) {
		if v := gt[pg].v + now.data; v > res {
			res = v
		}
		//fmt.Println(index, "gt", lt[pg], gt[pg].v+now.data)
	}
	return res
}

// warning: squash is destructive
// although this looks like o(n*n), it is actually o(n), as every elem is only
// pushed into the stack once and popped at most once.
func squash(x []bv) []bv {
	//fmt.Println("squash")
	//fmt.Println(x)
	var top int = 0
	for i := 1; i < len(x); i++ {
		if x[i].b == x[top].b {
			continue
			// save us some trouble as we already sort v in decreasing order
		}
		for top >= 0 && x[top].v < x[i].v {
			top--
		}
		top++
		x[top] = x[i]
	}
	//fmt.Println(top, x[:top+1])
	return x[:top+1]
}

func solve(nodes []*node) {
	var (
		queue, next      []int
		lt, gt           []bv //less than, greater than
		nextLt, nextGt   []bv
		res              int64 = -1
		min, max         int64
		nextMin, nextMax int64
		count            int
	)

	queue = []int{0}
	nodes[0].vis = true

	for len(queue) != 0 {
		/*fmt.Println("=====================")
		fmt.Println(lt)
		fmt.Println(gt)*/
		nextMin, nextMax = 1e9+1, 0
		for _, nowIndex := range queue {
			var nowMin, nowMax int64 = 1e9 + 1, 0
			now := nodes[nowIndex]
			now.vis = true
			for _, index := range now.edges {
				n := nodes[index]
				if n.vis {
					continue
				}
				if n.data < nowMin {
					nowMin = n.data
				}
				if n.data > nowMax {
					nowMax = n.data
				}
				n.parent = nowIndex
				next = append(next, index)
			}
			now.f = calc(nodes, lt, gt, nowIndex, min, max)
			//fmt.Println(nowIndex, "f:", now.f)
			if res < now.f {
				res = now.f
			}
			//fmt.Println(bv{b: nowMax, v: nowMax + now.f})
			//fmt.Println(bv{b: nowMin, v: now.f - nowMin})
			nextLt = append(nextLt, bv{b: nowMax, v: nowMax + now.f})
			nextGt = append(nextGt, bv{b: nowMin, v: now.f - nowMin})

			if nowMin < nextMin {
				nextMin = nowMin
			}
			if nowMax > nextMax {
				nextMax = nowMax
			}
			count++
		}
		// sort the nextLt/nextGt into an order that the smallest range is at the first,
		// and v in dereasing order
		sort.Slice(nextLt, func(i, j int) bool {
			if nextLt[i].b == nextLt[j].b {
				return nextLt[i].v > nextLt[i].v
			}
			return nextLt[i].b < nextLt[j].b
		})
		sort.Slice(nextGt, func(i, j int) bool {
			if nextGt[i].b == nextGt[j].b {
				return nextGt[i].v > nextGt[j].v
			}
			return nextGt[i].b > nextGt[j].b
		})
		lt, gt = squash(nextLt), squash(nextGt)
		nextLt, nextGt = []bv{}, []bv{}
		//fmt.Println(queue, next)
		//fmt.Scanf("\n")
		queue, next = next, queue[:0]
		min, max = nextMin, nextMax
	}
	fmt.Println(res)
	if len(nodes) != count {
		fmt.Println(len(nodes), count)
		panic("not all visited")
	}
}

func main() {
	input := bufio.NewReader(os.Stdin)
	var t int
	fmt.Fscanln(input, &t)
	for ; t > 0; t-- {
		var n int
		_, err := fmt.Fscanln(input, &n)
		if err != nil {
			panic(err)
		}
		nodes := make([]*node, n)
		for i := range nodes {
			nodes[i] = new(node)
		}
		for i := 1; i < n; i++ {
			var x int
			fmt.Fscan(input, &x)
			x--
			nodes[i].edges = append(nodes[i].edges, x)
			nodes[x].edges = append(nodes[x].edges, i)
			nodes[i].parent = i // set parent = self, means uninitialized
		}
		/*for i := 0; i < n; i++ {
			fmt.Printf("%d: %v\n", i, nodes[i].edges)
		}*/
		fmt.Fscanf(input, "\n")
		for i := 1; i < n; i++ {
			fmt.Fscan(input, &nodes[i].data)
			if nodes[i].data > 1e9 {
				panic("invalid input")
			}
		}
		fmt.Fscanf(input, "\n")
		solve(nodes)
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type node struct {
	index  int
	parent int
	edges  []int
	data   int64
	// min, max int64
	f   int64
	vis bool
}

type bv struct {
	b, v int64
}

func calcParent(p *node, data, min, max int64) int64 {
	v1, v2 := data-min, max-data
	if v1 < v2 {
		return v2 + p.f
	}
	return v1 + p.f
}

func calc(nodes []*node, lt, gt []bv, index int, min, max int64) int64 {
	now := nodes[index]
	if now.parent == index {
		return 0
	}

	res := calcParent(nodes[now.parent], now.data, min, max)
	//fmt.Println(index, "parent", res)

	pl := sort.Search(len(lt), func(i int) bool {
		return now.data <= lt[i].b
	})
	if pl < len(lt) {
		if v := lt[pl].v - now.data; v > res {
			res = v
		}
		//fmt.Println(index, "lt", lt[pl], lt[pl].v-now.data)
	}
	pg := sort.Search(len(gt), func(i int) bool {
		return now.data >= gt[i].b
	})
	if pg < len(gt) {
		if v := gt[pg].v + now.data; v > res {
			res = v
		}
		//fmt.Println(index, "gt", lt[pg], gt[pg].v+now.data)
	}
	return res
}

// warning: squash is destructive
// although this looks like o(n*n), it is actually o(n), as every elem is only
// pushed into the stack once and popped at most once.
func squash(x []bv) []bv {
	//fmt.Println("squash")
	//fmt.Println(x)
	var top int = 0
	for i := 1; i < len(x); i++ {
		if x[i].b == x[top].b {
			continue
			// save us some trouble as we already sort v in decreasing order
		}
		for top >= 0 && x[top].v < x[i].v {
			top--
		}
		top++
		x[top] = x[i]
	}
	//fmt.Println(top, x[:top+1])
	return x[:top+1]
}

func solve(nodes []*node) {
	var (
		queue, next      []int
		lt, gt           []bv //less than, greater than
		nextLt, nextGt   []bv
		res              int64 = -1
		min, max         int64
		nextMin, nextMax int64
	)

	queue = []int{0}
	nodes[0].vis = true

	for len(queue) != 0 {
		/*fmt.Println("=====================")
		fmt.Println(lt)
		fmt.Println(gt)*/
		nextMin, nextMax = 1e9+1, 0
		for _, nowIndex := range queue {
			var nowMin, nowMax int64 = 1e9 + 1, 0
			now := nodes[nowIndex]
			now.vis = true
			for _, index := range now.edges {
				n := nodes[index]
				if n.vis {
					continue
				}
				if n.data < nowMin {
					nowMin = n.data
				}
				if n.data > nowMax {
					nowMax = n.data
				}
				n.parent = nowIndex
				next = append(next, index)
			}
			now.f = calc(nodes, lt, gt, nowIndex, min, max)
			//fmt.Println(nowIndex, "f:", now.f)
			if res < now.f {
				res = now.f
			}
			//fmt.Println(bv{b: nowMax, v: nowMax + now.f})
			//fmt.Println(bv{b: nowMin, v: now.f - nowMin})
			nextLt = append(nextLt, bv{b: nowMax, v: nowMax + now.f})
			nextGt = append(nextGt, bv{b: nowMin, v: now.f - nowMin})

			if nowMin < nextMin {
				nextMin = nowMin
			}
			if nowMax > nextMax {
				nextMax = nowMax
			}
		}
		// sort the nextLt/nextGt into an order that the smallest range is at the first,
		// and v in dereasing order
		sort.Slice(nextLt, func(i, j int) bool {
			if nextLt[i].b == nextLt[j].b {
				return nextLt[i].v > nextLt[i].v
			}
			return nextLt[i].b < nextLt[j].b
		})
		sort.Slice(nextGt, func(i, j int) bool {
			if nextGt[i].b == nextGt[j].b {
				return nextGt[i].v > nextGt[j].v
			}
			return nextGt[i].b > nextGt[j].b
		})
		lt, gt = squash(nextLt), squash(nextGt)
		nextLt, nextGt = []bv{}, []bv{}
		//fmt.Println(queue, next)
		//fmt.Scanf("\n")
		queue, next = next, queue[:0]
		min, max = nextMin, nextMax
	}
	fmt.Println(res)
}

func main() {
	input := bufio.NewReader(os.Stdin)
	var t int
	fmt.Fscanln(input, &t)
	for ; t > 0; t-- {
		var n int
		_, err := fmt.Fscanln(input, &n)
		if err != nil {
			panic(err)
		}
		nodes := make([]*node, n)
		for i := range nodes {
			nodes[i] = new(node)
		}
		for i := 1; i < n; i++ {
			var x int
			fmt.Fscan(input, &x)
			x--
			nodes[i].edges = append(nodes[i].edges, x)
			nodes[x].edges = append(nodes[x].edges, i)
			nodes[i].parent = i // set parent = self, means uninitialized
		}
		/*for i := 0; i < n; i++ {
			fmt.Printf("%d: %v\n", i, nodes[i].edges)
		}*/
		fmt.Fscanf(input, "\n")
		for i := 1; i < n; i++ {
			fmt.Fscan(input, &nodes[i].data)
			if nodes[i].data > 1e9 {
				panic("invalid input")
			}
		}
		fmt.Fscanf(input, "\n")
		solve(nodes)
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type node struct {
	index  int
	parent int
	edges  []int
	data   int64
	// min, max int64
	f   int64
	vis bool
}

type bv struct {
	b, v int64
}

func calcParent(p *node, data, min, max int64) int64 {
	v1, v2 := data-min, max-data
	if v1 < v2 {
		return v2 + p.f
	}
	return v1 + p.f
}

func calc(nodes []*node, lt, gt []bv, index int, min, max int64) int64 {
	now := nodes[index]
	if now.parent == index {
		return 0
	}

	res := calcParent(nodes[now.parent], now.data, min, max)
	//fmt.Println(index, "parent", res)

	pl := sort.Search(len(lt), func(i int) bool {
		return now.data <= lt[i].b
	})
	if pl < len(lt) {
		if v := lt[pl].v - now.data; v > res {
			res = v
		}
		//fmt.Println(index, "lt", lt[pl], lt[pl].v-now.data)
	}
	pg := sort.Search(len(gt), func(i int) bool {
		return now.data >= gt[i].b
	})
	if pg < len(gt) {
		if v := gt[pg].v + now.data; v > res {
			res = v
		}
		//fmt.Println(index, "gt", lt[pg], gt[pg].v+now.data)
	}
	return res
}

// warning: squash is destructive
// although this looks like o(n*n), it is actually o(n), as every elem is only
// pushed into the stack once and popped at most once.
func squash(x []bv) []bv {
	//fmt.Println("squash")
	//fmt.Println(x)
	var top int = 0
	for i := 1; i < len(x); i++ {
		if x[i].b == x[top].b {
			continue
			// save us some trouble as we already sort v in decreasing order
		}
		for top >= 0 && x[top].v < x[i].v {
			top--
		}
		top++
		x[top] = x[i]
	}
	//fmt.Println(top, x[:top+1])
	return x[:top+1]
}

func solve(nodes []*node) {
	var (
		queue, next      []int
		lt, gt           []bv //less than, greater than
		nextLt, nextGt   []bv
		res              int64 = -1
		min, max         int64
		nextMin, nextMax int64
	)

	queue = []int{0}
	nodes[0].vis = true

	for len(queue) != 0 {
		/*fmt.Println("=====================")
		fmt.Println(lt)
		fmt.Println(gt)*/
		nextMin, nextMax = 1e9+1, 0
		for _, nowIndex := range queue {
			var nowMin, nowMax int64 = 1e9 + 1, 0
			now := nodes[nowIndex]
			now.vis = true
			for _, index := range now.edges {
				n := nodes[index]
				if n.vis {
					continue
				}
				if n.data < nowMin {
					nowMin = n.data
				}
				if n.data > nowMax {
					nowMax = n.data
				}
				n.parent = nowIndex
				next = append(next, index)
			}
			now.f = calc(nodes, lt, gt, nowIndex, min, max)
			//fmt.Println(nowIndex, "f:", now.f)
			if res < now.f {
				res = now.f
			}
			//fmt.Println(bv{b: nowMax, v: nowMax + now.f})
			//fmt.Println(bv{b: nowMin, v: now.f - nowMin})
			nextLt = append(nextLt, bv{b: nowMax, v: nowMax + now.f})
			nextGt = append(nextGt, bv{b: nowMin, v: now.f - nowMin})

			if nowMin < nextMin {
				nextMin = nowMin
			}
			if nowMax > nextMax {
				nextMax = nowMax
			}
		}
		// sort the nextLt/nextGt into an order that the smallest range is at the first,
		// and v in dereasing order
		sort.Slice(nextLt, func(i, j int) bool {
			if nextLt[i].b == nextLt[j].b {
				return nextLt[i].v > nextLt[i].v
			}
			return nextLt[i].b < nextLt[j].b
		})
		sort.Slice(nextGt, func(i, j int) bool {
			if nextGt[i].b == nextGt[j].b {
				return nextGt[i].v > nextGt[j].v
			}
			return nextGt[i].b > nextGt[j].b
		})
		lt, gt = squash(nextLt), squash(nextGt)
		nextLt, nextGt = []bv{}, []bv{}
		//fmt.Println(queue, next)
		//fmt.Scanf("\n")
		queue, next = next, queue[:0]
		min, max = nextMin, nextMax
	}
	fmt.Println(res)
}

func main() {
	input := bufio.NewReader(os.Stdin)
	var t int
	fmt.Fscanln(input, &t)
	for ; t > 0; t-- {
		var n int
		_, err := fmt.Fscanln(input, &n)
		if err != nil {
			panic(err)
		}
		nodes := make([]*node, n)
		for i := range nodes {
			nodes[i] = new(node)
		}
		for i := 1; i < n; i++ {
			var x int
			fmt.Fscan(input, &x)
			x--
			nodes[i].edges = append(nodes[i].edges, x)
			nodes[x].edges = append(nodes[x].edges, i)
			nodes[i].parent = i // set parent = self, means uninitialized
		}
		/*for i := 0; i < n; i++ {
			fmt.Printf("%d: %v\n", i, nodes[i].edges)
		}*/
		fmt.Fscanf(input, "\n")
		for i := 1; i < n; i++ {
			fmt.Fscan(input, &nodes[i].data)
		}
		fmt.Fscanf(input, "\n")
		solve(nodes)
	}
}

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
	"sort"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	var buf bytes.Buffer

	tc := readNum(reader)

	for tc > 0 {
		tc--
		n := readNum(reader)
		P := readNNums(reader, n-1)
		A := readNNums(reader, n-1)
		res := solve(n, P, A)
		buf.WriteString(fmt.Sprintf("%d\n", res))
	}

	fmt.Print(buf.String())
}

func readInt(bytes []byte, from int, val *int) int {
	i := from
	sign := 1
	if bytes[i] == '-' {
		sign = -1
		i++
	}
	tmp := 0
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + int(bytes[i]-'0')
		i++
	}
	*val = tmp * sign
	return i
}

func readNum(reader *bufio.Reader) (a int) {
	bs, _ := reader.ReadBytes('\n')
	readInt(bs, 0, &a)
	return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
	res := readNNums(reader, 2)
	a, b = res[0], res[1]
	return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
	res := readNNums(reader, 3)
	a, b, c = res[0], res[1], res[2]
	return
}

func readNNums(reader *bufio.Reader, n int) []int {
	res := make([]int, n)
	x := 0
	bs, _ := reader.ReadBytes('\n')
	for i := 0; i < n; i++ {
		for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
			x++
		}
		x = readInt(bs, x, &res[i])
	}
	return res
}

func readUint64(bytes []byte, from int, val *uint64) int {
	i := from

	var tmp uint64
	for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
		tmp = tmp*10 + uint64(bytes[i]-'0')
		i++
	}
	*val = tmp

	return i
}

const N_INF = -(1 << 29)

func solve(n int, P []int, A []int) int64 {

	pp := make([]int, n)
	copy(pp[1:], P)

	g := NewGraph(n, n+10)

	for i := 1; i < n; i++ {
		pp[i]--
		g.AddEdge(pp[i], i)
	}

	D := make([]int, n)
	var mx int
	var dfs func(u int)
	dfs = func(u int) {
		mx = max(mx, D[u])
		for i := g.nodes[u]; i > 0; i = g.next[i] {
			v := g.to[i]
			D[v] = D[u] + 1
			dfs(v)
		}
	}
	dfs(0)
	mx++
	C := make([]int, mx)
	for i := 0; i < n; i++ {
		C[D[i]]++
	}
	L := make([][]Pair, mx)
	for i := 0; i < mx; i++ {
		L[i] = make([]Pair, 0, C[i])
	}
	for i := 1; i < n; i++ {
		L[D[i]] = append(L[D[i]], Pair{A[i-1], i})
	}

	for i := 0; i < mx; i++ {
		sort.Sort(Pairs(L[i]))
	}
	dp := make([]int64, n)

	for i := 1; i < mx; i++ {
		cur := L[i]
		// if place blue at j'th node in this level, find another best red
		// because all nodes before j < A[j], so the best is A[j] - A[k] + dp[P[k]]
		// let best is dp[P[k]] - A[k]
		var best int64 = N_INF
		for _, p := range cur {
			j := p.second
			dp[j] = max2(dp[j], best+int64(A[j-1]))
			best = max2(best, dp[pp[j]]-int64(A[j-1]))
		}
		// A[k] - A[j] + dp[pp[k]]
		best = N_INF
		for k := len(cur) - 1; k >= 0; k-- {
			p := cur[k]
			j := p.second
			dp[j] = max2(dp[j], best-int64(A[j-1]))
			best = max2(best, int64(A[j-1])+dp[pp[j]])
		}
		// a0 or an is blue
		a0 := cur[0].first
		an := cur[len(cur)-1].first
		for _, p := range cur {
			j := p.second
			//if make j as red, then it's parent has to be red
			dp[j] = max2(dp[j], int64(p.first-a0)+dp[pp[j]])
			dp[j] = max2(dp[j], int64(an-p.first)+dp[pp[j]])
		}
	}

	var res int64

	for _, p := range L[mx-1] {
		res = max2(res, dp[p.second])
	}

	return res
}

type Pair struct {
	first, second int
}

type Pairs []Pair

func (this Pairs) Len() int {
	return len(this)
}

func (this Pairs) Less(i, j int) bool {
	return this[i].first < this[j].first
}

func (this Pairs) Swap(i, j int) {
	this[i], this[j] = this[j], this[i]
}

func max(a, b int) int {
	if a >= b {
		return a
	}
	return b
}

func max2(a, b int64) int64 {
	if a >= b {
		return a
	}
	return b
}

type Graph struct {
	nodes []int
	next  []int
	to    []int
	cur   int
}

func NewGraph(n int, e int) *Graph {
	nodes := make([]int, n)
	next := make([]int, e)
	to := make([]int, e)
	return &Graph{nodes, next, to, 0}
}

func (g *Graph) AddEdge(u, v int) {
	g.cur++
	g.next[g.cur] = g.nodes[u]
	g.nodes[u] = g.cur
	g.to[g.cur] = v
}