← Home
```go
package main

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

type FastScanner struct {
	r *bufio.Reader
}

func NewFastScanner() *FastScanner {
	return &FastScanner{r: bufio.NewReaderSize(os.Stdin, 1<<20)}
}

func (fs *FastScanner) NextInt() int {
	sign := 1
	val := 0
	c, _ := fs.r.ReadByte()
	for (c < '0' || c > '9') && c != '-' {
		c, _ = fs.r.ReadByte()
	}
	if c == '-' {
		sign = -1
		c, _ = fs.r.ReadByte()
	}
	for c >= '0' && c <= '9' {
		val = val*10 + int(c-'0')
		c, _ = fs.r.ReadByte()
	}
	return val * sign
}

type SegTree struct {
	n    int
	minv []int
	maxv []int
	lz   []int
}

func NewSegTree(n int, base []int) *SegTree {
	st := &SegTree{
		n:    n,
		minv: make([]int, 4*n),
		maxv: make([]int, 4*n),
		lz:   make([]int, 4*n),
	}
	st.build(1, 1, n, base)
	return st
}

func (st *SegTree) build(p, l, r int, base []int) {
	if l == r {
		val := base[l]
		st.minv[p] = val
		st.maxv[p] = val
		return
	}
	m := (l + r) >> 1
	st.build(p<<1, l, m, base)
	st.build(p<<1|1, m+1, r, base)
	st.pull(p)
}

func (st *SegTree) pull(p int) {
	if st.minv[p<<1] < st.minv[p<<1|1] {
		st.minv[p] = st.minv[p<<1]
	} else {
		st.minv[p] = st.minv[p<<1|1]
	}
	if st.maxv[p<<1] > st.maxv[p<<1|1] {
		st.maxv[p] = st.maxv[p<<1]
	} else {
		st.maxv[p] = st.maxv[p<<1|1]
	}
}

func (st *SegTree) apply(p, v int) {
	st.minv[p] += v
	st.maxv[p] += v
	st.lz[p] += v
}

func (st *SegTree) push(p int) {
	if st.lz[p] != 0 {
		st.apply(p<<1, st.lz[p])
		st.apply(p<<1|1, st.lz[p])
		st.lz[p] = 0
	}
}

func (st *SegTree) add(p, l, r, ql, qr, v int) {
	if ql > r || qr < l {
		return
	}
	if ql <= l && r <= qr {
		st.apply(p, v)
		return
	}
	st.push(p)
	m := (l + r) >> 1
	st.add(p<<1, l, m, ql, qr, v)
	st.add(p<<1|1, m+1, r, ql, qr, v)
	st.pull(p)
}

func (st *SegTree) Add(l, r, v int) {
	if l > r {
		return
	}
	st.add(1, 1, st.n, l, r, v)
}

func (st *SegTree) GetMin() int { return st.minv[1] }
func (st *SegTree) GetMax() int { return st.maxv[1] }

func main() {
	in := NewFastScanner()
	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	defer out.Flush()

	t := in.NextInt()
	for ; t > 0; t-- {
		n := in.NextInt()
		q := in.NextInt()

		children := make([][]int, n+1)
		parent := make([]int, n+1)
		parent[1] = 0
		for i := 2; i <= n; i++ {
			pv := in.NextInt()
			parent[i] = pv
			children[pv] = append(children[pv], i)
		}

		pArr := make([]int, n+1)
		pos := make([]int, n+1)
		for i := 1; i <= n; i++ {
			v := in.NextInt()
			pArr[i] = v
			pos[v] = i
		}

		const LOG = 20
		up := make([][]int, LOG)
		for i := 0; i < LOG; i++ {
			up[i] = make([]int, n+1)
		}
		depth := make([]int, n+1)
		size := make([]int, n+1)
		tin := make([]int, n+1)
		tout := make([]int, n+1)
		heavy := make([]int, n+1)

		type Item struct {
			v, st int
		}
		timer := 0
		stack := make([]Item, 0, 2*n)
		stack = append(stack, Item{1, 0})
		up[0][1] = 0
		depth[1] = 0
		for len(stack) > 0 {
			it := stack[len(stack)-1]
			stack = stack[:len(stack)-1]
			v := it.v
			if it.st == 0 {
				tin[v] = timer + 1
				timer++
				stack = append(stack, Item{v, 1})
				for i := len(children[v]) - 1; i >= 0; i-- {
					u := children[v][i]
					depth[u] = depth[v] + 1
					up[0][u] = v
					stack = append(stack, Item{u, 0})
				}
			} else {
				size[v] = 1
				maxsz := 0
				hc := 0
				for _, u := range children[v] {
					size[v] += size[u]
					if size[u] > maxsz {
						maxsz = size[u]
						hc = u
					}
				}
				heavy[v] = hc
				tout[v] = timer
			}
		}
		for k := 1; k < LOG; k++ {
			for v := 1; v <= n; v++ {
				m := up[k-1][v]
				if m != 0 {
					up[k][v] = up[k-1][m]
				}
			}
		}

		head := make([]int, n+1)
		posH := make([]int, n+1)
		cur := 0
		type Pair struct{ v, h int }
		st2 := make([]Pair, 0, n)
		st2 = append(st2, Pair{1, 1})
		for len(st2) > 0 {
			pr := st2[len(st2)-1]
			st2 = st2[:len(st2)-1]
			v := pr.v
			h := pr.h
			for v != 0 {
				head[v] = h
				posH[v] = cur + 1
				cur++
				hc := heavy[v]
				for i := len(children[v]) - 1; i >= 0; i-- {
					u := children[v][i]
					if u == hc {
						continue
					}
					st2 = append(st2, Pair{u, u})
				}
				v = hc
			}
		}

		base := make([]int, n+1)
		for v := 1; v <= n; v++ {
			base[posH[v]] = size[v] - 1
		}
		seg := NewSegTree(n, base)

		isAnc := func(a, b int) bool { return a != 0 && tin[a] <= tin[b] && tout[b] <= tout[a] }
		lca := func(a, b int) int {
			if isAnc(a, b) {
				return a
			}
			if isAnc(b, a) {
				return b
			}
			u := a
			for k := LOG - 1; k >= 0; k-- {
				w := up[k][u]
				if w != 0 && !isAnc(w, b) {
					u = w
				}
			}
			return up[0][u]
		}
		var pathAdd func(u, v, d int)
		pathAdd = func(u, v, d int) {
			for head[u] != head[v] {
				if depth[head[u]] < depth[head[v]] {
					u, v = v, u
				}
				seg.Add(posH[head[u]], posH[u], d)
				u = up[0][head[u]]
			}
			if depth[u] < depth[v] {
				u, v = v, u
			}
			seg.Add(posH[v], posH[u], d)
		}

		for i := 2; i <= n; i++ {
			w := lca(pArr[i-1], pArr[i])
			pathAdd(w, 1, -1)
		}

		okFirst := make([]bool, n+1)
		badFirst := 0
		for i := 1; i <= n; i++ {
			node := pArr[i]
			cond := false
			if i == 1 {
				cond = true
			} else {
				prev := pArr[i-1]
				if !(tin[node] <= tin[prev] && tout[prev] <= tout[node]) {
					cond = true
				}
			}
			okFirst[node] = cond
			if !cond {
				badFirst++
			}
		}

		for ; q > 0; q-- {
			x := in.NextInt()
			y := in.NextInt()
			if x == y {
				if badFirst == 0 && seg.GetMin() == 0 && seg.GetMax() == 0 {
					fmt.Fprintln(out, "YES")
				} else {
					fmt.Fprintln(out, "NO")
				}
				continue
			}
			if x > y {
				x, y = y, x
			}
			idxs := make([]int, 0, 4)
			tryAdd := func(i int) {
				if i < 1 || i >= n {
					return
				}
				for _, v := range idxs {
					if v == i {
						return
					}
				}
				idxs = append(idxs, i)
			}
			tryAdd(x - 1)
			tryAdd(x)
			tryAdd(y - 1)
			tryAdd(y)

			for _, i := range idxs {
				w := lca(pArr[i], pArr[i+1])
				pathAdd(w, 1, +1)
			}

			u := pArr[x]
			v := pArr[y]
			pArr[x], pArr[y] = pArr[y], pArr[x]
			pos[u] = y
			pos[v] = x

			jset := make([]int, 0, 4)
			addj := func(i int) {
				if i < 1 || i > n {
					return
				}
				for _, t2 := range jset {
					if t2 == i {
						return
					}
				}
				jset = append(jset, i)
			}
			addj(x)
			addj(y)
			addj(x + 1)
			addj(y + 1)
			for _, i := range jset {
				node := pArr[i]
				old := okFirst[node]
				cond := false
				if i == 1 {
					cond = true
				} else {
					prev := pArr[i-1]
					if !(tin[node] <= tin[prev] && tout[prev] <= tout[node]) {
						cond = true
					}
				}
				if old != cond {
					okFirst[node] = cond
					if cond {
						badFirst--
					} else {
						badFirst++
					}
				}
			}

			for _, i := range idxs {
				w := lca(pArr[i], pArr[i+1])
				pathAdd(w, 1, -1)
			}

			if badFirst == 0 && seg.GetMin() == 0 && seg.GetMax() == 0 {
				fmt.Fprintln(out, "YES")
			} else {
				fmt.Fprintln(out, "NO")
			}
		}
	}
}
```