#include <bits/stdc++.h>
using namespace std;
struct edge {
  int v, nxt;
} e[200005 << 1];
int top = 1;
int head[200005];
void Add_Edge(int u, int v) {
  e[++top] = edge{v, head[u]};
  head[u] = top;
}
int n;
int a[200005], par[200005][21], dep[200005], size[200005];
void dfs(int u, int fa) {
  size[u] = 1;
  par[u][0] = fa;
  dep[u] = dep[fa] + 1;
  for (register int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].v;
    dfs(v, u);
    size[u] += size[v];
  }
}
void Init() {
  for (register int j = 1; j <= 20; ++j)
    for (register int i = 1; i <= n; ++i) par[i][j] = par[par[i][j - 1]][j - 1];
}
int LCA(int u, int v) {
  if (dep[u] < dep[v]) swap(u, v);
  int dis = dep[u] - dep[v];
  for (register int i = 20; i >= 0; --i)
    if (dis & (1 << i)) u = par[u][i];
  if (u == v) return u;
  for (register int i = 20; i >= 0; --i)
    if (par[u][i] ^ par[v][i]) u = par[u][i], v = par[v][i];
  return par[u][0];
}
int dist(int a, int b) {
  int lca = LCA(a, b);
  return dep[a] + dep[b] - dep[lca] * 2;
}
struct Node {
  int x, y;
};
Node tree[200005 << 2];
Node merge(Node a, int b) {
  if (a.x < 0 || b < 0) return Node{-1, -1};
  int aa = a.x, bb = a.y;
  int d1 = dist(aa, b);
  int d2 = dist(bb, b);
  int d3 = dist(bb, aa);
  if (d1 + d2 == d3) return a;
  if (d1 + d3 == d2) return Node{b, bb};
  if (d2 + d3 == d1) return Node{aa, b};
  return Node{-1, -1};
}
Node Merge(Node a, Node b) {
  if (a.x < 0 || b.x < 0) return Node{-1, -1};
  Node up1 = merge(a, b.x);
  if (up1.x < 0)
    return Node{-1, -1};
  else
    return merge(up1, b.y);
}
void Pushup(int i) { tree[i] = Merge(tree[i << 1], tree[i << 1 | 1]); }
int Index[200005];
void build(int i, int l, int r) {
  if (l == r) return tree[i] = Node{Index[l], Index[l]}, void();
  int mid = (l + r) >> 1;
  build(i << 1, l, mid);
  build(i << 1 | 1, mid + 1, r);
  Pushup(i);
}
void update(int i, int l, int r, int res) {
  if (l == r) return tree[i] = Node{Index[l], Index[l]}, void();
  int mid = (l + r) >> 1;
  if (res <= mid)
    update(i << 1, l, mid, res);
  else
    update(i << 1 | 1, mid + 1, r, res);
  Pushup(i);
}
int query(Node &mq, int i, int l, int r) {
  if (tree[i].x >= 0) {
    if (mq.x < 0) return mq = tree[i], r + 1;
    Node up1 = Merge(mq, tree[i]);
    if (up1.x >= 0) return mq = up1, r + 1;
  }
  if (l == r) return l;
  int mid = (l + r) >> 1;
  int res = query(mq, i << 1, l, mid);
  if (res <= mid)
    return res;
  else
    return query(mq, i << 1 | 1, mid + 1, r);
}
int read() {
  int x = 0;
  char c = getchar();
  int f = 1;
  while (c < '0' || c > '9') {
    if (c == '-') f = -f;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = (x << 3) + (x << 1) + c - '0';
    c = getchar();
  }
  return x * f;
}
void write(int x) {
  if (x < 0) {
    x = -x;
    putchar('-');
  }
  if (x > 9) write(x / 10);
  putchar(x % 10 + '0');
}
signed main() {
  n = read();
  for (register int i = 1; i <= n; ++i) {
    a[i] = read() + 1;
    Index[a[i]] = i;
  }
  for (register int i = 2; i <= n; ++i) {
    int fa = read();
    Add_Edge(fa, i);
  }
  dfs(1, 1);
  Init();
  build(1, 1, n);
  int q = read();
  for (register int i = 1; i <= q; ++i) {
    int type = read();
    if (type == 1) {
      int x = read(), y = read();
      swap(Index[a[x]], Index[a[y]]);
      swap(a[x], a[y]);
      update(1, 1, n, a[x]);
      update(1, 1, n, a[y]);
    } else {
      Node mq = Node{-1, -1};
      int Ans = query(mq, 1, 1, n);
      write(Ans - 1), putchar('\n');
    }
  }
  return 0;
}
