#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000010;
int pla[MAXN], val[MAXN], n, head[MAXN], tot, q, ans;
int st[MAXN][20], pa[2 * MAXN], num, dep[MAXN], lg[MAXN], first[MAXN];
int a[5];
struct Tree {
  int l, r;
} tr[4 * MAXN], tmp;
struct Node {
  int to, nxt;
} e[2 * MAXN];
void add(int x, int y) {
  e[++tot] = (Node){y, head[x]};
  head[x] = tot;
}
void dfs(int now, int fa) {
  pa[++num] = now;
  first[now] = num;
  for (int i = head[now]; i; i = e[i].nxt) {
    int to = e[i].to;
    if (to != fa) {
      dep[to] = dep[now] + 1;
      dfs(to, now);
      pa[++num] = now;
    }
  }
}
void ST() {
  for (int i = 1; i <= num; ++i) st[i][0] = pa[i];
  for (int i = 1; i <= 20 && ((1 << i) <= num); ++i)
    for (int j = 1; j <= num; ++j)
      st[j][i] = (dep[st[j][i - 1]] < dep[st[j + (1 << (i - 1))][i - 1]])
                     ? st[j][i - 1]
                     : st[j + (1 << (i - 1))][i - 1];
}
int lca(int x, int y) {
  int Min = min(first[x], first[y]), Max = max(first[x], first[y]);
  int cha = Max - Min + 1;
  int z = dep[st[Min][lg[cha]]] < dep[st[Max - (1 << lg[cha]) + 1][lg[cha]]]
              ? st[Min][lg[cha]]
              : st[Max - (1 << lg[cha]) + 1][lg[cha]];
  return z;
}
bool check(int x, int y, int xx, int yy) {
  int z = lca(x, y);
  bool bo1 = 0;
  if ((lca(x, xx) == xx || lca(y, xx) == xx) && lca(z, xx) == z) bo1 = 1;
  bool bo2 = 0;
  if ((lca(x, yy) == yy || lca(y, yy) == yy) && lca(z, yy) == z) bo2 = 1;
  return bo1 & bo2;
}
Tree unite(Tree x, Tree y) {
  Tree z;
  z.l = -1;
  z.r = -1;
  if ((x.l == -1) || (y.r == -1)) return z;
  if (check(x.l, x.r, y.l, y.r))
    z.l = x.l, z.r = x.r;
  else if (check(x.l, y.l, x.r, y.r))
    z.l = x.l, z.r = y.l;
  else if (check(x.l, y.r, x.r, y.l))
    z.l = x.l, z.r = y.r;
  else if (check(x.r, y.l, x.l, y.r))
    z.l = x.r, z.r = y.l;
  else if (check(x.r, y.r, x.l, y.l))
    z.l = x.r, z.r = y.r;
  else if (check(y.l, y.r, x.l, x.r))
    z.l = y.l, z.r = y.r;
  return z;
}
void build(int l, int r, int x) {
  if (l == r) {
    tr[x].l = tr[x].r = pla[l];
    return;
  }
  int mid = (l + r) / 2;
  build(l, mid, x * 2);
  build(mid + 1, r, x * 2 + 1);
  Tree ls = tr[x * 2], rs = tr[x * 2 + 1];
  tr[x] = unite(ls, rs);
}
void change(int pur, int nxt, int l, int r, int x) {
  if (l == r) {
    tr[x].l = tr[x].r = pur;
    return;
  }
  int mid = (l + r) / 2;
  if (mid >= nxt)
    change(pur, nxt, l, mid, x * 2);
  else
    change(pur, nxt, mid + 1, r, x * 2 + 1);
  tr[x] = unite(tr[x * 2], tr[x * 2 + 1]);
}
void query(int l, int r, int now) {
  if (l == r) {
    if (tmp.l == -1 || unite(tmp, tr[now]).l != -1) {
      ans = max(ans, l);
      if (tmp.l != -1)
        tmp = unite(tmp, tr[now]);
      else
        tmp = tr[now];
    }
    return;
  }
  int mid = (l + r) >> 1;
  int ls = now * 2, rs = now * 2 + 1;
  if (tr[ls].l != -1 && (tmp.l == -1 || unite(tmp, tr[ls]).l != -1)) {
    if (tmp.l != -1)
      tmp = unite(tmp, tr[ls]);
    else
      tmp = tr[ls];
    ans = max(ans, mid);
    query(mid + 1, r, rs);
  } else
    query(l, mid, ls);
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &val[i]);
    pla[val[i]] = i;
  }
  for (int i = 2; i <= n; ++i) {
    int x;
    scanf("%d", &x);
    add(i, x);
    add(x, i);
  }
  dfs(1, 1);
  for (int i = 2; i <= num; ++i) lg[i] = lg[i / 2] + 1;
  ST();
  build(0, n - 1, 1);
  scanf("%d", &q);
  for (int i = 1; i <= q; ++i) {
    int x, y, z;
    scanf("%d", &x);
    if (x == 1) {
      scanf("%d%d", &y, &z);
      int v1 = val[y], v2 = val[z];
      change(y, v2, 0, n - 1, 1);
      change(z, v1, 0, n - 1, 1);
      val[y] = v2;
      val[z] = v1;
      pla[v1] = z;
      pla[v2] = y;
    } else {
      ans = 0;
      tmp.l = tmp.r = -1;
      query(0, n - 1, 1);
      printf("%d\n", ans + 1);
    }
  }
  return 0;
}
