#include <bits/stdc++.h>
using namespace std;
int n, q, a[200010], b[200010];
struct edge {
  int v, next;
} e[200010 << 1];
int eid, p[200010 << 1];
void insert(int u, int v) {
  e[++eid] = {v, p[u]};
  p[u] = eid;
}
int idx, c[200010 << 1], d[200010 << 1], dep[200010];
void dfs(int u, int fa) {
  c[u] = ++idx;
  d[idx] = u, dep[u] = dep[fa] + 1;
  for (int i = p[u]; i; i = e[i].next) {
    int v = e[i].v;
    if (v == fa) continue;
    dfs(v, u);
    c[u] = ++idx;
    d[idx] = u;
  }
}
namespace ST {
int st[200010 << 1][30], pos[200010 << 1][30];
void init() {
  for (int i = 1; i <= idx; ++i) st[i][0] = dep[d[i]], pos[i][0] = d[i];
  for (int i = 1; i <= 30; ++i)
    for (int j = 1; j <= idx - (1 << i) + 1; ++j) {
      if (st[j][i - 1] < st[j + (1 << i - 1)][i - 1])
        st[j][i] = st[j][i - 1], pos[j][i] = pos[j][i - 1];
      else
        st[j][i] = st[j + (1 << i - 1)][i - 1],
        pos[j][i] = pos[j + (1 << i - 1)][i - 1];
    }
}
int lca(int u, int v) {
  int l = c[u], r = c[v];
  if (l > r) swap(l, r);
  int len = log2(r - l + 1);
  if (st[l][len] <= st[r - (1 << len) + 1][len])
    return pos[l][len];
  else
    return pos[r - (1 << len) + 1][len];
}
int dist(int u, int v) { return dep[u] + dep[v] - 2 * dep[lca(u, v)]; }
void test() {
  while (1) {
    int u, v;
    cin >> u >> v;
    cout << lca(u, v) << " " << dist(u, v) << endl;
  }
}
}  // namespace ST
struct node {
  int l, r;
};
namespace segment_tree {
node s[200010 << 2];
node merge(node a, int b) {
  if (a.l < 0 || b < 0) return {-1, -1};
  int d1 = ST::dist(a.l, b);
  int d2 = ST::dist(a.r, b);
  int d3 = ST::dist(a.l, a.r);
  if (d1 + d2 == d3) return {a.l, a.r};
  if (d1 + d3 == d2) return {b, a.r};
  if (d2 + d3 == d1) return {a.l, b};
  return {-1, -1};
}
node up(node a, node b) {
  if (a.l < 0 || b.l < 0) return {-1, -1};
  node ans = merge(a, b.l);
  if (ans.l < 0) return {-1, -1};
  return merge(ans, b.r);
}
void build(int p, int l, int r) {
  if (l == r) {
    s[p] = {b[l], b[l]};
    return;
  }
  int mid = (l + r) >> 1;
  build(p << 1, l, mid);
  build(p << 1 | 1, mid + 1, r);
  s[p] = up(s[p << 1], s[p << 1 | 1]);
}
void change(int p, int l, int r, int x) {
  if (l == r) {
    s[p] = {b[l], b[l]};
    return;
  }
  int mid = (l + r) >> 1;
  if (x <= mid)
    change(p << 1, l, mid, x);
  else
    change(p << 1 | 1, mid + 1, r, x);
  s[p] = up(s[p << 1], s[p << 1 | 1]);
}
int query(node& x, int p, int l, int r) {
  if (s[p].l >= 0) {
    if (x.l < 0) {
      x = s[p];
      return r + 1;
    }
    node y = up(x, s[p]);
    if (y.l >= 0) {
      x = y;
      return r + 1;
    }
  }
  int mid = (l + r) >> 1;
  if (l == r) return l;
  int ans = query(x, p << 1, l, mid);
  if (ans <= mid) return ans;
  return query(x, p << 1 | 1, mid + 1, r);
}
}  // namespace segment_tree
int main() {
  cin >> n;
  for (int i = 1; i <= n; ++i) cin >> a[i], a[i]++, b[a[i]] = i;
  for (int u = 2; u <= n; ++u) {
    int v;
    cin >> v;
    insert(u, v);
    insert(v, u);
  }
  dfs(1, 1);
  ST::init();
  segment_tree::build(1, 1, n);
  cin >> q;
  while (q--) {
    int l, r, op;
    cin >> op;
    if (op == 1) {
      cin >> l >> r;
      swap(b[a[l]], b[a[r]]);
      swap(a[l], a[r]);
      segment_tree::change(1, 1, n, a[l]);
      segment_tree::change(1, 1, n, a[r]);
    } else {
      node x = {-1, -1};
      int ans = segment_tree::query(x, 1, 1, n);
      cout << ans - 1 << endl;
    }
  }
  return 0;
}
