#include <bits/stdc++.h>
using namespace std;
inline int Getint() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) ch != '-' ?: f = -1, ch = getchar();
  while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
  return x * f;
}
const int N = 200005;
int n, Q, cnt, top, h[N], a[N], dep[N], p[N * 2][20], dfn[N * 2], st[N * 2],
    id[N * 2], lg[N * 2];
struct edge {
  int to, next;
} e[N * 2];
void addedge(int x, int y) {
  e[++cnt] = (edge){y, h[x]};
  h[x] = cnt;
}
void dfs(int x, int fa) {
  st[++top] = x;
  dfn[x] = top;
  dep[x] = dep[fa] + 1;
  for (int i = h[x]; i; i = e[i].next) {
    int y = e[i].to;
    dfs(y, x);
    st[++top] = x;
  }
}
int LCA(int x, int y) {
  x = dfn[x];
  y = dfn[y];
  if (x > y) swap(x, y);
  int k = lg[y - x + 1];
  return dep[p[x][k]] < dep[p[y - (1 << k) + 1][k]] ? p[x][k]
                                                    : p[y - (1 << k) + 1][k];
}
struct line {
  int x, y;
  line(int a = 0, int b = 0) {
    x = a;
    y = b;
  }
} now;
bool judge(line a, int b) {
  int lca = LCA(a.x, a.y);
  return (LCA(a.x, b) == b || LCA(a.y, b) == b) && LCA(lca, b) == lca;
}
line merge(line a, line b) {
  if (a.x == -1) return a;
  if (b.x == -1) return b;
  if (!a.x) return b;
  if (!b.x) return a;
  int t[4] = {a.x, a.y, b.x, b.y};
  for (int i = 0; i < 4; i++)
    for (int j = i + 1; j < 4; j++) {
      bool FLAG = 1;
      for (int k = 0; k < 4 && FLAG; k++) FLAG &= judge(line(t[i], t[j]), t[k]);
      if (FLAG) return line(t[i], t[j]);
    }
  return line(-1, -1);
}
struct node {
  int l, r;
  line tmp;
} Tree[N * 4];
void pushup(int x) {
  Tree[x].tmp = merge(Tree[x * 2].tmp, Tree[x * 2 + 1].tmp);
}
void build(int x, int l, int r) {
  Tree[x] = (node){l, r};
  if (l == r) {
    if (l < n)
      Tree[x].tmp = line(id[l], id[l]);
    else
      Tree[x].tmp = line(-1, -1);
    return;
  }
  int mid = (l + r) >> 1;
  build(x * 2, l, mid);
  build(x * 2 + 1, mid + 1, r);
  pushup(x);
}
void modify(int x, int pos) {
  if (Tree[x].l == Tree[x].r)
    return Tree[x].tmp = line(id[pos], id[pos]), void();
  int mid = (Tree[x].l + Tree[x].r) >> 1;
  if (pos <= mid)
    modify(x * 2, pos);
  else
    modify(x * 2 + 1, pos);
  pushup(x);
}
int query(int x) {
  if (Tree[x].l == Tree[x].r) return Tree[x].l;
  line tmp = merge(Tree[x * 2].tmp, now);
  if (tmp.x != -1) return now = tmp, query(x * 2 + 1);
  return query(x * 2);
}
int main() {
  lg[1] = 0;
  for (int i = 2; i <= 400000; i++) lg[i] = lg[i >> 1] + 1;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    id[a[i] = Getint()] = i;
  }
  for (int i = 2; i <= n; i++) addedge(Getint(), i);
  dfs(1, 0);
  for (int i = 1; i <= 2 * n; i++) p[i][0] = st[i];
  for (int j = 1; j <= 19; j++)
    for (int i = 1; i + (1 << j) - 1 <= 2 * n; i++)
      if (dep[p[i][j - 1]] < dep[p[i + (1 << j - 1)][j - 1]])
        p[i][j] = p[i][j - 1];
      else
        p[i][j] = p[i + (1 << j - 1)][j - 1];
  build(1, 0, n);
  Q = Getint();
  while (Q--) {
    int op = Getint(), x, y;
    if (op == 1) {
      x = Getint();
      y = Getint();
      swap(id[a[x]], id[a[y]]);
      swap(a[x], a[y]);
      modify(1, a[x]);
      modify(1, a[y]);
    } else {
      now = line();
      cout << query(1) << "\n";
    }
  }
}
