#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
constexpr auto MOD = 1000000007LL;
constexpr auto LINF = (1LL << 60);
constexpr auto INF = 2147483647LL;
constexpr auto PI = 3.1415926535897932384626433;
constexpr auto EPS = 1E-9;
template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> p) {
  out << p.first << ' ' << p.second;
  return out;
}
template <typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &p) {
  in >> p.first >> p.second;
  return in;
}
template <typename T>
istream &operator>>(istream &in, vector<T> &v) {
  for (auto &x : v) in >> x;
  return in;
}
template <typename T>
ostream &operator<<(ostream &out, vector<T> v) {
  for (int i = 0; i < v.size(); i++)
    out << v[i] << (i + 1 == v.size() ? '\n' : ' ');
  out.flush();
  return out;
}
struct Node {
  int u, v, l, valid;
  Node() {
    u = -1;
    valid = 1;
  }
} T[200010 << 2];
int n, p[200010], par[20][200010], tab[20][200010 << 1], en[200010], ed[200010],
    d[200010], inv[200010];
vi euler;
vi e[200010];
void dfs(int now) {
  en[now] = euler.size();
  euler.push_back(now);
  for (auto x : e[now]) {
    d[x] = d[now] + 1;
    dfs(x);
    euler.push_back(now);
  }
  ed[now] = euler.size();
}
int lca(int u, int v) {
  if (en[u] > en[v]) swap(u, v);
  u = en[u];
  v = ed[v];
  int dx = v - u;
  int h = sizeof(int) * 8 - __builtin_clz(dx) - 1;
  if (d[tab[h][u]] < d[tab[h][v - (1 << h)]])
    return tab[h][u];
  else
    return tab[h][v - (1 << h)];
}
bool isin(int u, int v) { return (en[v] >= en[u] && ed[v] <= ed[u]); }
void maintain(Node &father, Node lhs, Node rhs) {
  if (lhs.u == -1) {
    father = rhs;
    return;
  }
  if (rhs.u == -1) {
    father = lhs;
    return;
  }
  father.valid = lhs.valid & rhs.valid;
  father.u = father.v = father.l = 1;
  if (not father.valid) return;
  if (isin(lhs.u, lhs.v) && isin(rhs.u, rhs.v)) {
    father.valid = true;
    if (isin(lhs.u, rhs.u) && (isin(lhs.v, rhs.v) || isin(rhs.v, lhs.v))) {
      father.u = (d[lhs.u] < d[rhs.u] ? lhs.u : rhs.u);
      father.v = (d[lhs.v] < d[rhs.v] ? rhs.v : lhs.v);
      father.l = father.u;
      return;
    }
    if (isin(lhs.u, rhs.u) && lca(rhs.u, lhs.v) == lhs.u) {
      father.u = rhs.v;
      father.v = lhs.v;
      father.l = lhs.u;
      return;
    }
    swap(lhs, rhs);
    if (isin(lhs.u, rhs.u) && (isin(lhs.v, rhs.v) || isin(rhs.v, lhs.v))) {
      father.u = (d[lhs.u] < d[rhs.u] ? lhs.u : rhs.u);
      father.v = (d[lhs.v] < d[rhs.v] ? rhs.v : lhs.v);
      father.l = father.u;
      return;
    }
    if (isin(lhs.u, rhs.u) && lca(rhs.u, lhs.v) == lhs.u) {
      father.u = rhs.v;
      father.v = lhs.v;
      father.l = lhs.u;
      return;
    }
    if (not isin(lhs.u, rhs.u) && not isin(rhs.u, lhs.u)) {
      father.u = lhs.v;
      father.v = rhs.v;
      father.l = lca(father.u, father.v);
      return;
    }
    father.valid = false;
    return;
  }
  if (isin(lhs.u, lhs.v) ^ isin(rhs.u, rhs.v)) {
    if (not isin(lhs.u, lhs.v)) {
      swap(lhs, rhs);
    }
    if (isin(rhs.l, lhs.u)) {
      if (isin(lhs.v, rhs.v) || isin(rhs.v, lhs.v)) {
        father.u = rhs.u;
        father.v = (d[lhs.v] < d[rhs.v] ? rhs.v : lhs.v);
        father.l = rhs.l;
        return;
      }
      swap(rhs.u, rhs.v);
      if (isin(lhs.v, rhs.v) || isin(rhs.v, lhs.v)) {
        father.u = rhs.u;
        father.v = (d[lhs.v] < d[rhs.v] ? rhs.v : lhs.v);
        father.l = rhs.l;
        return;
      }
    }
    father.valid = false;
    return;
  }
  if (lhs.l == rhs.l) {
    if ((isin(lhs.u, rhs.u) || isin(rhs.u, lhs.u)) &&
        (isin(lhs.v, rhs.v) || isin(rhs.v, lhs.v))) {
      father.u = (d[lhs.u] < d[rhs.u] ? rhs.u : lhs.u);
      father.v = (d[lhs.v] < d[rhs.v] ? rhs.v : lhs.v);
      father.l = lca(father.u, father.v);
      return;
    }
    swap(rhs.u, rhs.v);
    if ((isin(lhs.u, rhs.u) || isin(rhs.u, lhs.u)) &&
        (isin(lhs.v, rhs.v) || isin(rhs.v, lhs.v))) {
      father.u = (d[lhs.u] < d[rhs.u] ? rhs.u : lhs.u);
      father.v = (d[lhs.v] < d[rhs.v] ? rhs.v : lhs.v);
      father.l = lca(father.u, father.v);
      return;
    }
    father.valid = false;
    return;
  }
  father.valid = false;
  return;
}
void build(int id = 1, int l = 0, int r = n) {
  if (l + 1 == r) {
    T[id].u = T[id].v = T[id].l = inv[l];
    T[id].valid = 1;
    return;
  }
  build(id << 1, l, l + r >> 1);
  build(id << 1 | 1, l + r >> 1, r);
  maintain(T[id], T[id << 1], T[id << 1 | 1]);
  return;
}
void upd(int x, int id = 1, int l = 0, int r = n) {
  if (x >= r || l >= x + 1) {
    return;
  }
  if (l + 1 == r) {
    T[id].u = T[id].v = T[id].l = inv[l];
    T[id].valid = 1;
    return;
  }
  upd(x, id << 1, l, l + r >> 1);
  upd(x, id << 1 | 1, l + r >> 1, r);
  maintain(T[id], T[id << 1], T[id << 1 | 1]);
  return;
}
int ask(Node ret, int id = 1, int l = 0, int r = n) {
  Node tmp;
  if (l + 1 == r) {
    maintain(tmp, ret, T[id]);
    return (l + tmp.valid);
  }
  maintain(tmp, ret, T[id << 1]);
  if (tmp.valid) {
    return ask(tmp, id << 1 | 1, l + r >> 1, r);
  } else {
    return ask(ret, id << 1, l, l + r >> 1);
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> p[i];
    inv[p[i]] = i;
  }
  for (int i = 2; i <= n; i++) {
    cin >> par[0][i];
    e[par[0][i]].push_back(i);
  }
  par[0][1] = 1;
  dfs(1);
  for (int j = 0; j < euler.size(); j++) tab[0][j] = euler[j];
  for (int i = 1; i < 20; i++) {
    for (int j = 1; j <= n; j++) {
      par[i][j] = par[i - 1][par[i - 1][j]];
    }
    for (int j = 0; j < euler.size(); j++) {
      if (d[tab[i - 1][j]] < d[tab[i - 1][j + (1 << (i - 1))]])
        tab[i][j] = tab[i - 1][j];
      else
        tab[i][j] = tab[i - 1][j + (1 << (i - 1))];
    }
  }
  build();
  int q;
  cin >> q;
  for (int i = 0, op, x, y; i < q; i++) {
    cin >> op;
    if (op == 1) {
      cin >> x >> y;
      swap(p[x], p[y]);
      inv[p[x]] = x;
      inv[p[y]] = y;
      upd(p[x]);
      upd(p[y]);
    } else if (op == 2) {
      Node query;
      query.u = -1;
      cout << ask(query) << endl;
    } else
      assert(false);
  }
  return 0;
}
