#include <bits/stdc++.h>
using namespace std;
int val[200010], node[200010], x[800010], y[800010], head[200010], nxt[200010],
    a[200010], edge, jump[200010][20];
int lg, dep[200010], tx, ty, in[200010], out[200010], now;
int read() {
  int tmp = 0;
  char c = getchar();
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9') {
    tmp = tmp * 10 + c - '0';
    c = getchar();
  }
  return tmp;
}
void create(int u, int v) {
  edge++;
  a[edge] = v;
  nxt[edge] = head[u];
  head[u] = edge;
}
int get_lca(int u, int v) {
  if (dep[u] < dep[v]) swap(u, v);
  for (int i = lg; i >= 0; i--)
    if (dep[jump[u][i]] >= dep[v]) u = jump[u][i];
  if (u == v) return u;
  for (int i = lg; i >= 0; i--)
    if (jump[u][i] != jump[v][i]) {
      u = jump[u][i];
      v = jump[v][i];
    }
  return jump[u][0];
}
bool check_sub(int u, int v) { return in[v] >= in[u] && in[v] <= out[u]; }
bool check(int u, int v, int x, int y) {
  int tmp = get_lca(u, v);
  return check_sub(tmp, x) && check_sub(tmp, y) &&
         (check_sub(x, u) || check_sub(x, v)) &&
         (check_sub(y, u) || check_sub(y, v));
}
void update(int u1, int v1, int u2, int v2, int &x, int &y) {
  if (u1 == 0 || u2 == 0) {
    x = 0;
    y = 0;
    return;
  }
  if (u1 == -1) {
    x = u2;
    y = v2;
    return;
  }
  x = y = 0;
  if (check(u1, v1, u2, v2)) {
    x = u1;
    y = v1;
  } else if (check(u2, v2, u1, v1)) {
    x = u2;
    y = v2;
  } else if (check(u1, u2, v1, v2)) {
    x = u1;
    y = u2;
  } else if (check(u1, v2, v1, u2)) {
    x = u1;
    y = v2;
  } else if (check(v1, u2, u1, v2)) {
    x = v1;
    y = u2;
  } else if (check(v1, v2, u1, u2)) {
    x = v1;
    y = v2;
  }
}
void dfs(int u, int fa) {
  jump[u][0] = fa;
  in[u] = ++now;
  dep[u] = dep[fa] + 1;
  for (int i = head[u]; i; i = nxt[i]) {
    int v = a[i];
    dfs(v, u);
  }
  out[u] = now;
}
void build(int now, int l, int r) {
  if (l == r) {
    x[now] = y[now] = node[l];
    return;
  }
  int mid = (l + r) / 2;
  build(now * 2, l, mid);
  build(now * 2 + 1, mid + 1, r);
  update(x[now * 2], y[now * 2], x[now * 2 + 1], y[now * 2 + 1], x[now],
         y[now]);
}
void modify(int now, int l, int r, int t) {
  if (l == r) {
    x[now] = y[now] = node[l];
    return;
  }
  int mid = (l + r) / 2;
  if (t <= mid)
    modify(now * 2, l, mid, t);
  else
    modify(now * 2 + 1, mid + 1, r, t);
  update(x[now * 2], y[now * 2], x[now * 2 + 1], y[now * 2 + 1], x[now],
         y[now]);
}
int query(int now, int l, int r) {
  if (l == r) return l;
  int tmpx, tmpy, mid = (l + r) / 2;
  update(tx, ty, x[now * 2], y[now * 2], tmpx, tmpy);
  if (tmpx) {
    tx = tmpx;
    ty = tmpy;
    return query(now * 2 + 1, mid + 1, r);
  } else
    return query(now * 2, l, mid);
}
int main() {
  int n = read();
  for (int i = 1; i <= n; i++) {
    val[i] = read() + 1;
    node[val[i]] = i;
  }
  for (int i = 2; i <= n; i++) {
    int x = read();
    create(x, i);
  }
  dfs(1, 0);
  int tmp = 1;
  while (tmp <= n) {
    tmp *= 2;
    lg++;
  }
  for (int j = 1; j <= lg; j++)
    for (int i = 1; i <= n; i++) jump[i][j] = jump[jump[i][j - 1]][j - 1];
  build(1, 1, n);
  int m = read();
  for (int i = 1; i <= m; i++) {
    int opt = read();
    if (opt == 1) {
      int x = read(), y = read();
      node[val[x]] = y;
      node[val[y]] = x;
      swap(val[x], val[y]);
      modify(1, 1, n, val[x]);
      modify(1, 1, n, val[y]);
    } else {
      tx = ty = -1;
      if (x[1])
        printf("%d\n", n);
      else
        printf("%d\n", query(1, 1, n) - 1);
    }
  }
  return 0;
}
