← Home
```go
package main

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

type Info struct {
	u int
	v int
}

var depth []int
var first []int
var lg []int
var st [][]int

var invalid = Info{-1, 0}

func lca(u, v int) int {
	l := first[u]
	r := first[v]
	if l > r {
		l, r = r, l
	}
	j := lg[r-l+1]
	x := st[j][l]
	y := st[j][r-(1<<j)+1]
	if depth[x] <= depth[y] {
		return x
	}
	return y
}

func dist(u, v int) int {
	w := lca(u, v)
	return depth[u] + depth[v] - 2*depth[w]
}

func merge(x, y Info) Info {
	if x.u == -1 || y.u == -1 {
		return invalid
	}
	if x.u == 0 {
		return y
	}
	if y.u == 0 {
		return x
	}

	a, b, c, d := x.u, x.v, y.u, y.v
	nodes := [4]int{a, b, c, d}

	d01 := dist(a, b)
	d02 := dist(a, c)
	d03 := dist(a, d)
	d12 := dist(b, c)
	d13 := dist(b, d)
	d23 := dist(c, d)

	bestI, bestJ, bestD := 0, 1, d01
	if d02 > bestD {
		bestI, bestJ, bestD = 0, 2, d02
	}
	if d03 > bestD {
		bestI, bestJ, bestD = 0, 3, d03
	}
	if d12 > bestD {
		bestI, bestJ, bestD = 1, 2, d12
	}
	if d13 > bestD {
		bestI, bestJ, bestD = 1, 3, d13
	}
	if d23 > bestD {
		bestI, bestJ, bestD = 2, 3, d23
	}

	var dm [4][4]int
	dm[0][1], dm[1][0] = d01, d01
	dm[0][2], dm[2][0] = d02, d02
	dm[0][3], dm[3][0] = d03, d03
	dm[1][2], dm[2][1] = d12, d12
	dm[1][3], dm[3][1] = d13, d13
	dm[2][3], dm[3][2] = d23, d23

	for i := 0; i < 4; i++ {
		if dm[bestI][i]+dm[i][bestJ] != bestD {
			return invalid
		}
	}

	return Info{nodes[bestI], nodes[bestJ]}
}

func update(tree []Info, size, pos, node int) {
	i := size + pos
	tree[i] = Info{node, node}
	for i > 1 {
		i >>= 1
		tree[i] = merge(tree[i<<1], tree[i<<1|1])
	}
}

func answer(tree []Info, size, n int) int {
	if tree[1].u != -1 {
		return n
	}
	acc := Info{0, 0}
	idx, l, r := 1, 0, size
	for idx < size {
		mid := (l + r) >> 1
		t := merge(acc, tree[idx<<1])
		if t.u != -1 {
			acc = t
			idx = idx<<1 | 1
			l = mid
		} else {
			idx <<= 1
			r = mid
		}
	}
	if l > n {
		return n
	}
	return l
}

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

	n := readInt()

	pNode := make([]int, n+1)
	nodeOfValue := make([]int, n)
	for i := 1; i <= n; i++ {
		v := readInt()
		pNode[i] = v
		nodeOfValue[v] = i
	}

	head := make([]int, n+1)
	for i := 1; i <= n; i++ {
		head[i] = -1
	}
	to := make([]int, n-1)
	next := make([]int, n-1)
	for i := 2; i <= n; i++ {
		p := readInt()
		e := i - 2
		to[e] = i
		next[e] = head[p]
		head[p] = e
	}

	depth = make([]int, n+1)
	first = make([]int, n+1)

	euler := make([]int, 0, 2*n-1)
	stackU := make([]int, 0, n)
	stackE := make([]int, 0, n)

	stackU = append(stackU, 1)
	stackE = append(stackE, head[1])
	euler = append(euler, 1)
	first[1] = 0

	for len(stackU) > 0 {
		top := len(stackU) - 1
		e := stackE[top]
		if e != -1 {
			stackE[top] = next[e]
			v := to[e]
			depth[v] = depth[stackU[top]] + 1
			first[v] = len(euler)
			euler = append(euler, v)
			stackU = append(stackU, v)
			stackE = append(stackE, head[v])
		} else {
			stackU = stackU[:top]
			stackE = stackE[:top]
			if top > 0 {
				euler = append(euler, stackU[top-1])
			}
		}
	}

	m := len(euler)
	lg = make([]int, m+1)
	for i := 2; i <= m; i++ {
		lg[i] = lg[i>>1] + 1
	}

	kmax := lg[m] + 1
	st = make([][]int, kmax)
	st[0] = make([]int, m)
	copy(st[0], euler)
	for k := 1; k < kmax; k++ {
		lenSeg := 1 << k
		half := lenSeg >> 1
		limit := m - lenSeg + 1
		row := make([]int, limit)
		prev := st[k-1]
		for i := 0; i < limit; i++ {
			x := prev[i]
			y := prev[i+half]
			if depth[x] <= depth[y] {
				row[i] = x
			} else {
				row[i] = y
			}
		}
		st[k] = row
	}

	size := 1
	for size < n {
		size <<= 1
	}
	tree := make([]Info, size<<1)
	for v := 0; v < n; v++ {
		node := nodeOfValue[v]
		tree[size+v] = Info{node, node}
	}
	for i := size - 1; i >= 1; i-- {
		tree[i] = merge(tree[i<<1], tree[i<<1|1])
	}

	q := readInt()
	out := make([]byte, 0, q*8)

	for ; q > 0; q-- {
		t := readInt()
		if t == 1 {
			i := readInt()
			j := readInt()
			if i != j {
				x := pNode[i]
				y := pNode[j]
				pNode[i], pNode[j] = y, x
				update(tree, size, x, j)
				update(tree, size, y, i)
			}
		} else {
			ans := answer(tree, size, n)
			out = strconv.AppendInt(out, int64(ans), 10)
			out = append(out, '\n')
		}
	}

	os.Stdout.Write(out)
}
```