#include <bits/stdc++.h>
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
using namespace std;
const int BIT = 20;
const int N = 4e5 + 29;
vector<int> e[N];
int rmq[21][N], dep[N], n, lg[N], tot, pos[N], p[N];
pair<int, int> info[N * 7 + 19];
void dfs(int u) {
  pos[u] = ++tot;
  rmq[0][tot] = u;
  for (auto v : e[u]) {
    dep[v] = dep[u] + 1;
    dfs(v);
    rmq[0][++tot] = u;
  }
}
inline int lower(int a, int b) { return dep[a] < dep[b] ? a : b; }
void init_rmq(int n) {
  for (int i = 2; i <= n; i *= 2) lg[i] = 1;
  for (int i = 2; i <= n; ++i) lg[i] += lg[i - 1];
  for (int i = 1; i <= BIT; ++i)
    for (int j = 1; j + (1 << i) - 1 <= n; ++j)
      rmq[i][j] = lower(rmq[i - 1][j], rmq[i - 1][j + (1 << i - 1)]);
}
inline int lca(int u, int v) {
  if (u == v) return u;
  if (pos[u] > pos[v]) swap(u, v);
  int t = lg[pos[v] - pos[u]];
  return lower(rmq[t][pos[u]], rmq[t][pos[v] - (1 << t) + 1]);
}
inline int dis(int u, int v) { return dep[u] + dep[v] - 2 * dep[lca(u, v)]; }
pair<int, int> merge(int u, int v, int w) {
  int uv = dis(u, v), vw = dis(v, w), uw = dis(u, w);
  if (uv + uw == vw)
    return pair<int, int>(w, v);
  else if (uv + vw == uw)
    return pair<int, int>(u, w);
  else if (vw + uw == uv)
    return pair<int, int>(u, v);
  return pair<int, int>(-1, -1);
}
pair<int, int> merge(pair<int, int> a, pair<int, int> b) {
  if (~a.first && ~b.first) {
    a = merge(a.first, a.second, b.first);
    if (~a.first) a = merge(a.first, a.second, b.second);
    return a;
  } else
    return pair<int, int>(-1, -1);
}
pair<int, int> mdf(int pos, int l, int r) {
  int num = (((l) + (r)) | ((l) < (r))), mid = l + r >> 1;
  if (l == r) return info[num];
  if (pos > r || pos < l) return info[num];
  info[num] = merge(mdf(pos, l, mid), mdf(pos, mid + 1, r));
  return info[num];
}
int qry(int l, int r, pair<int, int> &ask) {
  int num = (((l) + (r)) | ((l) < (r))), mid = l + r >> 1;
  if (l == r) {
    pair<int, int> tmp = merge(ask, info[num]);
    if (!~tmp.first)
      return r;
    else {
      ask = tmp;
      return r + 1;
    }
  }
  pair<int, int> tmp = merge(ask, info[(((l) + (mid)) | ((l) < (mid)))]);
  if (!~tmp.first)
    return qry(l, mid, ask);
  else {
    ask = tmp;
    int x = qry(mid + 1, r, ask);
    if (!~ask.first)
      return mid + 1;
    else
      return x;
  }
}
void init(int l, int r) {
  int num = (((l) + (r)) | ((l) < (r))), mid = l + r >> 1;
  info[num] = pair<int, int>(-1, -1);
  if (l == r) return;
  init(l, mid);
  init(mid + 1, r);
}
void show(int l, int r) {
  int num = (((l) + (r)) | ((l) < (r))), mid = l + r >> 1;
  cout << l - 1 << ' ' << r - 1 << ':' << info[num].first << ' '
       << info[num].second << endl;
  if (l == r) return;
  show(l, mid);
  show(mid + 1, r);
}
int main() {
  scanf("%d", &n);
  init(1, n);
  for (int i = 1; i <= n; ++i) {
    int x;
    scanf("%d", &x);
    ++x;
    p[i] = x;
    info[(((x) + (x)) | ((x) < (x)))] = pair<int, int>(i, i);
  }
  for (int i = 2; i <= n; ++i) {
    int x;
    scanf("%d", &x);
    e[x].push_back(i);
  }
  dfs(1);
  init_rmq(tot);
  for (int i = 1; i <= n; ++i) mdf(i, 1, n);
  int q;
  scanf("%d", &q);
  for (int i = 1; i <= q; ++i) {
    int t;
    scanf("%d", &t);
    if (t == 2) {
      pair<int, int> ask = info[(((1) + (1)) | ((1) < (1)))];
      printf("%d\n", qry(1, n, ask) - 1);
    } else {
      int u, v;
      scanf("%d%d", &u, &v);
      swap(info[(((p[u]) + (p[u])) | ((p[u]) < (p[u])))],
           info[(((p[v]) + (p[v])) | ((p[v]) < (p[v])))]);
      swap(p[u], p[v]);
      mdf(p[u], 1, n);
      mdf(p[v], 1, n);
    }
  }
  return 0;
}
