#include <bits/stdc++.h>
using namespace std;
int gi() {
  char cc = getchar();
  int cn = 0, flus = 1;
  while (cc < '0' || cc > '9') {
    if (cc == '-') flus = -flus;
    cc = getchar();
  }
  while (cc >= '0' && cc <= '9') cn = cn * 10 + cc - '0', cc = getchar();
  return cn * flus;
}
const int N = 2e5 + 5;
int n, q, idx, Id[N], w[N], dfn[N], dep[N], fa[N], top[N], sz[N], son[N];
vector<int> G[N];
struct node {
  int u, v, f;
  node(int _u = 0, int _v = 0, int _f = 0) { u = _u, v = _v, f = _f; }
  void init() { u = 0, v = 0, f = 0; }
} tr[N << 2], fs;
void dfs1(int x) {
  sz[x] = 1, dep[x] = dep[fa[x]] + 1;
  for (int v : G[x]) {
    dfs1(v), sz[x] += sz[v];
    if (sz[v] >= sz[son[x]]) son[x] = v;
  }
}
void dfs2(int x, int high) {
  top[x] = high, dfn[x] = ++idx;
  if (son[x]) dfs2(son[x], high);
  for (int v : G[x])
    if (v ^ son[x]) dfs2(v, v);
}
int LCA(int x, int y) {
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]]) swap(x, y);
    x = fa[top[x]];
  }
  return (dep[x] > dep[y]) ? y : x;
}
int dis(int x, int y) { return dep[x] + dep[y] - 2 * dep[LCA(x, y)]; }
int a[10];
node merge(node x, node y) {
  if (x.f || y.f) return node(-1, -1, 1);
  a[0] = x.u, a[1] = x.v, a[2] = y.u, a[3] = y.v;
  sort(a, a + 4);
  do {
    int d = dis(a[0], a[3]);
    for (int i = 1; i < 4; ++i) d -= dis(a[i], a[i - 1]);
    if (d == 0) return node(a[0], a[3], 0);
  } while (next_permutation(a, a + 4));
  return node(-1, -1, 1);
}
void build(int x, int l, int r) {
  if (l == r) return tr[x] = node(Id[l], Id[l], 0), void();
  int mid = (l + r) >> 1;
  build((x << 1), l, mid), build((x << 1 | 1), mid + 1, r);
  tr[x] = merge(tr[(x << 1)], tr[(x << 1 | 1)]);
}
void update(int x, int l, int r, int k, node u) {
  if (l == r) return tr[x] = u, void();
  int mid = (l + r) >> 1;
  if (k <= mid)
    update((x << 1), l, mid, k, u);
  else
    update((x << 1 | 1), mid + 1, r, k, u);
  tr[x] = merge(tr[(x << 1)], tr[(x << 1 | 1)]);
}
bool check(node x) {
  if (x.f) return 0;
  if (fs.u == 0) {
    fs = x;
    return 1;
  }
  node t = merge(x, fs);
  if (t.f) return 0;
  fs = t;
  return 1;
}
int query(int x, int l, int r) {
  if (l == r) return (check(tr[x])) ? l : 0;
  int mid = (l + r) >> 1;
  if (check(tr[(x << 1)]))
    return max(mid, query((x << 1 | 1), mid + 1, r));
  else
    return query((x << 1), l, mid);
}
void Change(int x, int y) {
  update(1, 0, n - 1, w[x], node(y, y, 0)),
      update(1, 0, n - 1, w[y], node(x, x, 0)), swap(w[x], w[y]);
}
signed main() {
  n = gi();
  int opt, x, y;
  for (register int i = (1); i <= (n); ++i) x = gi(), Id[x] = i, w[i] = x;
  for (register int i = (2); i <= (n); ++i) fa[i] = gi(), G[fa[i]].push_back(i);
  dfs1(1), dfs2(1, 1), build(1, 0, n - 1);
  q = gi();
  while (q--) {
    opt = gi();
    if (opt == 1)
      x = gi(), y = gi(), Change(x, y);
    else
      fs.init(), printf("%d\n", query(1, 0, n - 1) + 1);
  }
  return 0;
}
