#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  return x * f;
}
const int N = 200005;
const int Log = 22;
struct Edge {
  int to, nxt;
  Edge() {}
  Edge(int a, int b) { to = a, nxt = b; }
} e[N];
int head[N], a[N], per[N], In[N], Ou[N], deth[N], f[N][Log + 1], En, Index;
struct Node {
  int x, y;
  Node() {}
  Node(int _x, int _y) { x = _x, y = _y; }
} T[N << 2];
bool operator<(const Node &A, const Node &B) {
  return A.x == B.x ? A.y < B.y : A.x < B.x;
}
int Jump(int x, int ly) {
  for (int i = Log; i >= 0; --i)
    if (deth[f[x][i]] >= ly) x = f[x][i];
  return x;
}
int LCA(int u, int v) {
  if (deth[u] < deth[v]) swap(u, v);
  int d = deth[u] - deth[v];
  for (int i = Log; i >= 0; --i)
    if ((d >> i) & 1) u = f[u][i];
  if (u == v) return u;
  for (int i = Log; i >= 0; --i)
    if (f[u][i] != f[v][i]) u = f[u][i], v = f[v][i];
  return f[u][0];
}
bool onpath(int x, int y, int z) {
  int anc = LCA(x, y);
  if (deth[anc] > deth[z]) return 0;
  return Jump(x, deth[z]) == z || Jump(y, deth[z]) == z;
}
Node operator+(const Node &A, const Node &B) {
  int a = A.x, b = A.y, c = B.x, d = B.y;
  if (a == -1 || b == -1 || c == -1 || d == -1) return Node(-1, -1);
  int x = min(Node(Ou[a], a),
              min(Node(Ou[b], b), min(Node(Ou[c], c), Node(Ou[d], d))))
              .y;
  int y = max(Node(In[a], a),
              max(Node(In[b], b), max(Node(In[c], c), Node(In[d], d))))
              .y;
  if (x == y) {
    int z = min(Node(deth[a], a),
                min(Node(deth[b], b), min(Node(deth[c], c), Node(deth[d], d))))
                .y;
    return Node(z, x);
  } else if (onpath(x, y, a) && onpath(x, y, b) && onpath(x, y, c) &&
             onpath(x, y, d))
    return Node(x, y);
  else
    return Node(-1, -1);
}
inline void add_edge(int u, int v) {
  ++En;
  e[En] = Edge(v, head[u]);
  head[u] = En;
}
void dfs(int u) {
  In[u] = ++Index;
  for (int i = head[u]; i; i = e[i].nxt)
    deth[e[i].to] = deth[u] + 1, dfs(e[i].to);
  Ou[u] = ++Index;
}
void build(int l, int r, int rt) {
  if (l == r) {
    T[rt].x = T[rt].y = per[l];
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, rt << 1);
  build(mid + 1, r, rt << 1 | 1);
  T[rt] = T[rt << 1] + T[rt << 1 | 1];
}
void update(int l, int r, int rt, int p, int v) {
  if (l == r) {
    T[rt].x = T[rt].y = v;
    return;
  }
  int mid = (l + r) >> 1;
  if (p <= mid) update(l, mid, rt << 1, p, v);
  if (p > mid) update(mid + 1, r, rt << 1 | 1, p, v);
  T[rt] = T[rt << 1] + T[rt << 1 | 1];
}
int query(int l, int r, int rt, Node now) {
  if (l == r) {
    return (now + T[rt]).x == -1 ? l - 1 : l;
  }
  int mid = (l + r) >> 1;
  Node tmp = now + T[rt << 1];
  if (tmp.x == -1)
    return query(l, mid, rt << 1, now);
  else
    return query(mid + 1, r, rt << 1 | 1, tmp);
}
int main() {
  int n = read();
  for (int i = 1; i <= n; ++i) a[i] = read(), per[a[i]] = i;
  for (int i = 2; i <= n; ++i) {
    int fa = read();
    add_edge(fa, i);
    f[i][0] = fa;
  }
  for (int j = 1; j <= Log; ++j)
    for (int i = 1; i <= n; ++i) f[i][j] = f[f[i][j - 1]][j - 1];
  deth[1] = 1;
  dfs(1);
  build(0, n - 1, 1);
  int Q = read();
  while (Q--) {
    int opt = read();
    if (opt == 2) {
      printf("%d\n", query(0, n - 1, 1, Node(per[0], per[0])) + 1);
      continue;
    }
    int x = read(), y = read();
    swap(per[a[x]], per[a[y]]);
    update(0, n - 1, 1, a[x], per[a[x]]);
    update(0, n - 1, 1, a[y], per[a[y]]);
    swap(a[x], a[y]);
  }
  return 0;
}
