#include <bits/stdc++.h>
using namespace std;
long long int mod = 1e9 + 7;
const double error = 1e-7;
const double PI = acos(-1);
mt19937 rng(
    (unsigned int)chrono::system_clock::now().time_since_epoch().count());
inline long long int MOD(long long int x, long long int m = mod) {
  if (x < m) return x;
  return x % m;
}
const int inf = 1e9;
const long long int infl = 1e18 + 1;
const int nmax = 1e5 + 5;
vector<int> adj[nmax];
const int lg_max = 18;
int depth[nmax];
int parent[nmax][lg_max];
void dfs(int root, int par) {
  depth[root] = depth[par] + 1;
  parent[root][0] = par;
  for (int i = 1; i < lg_max; i++)
    parent[root][i] = parent[parent[root][i - 1]][i - 1];
  for (int x : adj[root]) dfs(x, root);
  return;
}
inline int LCA(int u, int v) {
  if (depth[u] > depth[v]) swap(u, v);
  int lift = depth[v] - depth[u];
  for (int i = 0; lift != 0; lift >>= 1, i++)
    if (lift & 1) v = parent[v][i];
  if (u == v) return u;
  for (int i = lg_max - 1; i >= 0; i--)
    if (parent[u][i] != parent[v][i]) u = parent[u][i], v = parent[v][i];
  return parent[u][0];
}
struct node {
  node *lc, *rc;
  int sum;
  node(int s = 0) {
    sum = s;
    lc = rc = NULL;
  }
};
node *build(int l, int r) {
  if (l == r) {
    return new node(0);
  }
  node *n = new node(0);
  int mid = (l + r) >> 1;
  n->lc = build(l, mid);
  n->rc = build(mid + 1, r);
  return n;
}
node *update(node *n, int l, int r, int k) {
  if (r < k || k < l) return n;
  if (l == r) return new node(n->sum + 1);
  node *t = new node(0);
  int mid = (l + r) >> 1;
  t->lc = update(n->lc, l, mid, k);
  t->rc = update(n->rc, mid + 1, r, k);
  t->sum = t->lc->sum + t->rc->sum;
  return t;
}
int query(node *n, int l, int r, int L, int R) {
  if (r < L || R < l) return 0;
  if (L <= l && r <= R) return n->sum;
  int mid = (l + r) >> 1;
  int p = query(n->lc, l, mid, L, R);
  int q = query(n->rc, mid + 1, r, L, R);
  return p + q;
}
void print(node *n, int l, int r) {
  cout << l << " " << r << " : ";
  cout << n->sum << "\n";
  if (l == r) {
    return;
  }
  int mid = (l + r) >> 1;
  print(n->lc, l, mid);
  print(n->rc, mid + 1, r);
}
node *roots[nmax];
struct queryS {
  int a, b, k, y1, y2;
};
int destroyed[nmax];
vector<queryS> queries;
int q;
int cnt(int u, int a, int b) { return depth[u] - query(roots[u], 1, q, a, b); }
void treedfs(int root) {
  roots[root] = update(roots[parent[root][0]], 1, q, destroyed[root]);
  for (int x : adj[root]) treedfs(x);
  return;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  ;
  int n;
  cin >> n;
  int root;
  for (int i = 1; i <= n; i++) {
    int x;
    cin >> x;
    if (x == 0)
      root = i;
    else
      adj[x].push_back(i);
  }
  dfs(root, 0);
  cin >> q;
  for (int i = 1; i <= n; i++) destroyed[i] = q + 1;
  for (int i = 1; i <= q; i++) {
    int t;
    cin >> t;
    if (t == 1) {
      int u;
      cin >> u;
      destroyed[u] = i;
    } else {
      int a, b, k, y;
      cin >> a >> b >> k >> y;
      queries.push_back({a, b, k, y + 1, i});
    }
  }
  roots[0] = build(1, q);
  treedfs(root);
  for (auto Q : queries) {
    int c = LCA(Q.a, Q.b);
    int y1 = Q.y1, y2 = Q.y2;
    if (destroyed[Q.a] < y1 || destroyed[Q.a] > y2) Q.k++;
    int pc = cnt(c, y1, y2);
    int pa = cnt(Q.a, y1, y2);
    int pb = cnt(Q.b, y1, y2);
    int extra = (destroyed[c] >= y1 && destroyed[c] <= y2) ? 0 : 1;
    if (pa - pc < Q.k) {
      Q.k -= pa - pc;
      if (pb - pc + extra < Q.k) {
        cout << -1 << "\n";
        continue;
      }
      int u = Q.b;
      for (int i = lg_max - 1; i >= 0; i--) {
        if (cnt(parent[u][i], y1, y2) - pc + extra >= Q.k) u = parent[u][i];
      }
      if (u == Q.b) {
        cout << -1 << "\n";
        continue;
      }
      cout << u << "\n";
    } else {
      int u = Q.a;
      for (int i = lg_max - 1; i >= 0; i--) {
        int extra =
            (destroyed[parent[u][i]] < y1 || destroyed[parent[u][i]] > y2) ? 1
                                                                           : 0;
        if (parent[u][i] == 0) extra = 0;
        if (pa - cnt(parent[u][i], y1, y2) + extra < Q.k) u = parent[u][i];
      }
      u = parent[u][0];
      cout << u << "\n";
    }
  }
}
