#include <bits/stdc++.h>   using namespace std;   struct edge {     int v, nxt;   } e[200005 << 1];   int top = 1;   int head[200005];   void Add_Edge(int u, int v) {     e[++top] = edge{v, head[u]};     head[u] = top;   }   int n;   int a[200005], par[200005][21], dep[200005], size[200005];   void dfs(int u, int fa) {     size[u] = 1;     par[u][0] = fa;     dep[u] = dep[fa] + 1;     for (register int i = head[u]; i; i = e[i].nxt) {       int v = e[i].v;       dfs(v, u);       size[u] += size[v];     }   }   void Init() {     for (register int j = 1; j <= 20; ++j)       for (register int i = 1; i <= n; ++i) par[i][j] = par[par[i][j - 1]][j - 1];   }   int LCA(int u, int v) {     if (dep[u] < dep[v]) swap(u, v);     int dis = dep[u] - dep[v];     for (register int i = 20; i >= 0; --i)       if (dis & (1 << i)) u = par[u][i];     if (u == v) return u;     for (register int i = 20; i >= 0; --i)       if (par[u][i] ^ par[v][i]) u = par[u][i], v = par[v][i];     return par[u][0];   }   int dist(int a, int b) {     int lca = LCA(a, b);     return dep[a] + dep[b] - dep[lca] * 2;   }   struct Node {     int x, y;   };   Node tree[200005 << 2];   Node merge(Node a, int b) {     if (a.x < 0 || b < 0) return Node{-1, -1};     int aa = a.x, bb = a.y;     int d1 = dist(aa, b);     int d2 = dist(bb, b);     int d3 = dist(bb, aa);     if (d1 + d2 == d3) return a;     if (d1 + d3 == d2) return Node{b, bb};     if (d2 + d3 == d1) return Node{aa, b};     return Node{-1, -1};   }   Node Merge(Node a, Node b) {     if (a.x < 0 || b.x < 0) return Node{-1, -1};     Node up1 = merge(a, b.x);     if (up1.x < 0)       return Node{-1, -1};     else       return merge(up1, b.y);   }   void Pushup(int i) { tree[i] = Merge(tree[i << 1], tree[i << 1 | 1]); }   int Index[200005];   void build(int i, int l, int r) {     if (l == r) return tree[i] = Node{Index[l], Index[l]}, void();     int mid = (l + r) >> 1;     build(i << 1, l, mid);     build(i << 1 | 1, mid + 1, r);     Pushup(i);   }   void update(int i, int l, int r, int res) {     if (l == r) return tree[i] = Node{Index[l], Index[l]}, void();     int mid = (l + r) >> 1;     if (res <= mid)       update(i << 1, l, mid, res);     else       update(i << 1 | 1, mid + 1, r, res);     Pushup(i);   }   int query(Node &mq, int i, int l, int r) {     if (tree[i].x >= 0) {       if (mq.x < 0) return mq = tree[i], r + 1;       Node up1 = Merge(mq, tree[i]);       if (up1.x >= 0) return mq = up1, r + 1;     }     if (l == r) return l;     int mid = (l + r) >> 1;     int res = query(mq, i << 1, l, mid);     if (res <= mid)       return res;     else       return query(mq, i << 1 | 1, mid + 1, r);   }   int read() {     int x = 0;     char c = getchar();     int f = 1;     while (c <  0  || c >  9 ) {       if (c ==  - ) f = -f;       c = getchar();     }     while (c >=  0  && c <=  9 ) {       x = (x << 3) + (x << 1) + c -  0 ;       c = getchar();     }     return x * f;   }   void write(int x) {     if (x < 0) {       x = -x;       putchar( - );     }     if (x > 9) write(x / 10);     putchar(x % 10 +  0 );   }   signed main() {     n = read();     for (register int i = 1; i <= n; ++i) {       a[i] = read() + 1;       Index[a[i]] = i;     }     for (register int i = 2; i <= n; ++i) {       int fa = read();       Add_Edge(fa, i);     }     dfs(1, 1);     Init();     build(1, 1, n);     int q = read();     for (register int i = 1; i <= q; ++i) {       int type = read();       if (type == 1) {         int x = read(), y = read();         swap(Index[a[x]], Index[a[y]]);         swap(a[x], a[y]);         update(1, 1, n, a[x]);         update(1, 1, n, a[y]);       } else {         Node mq = Node{-1, -1};         int Ans = query(mq, 1, 1, n);         write(Ans - 1), putchar(  n );       }     }     return 0;   }