#include <bits/stdc++.h>
using namespace std;
const int N = 2e5;
int n, q, p[N], in[N], out[N], rem, dp[18][N], depth[N], at[N];
vector<int> g[N];
struct node {
  int s, e;
  node(int a = -1, int b = -1) {
    s = a;
    e = b;
  }
} seg[4 * N], cur;
void dfs(int u) {
  for (int i = 1; i < 18; i++)
    if (dp[i - 1][u] == -1)
      dp[i][u] = -1;
    else
      dp[i][u] = dp[i - 1][dp[i - 1][u]];
  in[u] = rem++;
  for (auto i : g[u]) {
    depth[i] = depth[u] + 1;
    dp[0][i] = u;
    dfs(i);
  }
  out[u] = rem - 1;
}
int lca(int u, int v) {
  if (depth[u] < depth[v]) swap(u, v);
  for (int i = 17; i + 1; i--)
    if (depth[u] - (1 << i) >= depth[v]) u = dp[i][u];
  if (u == v) return u;
  for (int i = 17; i + 1; i--)
    if (dp[i][u] != dp[i][v]) {
      u = dp[i][u];
      v = dp[i][v];
    }
  return dp[0][u];
}
bool within(int a, int b) { return in[a] <= in[b] && in[b] <= out[a]; }
node merge(node a, node b) {
  if (a.s == -1) return node();
  if (b.s == -1) return node();
  if (within(a.e, a.s) && !within(b.e, b.s)) swap(a, b);
  if (within(a.e, a.s)) {
    int c = lca(a.e, b.e);
    if (c != a.e && c != b.e) return node(a.s, b.s);
    if (c == b.e) swap(a, b);
    if (within(b.s, a.s)) return node(a.s, a.e);
    if (within(a.s, b.s)) return node(b.s, a.e);
    if (lca(b.s, a.s) == c) return node(a.s, b.s);
    return node(-1, -1);
  }
  node ret;
  ret.s = a.s;
  ret.e = a.e;
  if (within(b.e, b.s)) {
    int c = lca(a.s, a.e);
    if (within(c, b.e)) {
      if (within(b.s, a.s) || within(b.s, a.e)) return ret;
      if (within(a.s, b.s)) {
        ret.s = b.s;
        return ret;
      }
      if (within(a.e, b.s)) {
        ret.e = b.s;
        return ret;
      }
    }
    return node();
  }
  int c = lca(a.s, a.e), c1 = lca(b.s, b.e);
  if (c != c1) return node();
  ret = node();
  if (within(a.s, b.s)) ret.s = b.s;
  if (within(b.s, a.s)) ret.s = a.s;
  if (within(a.e, b.e)) ret.e = b.e;
  if (within(b.e, a.e)) ret.e = a.e;
  if (ret.s == -1 || ret.e == -1) ret = node();
  return ret;
}
void build(int c, int l, int r) {
  if (l == r) {
    seg[c].s = seg[c].e = at[l];
    return;
  }
  build(2 * c + 1, l, (l + r) / 2);
  build(2 * c + 2, (l + r) / 2 + 1, r);
  seg[c] = merge(seg[2 * c + 1], seg[2 * c + 2]);
  if (seg[c].s != -1) {
    if (in[seg[c].s] < in[seg[c].e]) swap(seg[c].s, seg[c].e);
  }
}
void update(int c, int l, int r, int s) {
  if (l > s || r < s) return;
  if (l == r) {
    seg[c].s = seg[c].e = at[l];
    return;
  }
  update(2 * c + 1, l, (l + r) / 2, s);
  update(2 * c + 2, (l + r) / 2 + 1, r, s);
  seg[c] = merge(seg[2 * c + 1], seg[2 * c + 2]);
  if (seg[c].s != -1) {
    if (in[seg[c].s] < in[seg[c].e]) swap(seg[c].s, seg[c].e);
  }
}
int get(int c, int l, int r) {
  if (l == r) {
    node temp = merge(cur, seg[c]);
    if (temp.s == -1) return -1;
    cur = temp;
    return r;
  }
  if (cur.s == -1) cur = seg[2 * c + 1];
  node temp = merge(seg[2 * c + 1], cur);
  if (temp.s == -1) return get(2 * c + 1, l, (l + r) / 2);
  cur = temp;
  int ans = (l + r) / 2;
  return max(ans, get(2 * c + 2, (l + r) / 2 + 1, r));
}
void print(int c, int l, int r) {
  cout << l << " " << r << " " << seg[c].s << " " << seg[c].e << endl;
  if (l == r) return;
  print(2 * c + 1, l, (l + r) / 2);
  print(2 * c + 2, (l + r) / 2 + 1, r);
}
int main() {
  memset(dp, -1, sizeof dp);
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%d", p + i);
    at[p[i]] = i;
  }
  for (int i = 1, a; i < n; i++) {
    scanf("%d", &a);
    g[a - 1].push_back(i);
  }
  dfs(0);
  build(0, 0, n - 1);
  scanf("%d", &q);
  for (int i = 0, t, a, b; i < q; i++) {
    scanf("%d", &t);
    cur = node();
    if (t == 1) {
      scanf("%d%d", &a, &b);
      swap(at[p[--a]], at[p[--b]]);
      swap(p[a], p[b]);
      update(0, 0, n - 1, p[a]);
      update(0, 0, n - 1, p[b]);
    } else
      printf("%d\n", get(0, 0, n - 1) + 1);
  }
}
