#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
const int logn = 20;
const int INF = 1e9 + 7;
int n, q, tl, clk;
int a[maxn], b[maxn];
int que[maxn << 1], in[maxn], out[maxn], dfn[maxn], dep[maxn];
vector<int> g[maxn];
class SparseTable {
 public:
  int lg[maxn << 1];
  pair<int, int> dat[maxn << 1][logn];
  inline void init() {
    for (int i = (0); i < (tl); ++i) dat[i][0] = make_pair(dep[que[i]], que[i]);
    for (int j = (1); j < (logn); ++j)
      for (int i = (0); i < (tl); ++i)
        dat[i][j] = min(dat[i][j - 1], (i + (1 << j - 1) < tl)
                                           ? dat[i + (1 << j - 1)][j - 1]
                                           : make_pair(INF, -1));
    lg[1] = 0;
    for (int i = (2); i <= (tl); ++i)
      lg[i] = lg[i - 1] + ((1 << lg[i - 1] + 1) <= i);
    return;
  }
  inline int lca(int u, int v) {
    int l = dfn[u], r = dfn[v];
    if (l > r) swap(l, r);
    int k = lg[r - l + 1];
    return min(dat[l][k], dat[r - (1 << k) + 1][k]).second;
  }
} st;
inline bool inSubtree(int r, int u) {
  return in[u] >= in[r] && out[u] <= out[r];
};
inline bool onPath(int u, int r, int v) {
  return inSubtree(r, u) && inSubtree(u, v);
}
class SegmentTree {
 private:
  static const int siz = 262144;
  inline void apply(int x, int v) {
    ver[x][0] = v;
    ver[x][1] = -1;
    return;
  }
  inline void merge(int *verp, int *verq, int *verx) {
    if (verp[0] == n) {
      verx[0] = verq[0], verx[1] = verq[1];
      return;
    } else if (!~verp[0] || !~verq[0]) {
      verx[0] = verx[1] = -1;
      return;
    }
    vector<int> nver;
    for (int i = (0); i < (2); ++i)
      if (~verp[i]) nver.push_back(verp[i]);
    for (int i = (0); i < (2); ++i)
      if (~verq[i]) nver.push_back(verq[i]);
    verx[0] = -1;
    for (int i = (0); i < (nver.size()); ++i) {
      for (int j = (i); j < (nver.size()); ++j) {
        int r = st.lca(nver[i], nver[j]), f = true;
        for (int k = (0); k < (nver.size()); ++k)
          if (k != i && k != j)
            f &= (onPath(nver[k], r, nver[i]) || onPath(nver[k], r, nver[j]));
        if (f) {
          verx[0] = nver[i], verx[1] = nver[j];
          break;
        }
      }
      if (~verx[0]) break;
    }
    return;
  }
  inline void pushUp(int x) {
    int p = x << 1, q = x << 1 | 1;
    if (!~ver[p][0] || !~ver[q][0])
      ver[x][0] = -1;
    else
      merge(ver[p], ver[q], ver[x]);
    return;
  }

 public:
  int ver[siz << 1][2], segDep[siz << 1];
  inline int size() { return siz; }
  inline void build(int x, int l, int r, int d) {
    segDep[x] = d;
    if (l == r) {
      apply(x, l > n ? -1 : b[l]);
      return;
    }
    int md = l + r >> 1;
    build(x << 1, l, md, d + 1);
    build(x << 1 | 1, md + 1, r, d + 1);
    pushUp(x);
    return;
  }
  inline void update(int x, int y) {
    int u = a[y] + siz, v = a[x] + siz;
    apply(u, x);
    apply(v, y);
    for (u >>= 1, v >>= 1; u && v; u >>= 1, v >>= 1) {
      pushUp(u);
      if (u != v) pushUp(v);
    }
    swap(a[y], a[x]);
    return;
  }
  inline int query(int x, int l, int r, int *ans) {
    if (l == r) {
      merge(ans, ver[x], ans);
      if (~ans[0]) return min(l, n - 1);
      return min(l - 1, n - 1);
    }
    int md = l + r >> 1;
    int tmpans[2];
    merge(ans, ver[x << 1], tmpans);
    if (~tmpans[0]) {
      for (int i = (0); i < (2); ++i) ans[i] = tmpans[i];
      return query(x << 1 | 1, md + 1, r, ans);
    } else
      return query(x << 1, l, md, ans);
  }
} seg;
int ans[2];
inline void dfs(int u, int p) {
  dfn[u] = tl;
  que[tl++] = u;
  in[u] = clk++;
  if (~p) dep[u] = dep[p] + 1;
  for (int i = (0); i < (g[u].size()); ++i) {
    int v = g[u][i];
    if (v == p) continue;
    dfs(v, u);
    que[tl++] = u;
  }
  out[u] = clk;
  return;
}
int main() {
  scanf("%d", &n);
  for (int i = (0); i < (n); ++i) scanf("%d", a + i), b[a[i]] = i;
  for (int i = (1); i < (n); ++i) {
    int d;
    scanf("%d", &d);
    --d;
    g[d].push_back(i);
  }
  dfs(0, -1);
  st.init();
  seg.build(1, 0, seg.size() - 1, 0);
  scanf("%d", &q);
  for (int i = (0); i < (q); ++i) {
    int t;
    scanf("%d", &t);
    --t;
    if (!t) {
      int x, y;
      scanf("%d%d", &x, &y);
      --x;
      --y;
      seg.update(x, y);
    } else {
      ans[0] = ans[1] = n;
      printf("%d\n", seg.query(1, 0, seg.size() - 1, ans) + 1);
    }
  }
  return 0;
}
