#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int mx = 212345;
struct Node {
  int a, b, e;
  bool f;
  Node(int a = -1, int b = -1, int e = -1, bool f = 0)
      : a(a), b(b), e(e), f(f){};
};
class lca_t {
 public:
  int n;
  int max_log, t;
  vector<int> h, in, rin, out;
  vector<vector<int>> adj, up;
  lca_t(int _n) : n(_n) {
    max_log = 0;
    while ((1 << max_log) <= n) max_log++;
    h.resize(n);
    in.resize(n);
    rin.resize(n);
    out.resize(n);
    adj.resize(n);
    up.resize(n, vector<int>(max_log));
    t = 0;
  }
  int walk(int first, int k) {
    for (int i = max_log - 1; i >= 0; i--) {
      if (k & (1 << i)) first = up[first][i];
    }
    return first;
  }
  bool anc(int first, int second) {
    return in[first] <= in[second] && out[first] >= out[second];
  }
  int lca(int first, int second) {
    if (anc(first, second)) return first;
    if (anc(second, first)) return second;
    for (int i = max_log - 1; i >= 0; i--)
      if (!anc(up[first][i], second)) first = up[first][i];
    return up[first][0];
  }
  void add(int first, int second) {
    adj[first].push_back(second);
    adj[second].push_back(first);
  }
  void dfs(int v, int p) {
    in[v] = t++;
    rin[in[v]] = v;
    up[v][0] = p;
    for (int i = 1; i < max_log; i++) up[v][i] = up[up[v][i - 1]][i - 1];
    for (int i = 0; i < (int)adj[v].size(); i++) {
      int u = adj[v][i];
      if (u == p) continue;
      h[u] = h[v] + 1;
      dfs(u, v);
    }
    out[v] = t;
  };
  void set_root(int first) {
    h[first] = 0;
    dfs(first, first);
  }
};
lca_t *t = NULL;
Node merge(Node first, Node second) {
  if (!first.f || !second.f) return Node();
  int a = first.a, b = first.b, e = first.e;
  int c = second.a, d = second.b, f = second.e;
  Node res = Node();
  if (a != e && c != f) {
    if (e == f) {
      int first = t->lca(a, c);
      int second = t->lca(b, d);
      if ((first == a || first == c) && (second == b || second == d)) {
        if (t->in[a] < t->in[c]) swap(a, c);
        if (t->in[b] < t->in[d]) swap(b, d);
        res = {a, b, e, 1};
      }
    }
  } else if (a == e && c == f) {
    int first = t->lca(a, c);
    int second = t->lca(b, d);
    if (first == second) {
      if (t->in[b] > t->in[d]) swap(b, d);
      res = {b, d, first, 1};
    }
    if ((first == a || first == c) && (second == b || second == d)) {
      int x0 = max(pair<int, int>{t->in[a], a},
                   max(pair<int, int>{t->in[b], b},
                       max(pair<int, int>{t->in[c], c},
                           pair<int, int>{t->in[d], d})))
                   .second;
      int y0 = min(pair<int, int>{t->in[a], a},
                   min(pair<int, int>{t->in[b], b},
                       min(pair<int, int>{t->in[c], c},
                           pair<int, int>{t->in[d], d})))
                   .second;
      res = {y0, x0, y0, 1};
    }
  } else {
    if (a == e) swap(a, c), swap(b, d), swap(e, f);
    if (t->in[c] < t->out[e] && t->in[c] >= t->in[e]) {
      int first = t->lca(a, d);
      int second = t->lca(b, d);
      if (first == a || first == d) {
        res = {max(pair<int, int>{t->in[a], a}, pair<int, int>{t->in[d], d})
                   .second,
               b, e, 1};
      }
      if (second == b || second == d) {
        res = {a,
               max(pair<int, int>{t->in[b], b}, pair<int, int>{t->in[d], d})
                   .second,
               e, 1};
      }
    }
  }
  return res;
}
Node tree[4 * mx];
void upd(Node first, int pos, int l, int r, int on = 1) {
  if (l + 1 == r) {
    tree[on] = first;
    return;
  }
  int m = l + r >> 1;
  if (pos < m)
    upd(first, pos, l, m, 2 * on);
  else
    upd(first, pos, m, r, 2 * on + 1);
  tree[on] = merge(tree[2 * on], tree[2 * on + 1]);
}
int query(Node first, int l, int r, int on = 1) {
  if (merge(tree[on], first).f == 1) return r - l;
  if (l + 1 == r) return first.f ? merge(first, tree[on]).f : tree[on].f;
  int m = l + r >> 1;
  if ((first.f ? merge(first, tree[2 * on]) : tree[2 * on]).f == 1)
    return m - l +
           query(first.f ? merge(first, tree[2 * on]) : tree[2 * on], m, r,
                 2 * on + 1);
  else
    return query(first, l, m, 2 * on);
}
int p[mx];
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &p[i]);
  }
  t = new lca_t(n + 1);
  for (int i = 2; i <= n; i++) {
    int first;
    scanf("%d", &first);
    t->add(first, i);
  }
  t->set_root(1);
  for (int i = 1; i <= n; i++) {
    upd(Node(i, i, i, 1), p[i], 0, n);
  }
  int q;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    int t;
    scanf("%d", &t);
    if (t == 2) {
      printf("%d\n", query(Node(), 0, n));
    } else {
      int a, b;
      scanf("%d%d", &a, &b);
      swap(p[a], p[b]);
      upd(Node(a, a, a, 1), p[a], 0, n);
      upd(Node(b, b, b, 1), p[b], 0, n);
    }
  }
}
