#include <bits/stdc++.h>   using namespace std;   const int maxn = 200001;   int n;   int d[maxn], anc[maxn][18], p[maxn];   array<int, 2> tree[maxn * 4];   int jua(int x, int y) {     int dd = d[y] - d[x];     for (int i = 17; i >= 0; i--) {       if (dd >= 1 << i) {         y = anc[y][i];         dd -= (1 << i);       }     }     return x == y;   }   int lca(int x, int y) {     if (d[x] < d[y]) swap(x, y);     int dd = d[x] - d[y];     for (int i = 17; i >= 0; i--) {       if (dd >= 1 << i) {         x = anc[x][i];         dd -= (1 << i);       }     }     if (x == y) return x;     for (int i = 17; i >= 0; i--) {       if (anc[x][i] != anc[y][i]) {         x = anc[x][i];         y = anc[y][i];       }     }     return anc[x][0];   }   void cmb2(array<int, 2> &p0, int x) {     if (p0[0] == -1 || x == -1) {       p0[0] = -1;       p0[1] = -1;       return;     }     if (d[p0[0]] > d[p0[1]]) swap(p0[0], p0[1]);     if (jua(p0[0], p0[1])) {       if (d[x] >= d[p0[0]] && d[x] <= d[p0[1]] && jua(x, p0[1])) {         return;       }       if (jua(p0[1], x)) {         p0[1] = x;         return;       }       int c = lca(p0[1], x);       if (d[c] > d[p0[0]]) {         p0[0] = p0[1] = -1;         return;       }       p0[0] = x;     } else {       int c = lca(p0[0], p0[1]);       if (d[x] >= d[c] && (jua(x, p0[0]) || jua(x, p0[1]))) {         return;       }       if (jua(p0[0], x)) {         p0[0] = x;         return;       }       if (jua(p0[1], x)) {         p0[1] = x;         return;       }       p0[0] = p0[1] = -1;     }     return;   }   array<int, 2> cmb(array<int, 2> p1, array<int, 2> p2) {     cmb2(p1, p2[0]);     cmb2(p1, p2[1]);     return p1;   }   void update(int v, array<int, 2> pp, int k, int l, int r) {     if (l == r) {       tree[k] = pp;       return;     }     int mid = (l + r) / 2;     if (v <= mid)       update(v, pp, k * 2, l, mid);     else       update(v, pp, k * 2 + 1, mid + 1, r);     tree[k] = cmb(tree[k * 2], tree[k * 2 + 1]);   }   int query(int k, int l, int r, array<int, 2> p) {     array<int, 2> t = tree[k];     if (l) t = cmb(t, p);     if (t[0] != -1) {       return r + 1;     }     if (l == r) return l;     int mid = (l + r) / 2;     array<int, 2> tt = tree[k * 2];     if (l) tt = cmb(tt, p);     if (tt[0] != -1)       return query(k * 2 + 1, mid + 1, r, tt);     else       return query(k * 2, l, mid, p);   }   int main() {     ios_base::sync_with_stdio(0);     cin.tie(0);     cin >> n;     for (int i = 0; i < n; i++) {       cin >> p[i];     }     memset(anc[0], -1, sizeof(anc[0]));     anc[1][0] = -1;     d[1] = 1;     for (int i = 1; i < n; i++) {       int x;       cin >> x, x--;       anc[i][0] = x;       d[i] = d[x] + 1;     }     for (int i = 1; i < n; i++) {       for (int j = 0; j < 17; j++) {         if (anc[i][j] != -1)           anc[i][j + 1] = anc[anc[i][j]][j];         else           anc[i][j + 1] = -1;       }     }     for (int i = 0; i < n; i++) {       update(p[i], {i, i}, 1, 0, n - 1);     }     int q;     cin >> q;     while (q--) {       int ju;       cin >> ju;       if (ju == 1) {         int x, y;         cin >> x >> y;         x--, y--;         swap(p[x], p[y]);         update(p[x], {x, x}, 1, 0, n - 1);         update(p[y], {y, y}, 1, 0, n - 1);       } else {         cout << query(1, 0, n - 1, {}) << endl;       }     }   }