#include <bits/stdc++.h>
using namespace std;
const int N = 200000 + 20;
vector<int> vec[N];
int n;
int a[N];
int lg[N << 1];
int tot;
int f[N << 1];
int rmq[20][N << 1];
int dep[N];
int st[N];
int pos[N];
struct Node {
  int flag;
  int u, v;
} node[N << 2];
int get_lca(int u, int v) {
  int a = st[u];
  int b = st[v];
  if (a > b) swap(a, b);
  int k = lg[b - a + 1];
  int x = rmq[k][a];
  int y = rmq[k][b + 1 - (1 << k)];
  if (dep[x] > dep[y]) swap(x, y);
  return x;
}
bool check(int x, int y, const vector<int> &v) {
  int lca = get_lca(x, y);
  for (int z : v) {
    int a = get_lca(z, lca);
    int b = get_lca(z, x);
    int c = get_lca(z, y);
    if (a != lca) return false;
    if (b != z && c != z) {
      return false;
    }
  }
  return true;
}
bool merge(int a, int b, int c, int d, vector<int> &output) {
  vector<int> v{a, b, c, d};
  for (int i = 0; i < v.size(); i++) {
    for (int j = i + 1; j < v.size(); j++) {
      if (check(v[i], v[j], v)) {
        output = {v[i], v[j]};
        return true;
      }
    }
  }
  return false;
}
void push_up(int p, int l, int r) {
  int lson = p << 1;
  int rson = lson | 1;
  if (node[lson].flag && node[rson].flag) {
    vector<int> output;
    if (merge(node[lson].u, node[lson].v, node[rson].u, node[rson].v, output)) {
      node[p].flag = 1;
      node[p].u = output[0];
      node[p].v = output[1];
      return;
    }
  }
  node[p].flag = 0;
  node[p].u = node[p].v = 0;
}
void build(int p, int l, int r) {
  if (l == r) {
    node[p].flag = 1;
    node[p].u = node[p].v = pos[l];
    return;
  }
  int mid = (l + r) >> 1;
  build(p << 1, l, mid);
  build(p << 1 | 1, mid + 1, r);
  push_up(p, l, r);
}
void update(int p, int l, int r, int x, int y) {
  if (l == r) {
    node[p].flag = 1;
    node[p].u = node[p].v = y;
    return;
  }
  int mid = (l + r) >> 1;
  if (x <= mid) {
    update(p << 1, l, mid, x, y);
  } else {
    update(p << 1 | 1, mid + 1, r, x, y);
  }
  push_up(p, l, r);
}
int query(int p, int l, int r, vector<int> &v) {
  if (node[p].flag && merge(node[p].u, node[p].v, v[0], v[1], v)) {
    return r;
  }
  if (l == r) return 0;
  int mid = (l + r) >> 1;
  int res = query(p << 1, l, mid, v);
  if (res == mid) {
    return max(res, query(p << 1 | 1, mid + 1, r, v));
  }
  return res;
}
void dfs(int u, int fa, int d) {
  dep[u] = d;
  f[++tot] = u;
  st[u] = tot;
  for (int v : vec[u]) {
    if (v == fa) continue;
    dfs(v, u, d + 1);
    f[++tot] = u;
  }
}
void init_rmq() {
  int m = 2 * n;
  for (int i = 1; i < m; i++) {
    rmq[0][i] = f[i];
  }
  for (int i = 1; i < 20; i++) {
    for (int j = 1; j + (1 << i) - 1 <= m; j++) {
      int a = rmq[i - 1][j];
      int b = rmq[i - 1][j + (1 << (i - 1))];
      if (dep[a] > dep[b]) swap(a, b);
      rmq[i][j] = a;
    }
  }
}
void solve() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    pos[a[i]] = i;
  }
  for (int i = 2; i <= n; i++) {
    int x;
    scanf("%d", &x);
    vec[i].push_back(x);
    vec[x].push_back(i);
  }
  tot = 0;
  dfs(1, 0, 1);
  init_rmq();
  build(1, 0, n - 1);
  int q;
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    int t;
    cin >> t;
    if (t == 1) {
      int x, y;
      scanf("%d%d", &x, &y);
      swap(a[x], a[y]);
      pos[a[x]] = x;
      pos[a[y]] = y;
      update(1, 0, n - 1, a[x], x);
      update(1, 0, n - 1, a[y], y);
    } else {
      vector<int> vec{pos[1], pos[1]};
      int ans = query(1, 0, n - 1, vec) + 1;
      printf("%d\n", ans);
    }
  }
}
int main() {
  for (int i = 1; i < (N << 1); i++) {
    lg[i] = log(i) / log(2.0);
  }
  solve();
  return 0;
}
