#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 + 5;
struct Edge {
  int v, nxt;
} edge[maxn * 2];
int head[maxn], tot;
void init() {
  memset(head, -1, sizeof head);
  tot = 0;
}
void addedge(int u, int v) {
  edge[tot] = {v, head[u]};
  head[u] = tot++;
}
int n, m, first[maxn], dep[maxn];
int dfn[maxn * 2], N;
void dfs1(int u) {
  dfn[++N] = u;
  first[u] = N;
  for (int i = head[u]; ~i; i = edge[i].nxt) {
    int v = edge[i].v;
    dep[v] = dep[u] + 1;
    dfs1(v);
    dfn[++N] = u;
  }
}
int lg2[maxn * 2];
int mn[maxn * 2][20];
void RMQ_init() {
  lg2[1] = 0;
  for (int i = 2; i <= N; i++)
    if ((1 << (lg2[i - 1] + 1)) == i)
      lg2[i] = lg2[i - 1] + 1;
    else
      lg2[i] = lg2[i - 1];
  for (int i = 1; i <= N; i++) mn[i][0] = dfn[i];
  for (int i = 1; i <= lg2[N]; i++)
    for (int j = 1; j + (1 << i) - 1 <= N; j++) {
      int x = mn[j][i - 1], y = mn[j + (1 << (i - 1))][i - 1];
      mn[j][i] = (dep[x] < dep[y]) ? x : y;
    }
}
int LCA(int x, int y) {
  int l = first[x], r = first[y];
  if (l > r) swap(l, r);
  int k = lg2[r - l + 1];
  x = mn[l][k], y = mn[r - (1 << k) + 1][k];
  return (dep[x] < dep[y]) ? x : y;
}
int p[maxn];
int np[maxn];
struct node {
  int x, y;
} data[maxn * 4];
bool InPath(int x, node a) {
  int lca = LCA(a.x, a.y);
  if (LCA(lca, x) != lca) return false;
  return (LCA(a.x, x) == x || LCA(a.y, x) == x);
}
node merge(node a, node b) {
  if (a.x == -1 || b.x == -1) return {-1, -1};
  if (InPath(a.x, b) && InPath(a.y, b)) return b;
  if (InPath(b.x, a) && InPath(b.y, a)) return a;
  node ret = {a.x, b.x};
  if (InPath(a.y, ret) && InPath(b.y, ret)) return ret;
  ret = {a.x, b.y};
  if (InPath(a.y, ret) && InPath(b.x, ret)) return ret;
  ret = {a.y, b.x};
  if (InPath(a.x, ret) && InPath(b.y, ret)) return ret;
  ret = {a.y, b.y};
  if (InPath(a.x, ret) && InPath(b.x, ret)) return ret;
  return {-1, -1};
}
void build(int i, int L, int R) {
  if (L == R) {
    data[i] = {np[L], np[L]};
    return;
  }
  int mid = (L + R) >> 1;
  build(i << 1, L, mid);
  build((i << 1) | 1, mid + 1, R);
  data[i] = merge(data[i << 1], data[(i << 1) | 1]);
}
using pii = pair<int, node>;
pii ans;
void ask(int i, int L, int R) {
  if (data[i].x != -1) {
    if (ans.first == -1) {
      ans = {R, data[i]};
      return;
    } else {
      node tmp = merge(ans.second, data[i]);
      if (tmp.x != -1) {
        ans = {R, tmp};
        return;
      }
    }
  }
  if (L == R) return;
  int mid = (L + R) >> 1;
  ask(i << 1, L, mid);
  if (ans.first == mid) ask((i << 1) | 1, mid + 1, R);
}
void modify(int i, int L, int R, int pos) {
  if (L == R) {
    data[i] = {np[L], np[L]};
    return;
  }
  int mid = (L + R) >> 1;
  if (mid >= pos)
    modify(i << 1, L, mid, pos);
  else
    modify((i << 1) | 1, mid + 1, R, pos);
  data[i] = merge(data[i << 1], data[(i << 1) | 1]);
}
int main() {
  init();
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &p[i]);
    np[p[i]] = i;
  }
  for (int i = 2; i <= n; i++) {
    int x;
    scanf("%d", &x);
    addedge(x, i);
  }
  dfs1(1);
  RMQ_init();
  build(1, 0, n - 1);
  scanf("%d", &m);
  while (m--) {
    int op, x, y;
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d%d", &x, &y);
      swap(p[x], p[y]);
      np[p[x]] = x;
      np[p[y]] = y;
      modify(1, 0, n - 1, p[x]);
      modify(1, 0, n - 1, p[y]);
    } else if (op == 2) {
      ans = {-1, {-1, -1}};
      ask(1, 0, n - 1);
      printf("%d\n", ans.first + 1);
    }
  }
  return 0;
}
