#include <bits/stdc++.h>
using namespace std;
int a[200005], b[200005], dep[200005], cnt = 0, top[200005], sz[200005],
                                       fa[200005], son[200005];
vector<int> g[200005];
void dfs1(int x) {
  sz[x] = 1, dep[x] = dep[fa[x]] + 1;
  for (int i = 0; i < g[x].size(); ++i) {
    dfs1(g[x][i]);
    sz[x] += sz[g[x][i]];
    if (sz[g[x][i]] > sz[son[x]]) son[x] = g[x][i];
  }
}
void dfs2(int x, int s) {
  top[x] = s;
  if (!son[x]) return;
  dfs2(son[x], s);
  for (int i = 0; i < g[x].size(); ++i)
    if (g[x][i] != son[x]) dfs2(g[x][i], g[x][i]);
}
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] ? x : y;
}
int dis(int x, int y) { return dep[x] + dep[y] - 2 * dep[lca(x, y)]; }
bool pd(int x, int y, int z) { return dis(x, y) == dis(x, z) + dis(y, z); }
struct qwq {
  int u, v;
  qwq operator+(const qwq &a) const {
    if (!u || !v || !a.u || !a.v) return (qwq){0, 0};
    if (pd(a.u, u, v) && pd(a.u, u, a.v)) return (qwq){a.u, u};
    if (pd(a.u, v, u) && pd(a.u, v, a.v)) return (qwq){a.u, v};
    if (pd(a.u, a.v, u) && pd(a.u, a.v, v)) return (qwq){a.u, a.v};
    if (pd(u, a.v, a.u) && pd(u, a.v, v)) return (qwq){u, a.v};
    if (pd(u, v, a.u) && pd(u, v, a.v)) return (qwq){u, v};
    if (pd(a.v, v, a.u) && pd(a.v, v, u)) return (qwq){a.v, v};
    return (qwq){0, 0};
  }
} t[200005 << 2], pmt;
void build(int l, int r, int o) {
  if (l == r) {
    t[o] = (qwq){b[l], b[l]};
    return;
  }
  int mid = (l + r) >> 1;
  t[o] = (qwq){0, 0};
  build(l, mid, (o << 1));
  build(mid + 1, r, (o << 1 | 1));
  t[o] = t[o << 1] + t[o << 1 | 1];
}
void update(int l, int r, int o, int x) {
  if (l == r) {
    t[o] = (qwq){b[l], b[l]};
    return;
  }
  int mid = (l + r) >> 1;
  if (x <= mid)
    update(l, mid, (o << 1), x);
  else
    update(mid + 1, r, (o << 1 | 1), x);
  t[o] = t[o << 1] + t[o << 1 | 1];
}
int query(int l, int r, int o, qwq &x) {
  if (t[o].u && t[o].v) {
    if (!x.u) {
      x = t[o];
      return r;
    }
    qwq tmp = x + t[o];
    if (tmp.u) {
      x = tmp;
      return r;
    }
  }
  if (l == r) {
    return (x + t[o]).u ? l : 0;
  }
  int mid = l + r >> 1;
  int res = query(l, mid, (o << 1), x);
  if (res < mid)
    return res;
  else
    return max(query(mid + 1, r, (o << 1 | 1), x), res);
}
int main() {
  int n, x, q, i, op, y;
  scanf("%d", &n);
  for (i = 1; i <= n; ++i) scanf("%d", &a[i]), a[i]++, b[a[i]] = i;
  for (i = 2; i <= n; ++i) scanf("%d", &fa[i]), g[fa[i]].push_back(i);
  dfs1(1), dfs2(1, 1);
  build(1, n, 1);
  scanf("%d", &q);
  while (q--) {
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d%d", &x, &y);
      swap(b[a[x]], b[a[y]]), swap(a[x], a[y]);
      update(1, n, 1, a[x]), update(1, n, 1, a[y]);
    } else
      pmt = (qwq){0, 0}, printf("%d\n", query(1, n, 1, pmt));
  }
}
