#include <bits/stdc++.h>
using namespace std;
int n, m, timer, a[600000], pos[600000], size[600000], dfn[600000], dep[600000];
int A[2000000], B[2000000], C[2000000], Log[600000], bits[23], ST[600000][23];
int read() {
  int x = 0, k = 1;
  char c;
  c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') k = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  return x * k;
}
struct edge {
  int cnp, to[600000], last[600000], head[600000];
  edge() { cnp = 2; }
  void add(int u, int v) { to[cnp] = v, last[cnp] = head[u], head[u] = cnp++; }
} E1;
struct node {
  int s, t, x;
  node(int _a = 0, int _b = 0, int _c = 0) { s = _a, t = _b, x = _c; }
};
void dfs(int u) {
  ST[dfn[u] = ++timer][0] = u;
  size[u] = 1;
  for (int i = E1.head[u]; i; i = E1.last[i]) {
    int v = E1.to[i];
    dep[v] = dep[u] + 1;
    dfs(v);
    ST[++timer][0] = u;
    size[u] += size[v];
  }
}
int cmp(int x, int y) { return dep[x] < dep[y] ? x : y; }
void Pre() {
  Log[0] = -1;
  for (int i = 1; i < 600000; i++) Log[i] = Log[i >> 1] + 1;
  bits[0] = 1;
  for (int i = 1; i < 23; i++) bits[i] = bits[i - 1] << 1;
  for (int j = 1; j <= Log[timer]; j++)
    for (int i = 1; i + bits[j] - 1 <= timer; i++)
      ST[i][j] = cmp(ST[i][j - 1], ST[i + bits[j - 1]][j - 1]);
}
int LCA(int u, int v) {
  u = dfn[u], v = dfn[v];
  if (u > v) swap(u, v);
  int k = Log[v - u + 1];
  return cmp(ST[u][k], ST[v - bits[k] + 1][k]);
}
node Check(int s1, int t1, int s2, int t2) {
  int a[4] = {s1, t1, s2, t2};
  if (s1 == t1 && s2 == t2 && s1 == s2) return node(s1, t1, 1);
  for (int i = 0; i <= 3; i++)
    for (int j = i + 1; j <= 3; j++) {
      if (a[i] == a[j]) continue;
      int x = LCA(a[i], a[j]), y = -1, z;
      bool flag1 = 0, flag2 = 0;
      for (int k = 0; k <= 3; k++) {
        if (y == -1 && k != i && k != j)
          y = a[k];
        else if (k != j && k != i)
          z = a[k];
      }
      if (LCA(y, a[i]) == y || LCA(y, a[j]) == y) {
        if (LCA(y, x) == x) flag1 = 1;
      }
      if (LCA(z, a[i]) == z || LCA(z, a[j]) == z) {
        if (LCA(z, x) == x) flag2 = 1;
      }
      if (flag1 && flag2) {
        return node(a[i], a[j], 1);
      }
    }
  return node(0, 0, 0);
}
void Push_Up(int p) {
  if (!C[p << 1] || !C[p << 1 | 1])
    A[p] = B[p] = C[p] = 0;
  else {
    int ls = p << 1, rs = p << 1 | 1;
    node a = Check(A[ls], B[ls], A[rs], B[rs]);
    if (!a.x)
      A[p] = B[p] = C[p] = 0;
    else
      A[p] = a.s, B[p] = a.t, C[p] = 1;
  }
}
void Build(int p, int l, int r) {
  if (l == r) {
    A[p] = pos[l], B[p] = pos[l];
    C[p] = 1;
    return;
  }
  int mid = (l + r) >> 1;
  Build(p << 1, l, mid), Build(p << 1 | 1, mid + 1, r);
  Push_Up(p);
}
void Update(int p, int l, int r, int x, int y) {
  if (l == r) {
    A[p] = y, B[p] = y, C[p] = 1;
    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);
}
int Query(int p, int l, int r, int s, int t) {
  if (l == r) {
    node a = Check(s, t, A[p], B[p]);
    return a.x ? l : l - 1;
  }
  int mid = (l + r) >> 1, ls = p << 1;
  node a = C[ls] ? Check(s, t, A[ls], B[ls]) : node(0, 0, 0);
  if (!a.x)
    return Query(p << 1, l, mid, s, t);
  else
    return Query(p << 1 | 1, mid + 1, r, a.s, a.t);
}
int main() {
  n = read();
  for (int i = 1; i <= n; i++) a[i] = read() + 1, pos[a[i]] = i;
  for (int i = 2; i <= n; i++) {
    int x = read();
    E1.add(x, i);
  }
  dep[1] = 1;
  dfs(1);
  Pre();
  Build(1, 1, n);
  m = read();
  for (int i = 1; i <= m; i++) {
    int opt = read();
    if (opt == 1) {
      int x = read(), y = read();
      Update(1, 1, n, a[x], y);
      Update(1, 1, n, a[y], x);
      swap(a[x], a[y]);
      pos[a[x]] = x, pos[a[y]] = y;
    } else
      printf("%d\n", Query(1, 1, n, pos[1], pos[1]));
  }
  return 0;
}
