#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
struct Node {
  int l, r;
  int cnt;
  int ls, rs;
} p[N * 20];
int root[N], size;
int fa[N][22], yr[N], n, m;
vector<int> e[N];
int f[N], t[N], k[N], y[N], cmd[N], dep[N];
int rt;
void init() {
  size = 0;
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &fa[i][0]);
    if (fa[i][0] == 0) {
      rt = i;
      continue;
    }
    e[fa[i][0]].push_back(i);
  }
  scanf("%d", &m);
  for (int i = 1, c; i <= m; ++i) {
    scanf("%d", &cmd[i]);
    if (cmd[i] == 1) {
      scanf("%d", &c);
      yr[c] = i;
    } else
      scanf("%d %d %d %d", f + i, t + i, k + i, y + i);
  }
  for (int s = 1; s < 20; ++s)
    for (int i = 1; i <= n; ++i) fa[i][s] = fa[fa[i][s - 1]][s - 1];
}
int build(int l, int r) {
  int now = size++;
  p[now].l = l, p[now].r = r, p[now].cnt = 0;
  if (l == r) return now;
  int mid = (l + r) >> 1;
  p[now].ls = build(l, mid);
  p[now].rs = build(mid + 1, r);
  return now;
}
int insert(int c, int ps) {
  int now = size++;
  p[now] = p[c], p[now].cnt++;
  if (p[now].l == p[now].r) return now;
  int mid = (p[now].l + p[now].r) >> 1;
  if (ps <= mid)
    p[now].ls = insert(p[c].ls, ps);
  else
    p[now].rs = insert(p[c].rs, ps);
  return now;
}
void build_tree(int x, int depth) {
  dep[x] = depth;
  root[x] = insert(root[fa[x][0]], yr[x]);
  for (int i = 0; i < (int)e[x].size(); ++i) build_tree(e[x][i], depth + 1);
}
int LCA(int a, int b) {
  if (dep[a] > dep[b]) swap(a, b);
  if (dep[a] < dep[b]) {
    int delta = dep[b] - dep[a];
    for (int i = 0; i < 20; ++i)
      if (delta & (1 << i)) b = fa[b][i];
  }
  if (a != b) {
    for (int i = 19; i >= 0; --i)
      if (fa[a][i] != fa[b][i] && fa[a][i] && fa[b][i])
        a = fa[a][i], b = fa[b][i];
    a = fa[a][0];
  }
  return a;
}
int find(int c1, int c2, int b, int e) {
  if (p[c1].r < b || p[c1].l > e) return 0;
  if (b <= p[c1].l && p[c1].r <= e) return p[c1].cnt - p[c2].cnt;
  return find(p[c1].ls, p[c2].ls, b, e) + find(p[c1].rs, p[c2].rs, b, e);
}
int cal(int x, int y, int last, int cur) {
  return dep[x] - dep[y] + 1 - find(root[x], root[fa[y][0]], last, cur);
}
int search(int x, int y, int ks, int last, int cur, int iter) {
  if (x == y) return x;
  if (y == fa[x][0]) {
    if (ks == 2)
      return y;
    else {
      if (last <= yr[x] && yr[x] <= cur) return y;
      return x;
    }
  }
  if (fa[x][iter] == 0 || dep[fa[x][iter]] <= dep[y])
    return search(x, y, ks, last, cur, iter - 1);
  int down = cal(x, fa[x][iter], last, cur);
  if (down >= ks) return search(x, fa[x][iter], ks, last, cur, iter - 1);
  return search(fa[fa[x][iter]][0], y, ks - down, last, cur, iter - 1);
}
void solve() {
  root[0] = build(0, m);
  build_tree(rt, 0);
  for (int i = 1; i <= m; ++i) {
    if (cmd[i] == 1) continue;
    int lca = LCA(f[i], t[i]);
    int left = cal(f[i], lca, y[i] + 1, i);
    int right = cal(t[i], lca, y[i] + 1, i);
    int lca_d = !(y[i] + 1 <= yr[lca] && yr[lca] <= i);
    int f_d = !(y[i] + 1 <= yr[f[i]] && yr[f[i]] <= i);
    int t_d = !(y[i] + 1 <= yr[t[i]] && yr[t[i]] <= i);
    if (f_d) k[i] += 1;
    if (left + right - lca_d - t_d < k[i]) {
      puts("-1");
      continue;
    }
    if (left >= k[i])
      printf("%d\n", search(f[i], lca, k[i], y[i] + 1, i, 19));
    else
      printf("%d\n", search(t[i], lca, left + right - lca_d - k[i] + 1,
                            y[i] + 1, i, 19));
  }
}
int main() {
  init();
  solve();
  return 0;
}
