```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)
}
```