#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
const int lgN = 18;
const int MOD = 1e9 + 7;
const int B = 448;
vector<int> g[N];
int v[N], fir[N], sz, logg[2 * N], h[N], inv[N];
int sparse[lgN + 1][2 * N];
vector<int> euler, dep;
int lca(int uu, int vv) {
  uu = fir[uu];
  vv = fir[vv];
  if (uu > vv) swap(uu, vv);
  int j = logg[vv - uu + 1], go;
  go = sparse[j][uu];
  if (dep[sparse[j][vv - (1 << j) + 1]] < dep[go])
    go = sparse[j][vv - (1 << j) + 1];
  return euler[go];
}
void pre(int node, int p, int curr_depth) {
  int i;
  euler.push_back(node);
  dep.push_back(curr_depth);
  h[node] = curr_depth;
  fir[node] = min(fir[node], sz);
  sz++;
  for (auto it : g[node])
    if (it != p) {
      pre(it, node, curr_depth + 1);
      euler.push_back(node);
      dep.push_back(curr_depth);
      sz++;
    }
}
void setup_lca() {
  int i, j;
  for (i = 0; i < sz; i++) sparse[0][i] = i;
  for (j = 1; j < lgN + 1; j++) {
    for (i = 0; i < sz; i++) {
      sparse[j][i] = sparse[j - 1][i];
      if ((1 << (j - 1)) + i < sz) {
        int tst = i + (1 << (j - 1));
        tst = sparse[j - 1][tst];
        if (dep[tst] < dep[sparse[j][i]]) sparse[j][i] = tst;
      }
    }
  }
}
pair<int, int> merge_path(pair<int, int> a, int b) {
  if (a.first == 0) return {b, b};
  if (b == 0) return a;
  if (a.first == -1 || b == -1) return {-1, -1};
  int l = lca(a.first, a.second);
  if (l == a.second) {
    int aok = lca(a.first, b);
    if (aok == a.first) return {b, a.second};
    if (h[aok] > h[l]) {
      if (aok == b) return a;
      return {-1, -1};
    }
    if (h[b] > h[a.first]) return {b, a.first};
    return {a.first, b};
  } else {
    int aok = lca(a.first, b);
    if (h[aok] < h[l]) return {-1, -1};
    if (aok == b) return a;
    if (aok == a.first) return {b, a.second};
    aok = lca(a.second, b);
    if (aok == a.second) {
      if (h[b] > h[a.first]) return {b, a.first};
      return {a.first, b};
    }
    if (aok == b) return a;
  }
  return {-1, -1};
}
pair<int, int> merge_path(pair<int, int> a, pair<int, int> b) {
  return merge_path(merge_path(a, b.first), b.second);
}
struct tree_node {
  pair<int, int> path;
} tree[4 * N];
void merge_node(tree_node a, tree_node b, tree_node &c) {
  c.path = merge_path(a.path, b.path);
}
void build(int node, int L, int R) {
  if (L == R) {
    tree[node].path = {inv[L], inv[L]};
    return;
  }
  int M = (L + R) >> 1;
  build(2 * node + 1, L, M);
  build(2 * node + 2, M + 1, R);
  merge_node(tree[2 * node + 1], tree[2 * node + 2], tree[node]);
}
void update(int pos1, int pos2, int node, int L, int R) {
  if (L == R) {
    tree[node].path = {inv[L], inv[L]};
    return;
  }
  int M = (L + R) >> 1;
  if ((pos1 <= M && pos1 >= L) || (pos2 <= M && pos2 >= L))
    update(pos1, pos2, 2 * node + 1, L, M);
  if ((pos1 > M && pos1 <= R) || (pos2 > M && pos2 <= R))
    update(pos1, pos2, 2 * node + 2, M + 1, R);
  merge_node(tree[2 * node + 1], tree[2 * node + 2], tree[node]);
}
int query(pair<int, int> path, int node, int L, int R) {
  if (L == R) {
    path = merge_path(path, tree[node].path);
    if (path.first == -1) return -1;
    return L;
  }
  if (merge_path(tree[node].path, path).first != -1) return R;
  int M = (L + R) >> 1;
  int ans = query(path, 2 * node + 1, L, M);
  if (ans == M) {
    path = merge_path(path, tree[2 * node + 1].path);
    ans = max(ans, query(path, 2 * node + 2, M + 1, R));
  }
  return ans;
}
void disp(int node, int l, int r) {
  cout << node << " : " << tree[node].path.first << " -> "
       << tree[node].path.second;
  cout << " contains [" << l << "," << r << "]\n";
  if (l == r) return;
  int m = (l + r) >> 1;
  disp(2 * node + 1, l, m);
  disp(2 * node + 2, m + 1, r);
}
int main() {
  int n, m, i, j, nxt = 0;
  scanf("%d", &n);
  for (i = 1; i <= n; i++) {
    cin >> v[i];
    inv[v[i]] = i;
    fir[i] = 4 * n;
  }
  for (i = 1; i < n + n; i++) {
    if ((1 << nxt) == i) nxt++;
    logg[i] = nxt - 1;
  }
  for (i = 2; i <= n; i++) {
    int uu;
    scanf("%d", &uu);
    g[uu].push_back(i);
    g[i].push_back(uu);
  }
  pre(1, 1, 0);
  setup_lca();
  pair<int, int> now = merge_path({8, 8}, 5);
  build(0, 0, n - 1);
  int q;
  scanf("%d", &q);
  while (q--) {
    int type;
    scanf("%d", &type);
    if (type == 2) {
      printf("%d\n", query({0, 0}, 0, 0, n - 1) + 1);
    } else {
      int uu, vv;
      scanf("%d %d", &uu, &vv);
      swap(inv[v[uu]], inv[v[vv]]);
      swap(v[uu], v[vv]);
      update(v[uu], v[vv], 0, 0, n - 1);
    }
  }
  return 0;
}
