#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int ret = 0, flag = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') flag = -1;
    ch = getchar();
  }
  while ('0' <= ch && ch <= '9') {
    ret = ret * 10 + (ch - '0');
    ch = getchar();
  }
  return flag * ret;
}
const int maxn = 2e5 + 7;
vector<int> son[maxn];
int p[maxn], q[maxn], In[maxn], Out[maxn], _cnt = 0, Log = 0;
int fa[maxn][20], depth[maxn], vis = 0;
pair<int, int> Zero = make_pair(0, 0);
bool IsAncestor(int u, int v) { return In[u] <= In[v] && Out[u] >= Out[v]; }
void DFS(int st) {
  In[st] = ++_cnt;
  for (int x : son[st]) {
    fa[x][0] = st;
    depth[x] = depth[st] + 1;
    DFS(x);
  }
  Out[st] = ++_cnt;
}
void _init(int n) {
  for (int i = 1; i <= n; i <<= 1) {
    Log++;
    for (int j = 1; j <= n; j++) {
      fa[j][Log] = fa[fa[j][Log - 1]][Log - 1];
    }
  }
}
int LCA(int u, int v) {
  if (u == v) return u;
  if (depth[u] < depth[v]) swap(u, v);
  for (int i = Log; i >= 0; i--) {
    if (depth[u] - (1 << i) >= depth[v]) {
      u = fa[u][i];
    }
  }
  for (int i = Log; i >= 0; i--) {
    if (fa[u][i] == fa[v][i]) continue;
    u = fa[u][i], v = fa[v][i];
  }
  return u == v ? u : fa[u][0];
}
int MaxDepth(pair<int, int> st) {
  int u = st.first, v = st.second;
  return depth[u] > depth[v] ? u : v;
}
pair<int, int> Deal(int x, int y, int z) {
  if (!x || !y || !z) return Zero;
  if (depth[x] < depth[y]) swap(x, y);
  if (IsAncestor(y, x)) {
    if (IsAncestor(x, z))
      return make_pair(z, y);
    else if (IsAncestor(y, z) && IsAncestor(z, x))
      return make_pair(x, y);
    else if (!IsAncestor(y, z))
      return make_pair(x, z);
    else if (LCA(x, z) == y)
      return make_pair(x, z);
    else
      return Zero;
  } else {
    if (IsAncestor(x, z))
      return make_pair(z, y);
    else if (IsAncestor(y, z))
      return make_pair(x, z);
    else {
      int lca = LCA(x, y);
      if (IsAncestor(lca, z) && (IsAncestor(z, x) || IsAncestor(z, y)))
        return make_pair(x, y);
      else
        return Zero;
    }
  }
}
pair<int, int> Merge(pair<int, int> x, pair<int, int> y) {
  x = Deal(x.first, x.second, y.first);
  x = Deal(x.first, x.second, y.second);
  return x;
}
struct SegmentTree {
  pair<int, int> val[maxn << 2], rcd;
  int askAns;
  void BuildTree(int l, int r, int pos) {
    if (l == r) {
      val[pos] = make_pair(q[l], q[r]);
      return;
    }
    int mid = (l + r) >> 1;
    BuildTree(l, mid, pos << 1);
    BuildTree(mid + 1, r, pos << 1 | 1);
    val[pos] = Merge(val[pos << 1], val[pos << 1 | 1]);
  }
  void Update(int l, int r, int pos, int u, int v) {
    if (l == r) {
      val[pos] = make_pair(v, v);
      return;
    }
    int mid = (l + r) >> 1;
    if (u <= mid)
      Update(l, mid, pos << 1, u, v);
    else
      Update(mid + 1, r, pos << 1 | 1, u, v);
    val[pos] = Merge(val[pos << 1], val[pos << 1 | 1]);
  }
  bool Query(int l, int r, int pos) {
    pair<int, int> tmp = Merge(rcd, val[pos]);
    if (tmp.first != 0) {
      rcd = tmp;
      askAns = r;
      return true;
    }
    if (l == r) return false;
    int mid = (l + r) >> 1;
    if (Query(l, mid, pos << 1))
      return Query(mid + 1, r, pos << 1 | 1);
    else
      return false;
  }
  int Ask(int n) {
    rcd = make_pair(q[1], q[1]);
    askAns = 0;
    Query(1, n, 1);
    return askAns;
  }
} Tree;
int main() {
  int n = read();
  for (int i = 1; i <= n; i++) {
    p[i] = read() + 1;
    q[p[i]] = i;
  }
  for (int i = 2; i <= n; i++) {
    son[read()].push_back(i);
  }
  fa[1][0] = 1, depth[1] = 1;
  DFS(1);
  _init(n);
  Tree.BuildTree(1, n, 1);
  int Q = read();
  int op, x, y;
  while (Q--) {
    op = read();
    if (op == 1) {
      x = read();
      y = read();
      Tree.Update(1, n, 1, p[y], x);
      Tree.Update(1, n, 1, p[x], y);
      swap(p[x], p[y]);
      q[p[x]] = x, q[p[y]] = y;
    } else if (op == 2) {
      printf("%d\n", Tree.Ask(n));
    }
  }
  return 0;
}
