#include <bits/stdc++.h>
char gc() {
  static char buf[100000], *p1 = buf, *p2 = buf;
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
using namespace std;
template <class T>
void read(T &x) {
  T f = 1;
  x = 0;
  char c = gc();
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = gc();
  }
  while ('0' <= c && c <= '9') {
    x = x * 10 + c - '0';
    c = gc();
  }
  x *= f;
}
template <class T>
void print(T x, char c) {
  if (x < 0) putchar('-'), x = -x;
  int s[20], top = 0;
  while (s[++top] = x % 10, x /= 10)
    ;
  while (top) putchar(s[top--] + '0');
  putchar(c);
}
int n, m, RT, cnt, h[100005];
struct Edge {
  int to, next;
} a[100005];
void Add(int x, int y) {
  cnt++;
  a[cnt].to = y;
  a[cnt].next = h[x];
  h[x] = cnt;
}
int dep[100005], top[100005], siz[100005], son[100005], fa[100005], dam[100005];
void dfs1(int x, int f) {
  fa[x] = f;
  dep[x] = dep[f] + 1;
  siz[x] = 1;
  for (int i = h[x]; i; i = a[i].next) {
    int y = a[i].to;
    dfs1(y, x);
    siz[x] += siz[y];
    if (siz[y] > siz[son[x]]) son[x] = y;
  }
}
int step, fp[100005], dfn[100005];
void dfs2(int x, int tp) {
  top[x] = tp;
  dfn[++step] = x;
  fp[x] = step;
  if (son[x]) dfs2(son[x], tp);
  for (int i = h[x], y; i; i = a[i].next)
    if (!top[y = a[i].to]) dfs2(y, y);
}
int all, rt0, root[100005], lc[100005 << 5], rc[100005 << 5], sum[100005 << 5];
void build(int &rt, int l, int r) {
  rt = ++all;
  sum[rt] = r - l + 1;
  if (l == r) return;
  int mid = l + r >> 1;
  build(lc[rt], l, mid);
  build(rc[rt], mid + 1, r);
}
void range(int &rt, int l, int r, int pos) {
  if (!rt) rt = ++all;
  sum[rt]++;
  if (l == r) return;
  int mid = l + r >> 1;
  pos <= mid ? range(lc[rt], l, mid, pos) : range(rc[rt], mid + 1, r, pos);
}
void modify(int &rt, int pre, int l, int r, int pos) {
  rt = ++all;
  lc[rt] = lc[pre], rc[rt] = rc[pre], sum[rt] = sum[pre] + 1;
  if (l == r) return;
  int mid = l + r >> 1;
  pos <= mid ? modify(lc[rt], lc[pre], l, mid, pos)
             : modify(rc[rt], rc[pre], mid + 1, r, pos);
}
int lca(int x, int y) {
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]]) swap(x, y);
    x = fa[top[x]];
  }
  return dep[x] < dep[y] ? x : y;
}
int ask(int rt, int zero, int l, int r, int L, int R) {
  if (R < l || r < L) return 0;
  if (L <= l && r <= R) return sum[rt] - sum[zero];
  int mid = l + r >> 1;
  return ask(lc[rt], lc[zero], l, mid, L, R) +
         ask(rc[rt], rc[zero], mid + 1, r, L, R);
}
int findup(int x, int y, int d) {
  int res = 0;
  while (top[x] != top[y]) {
    res += ask(root[d], rt0, 1, n, fp[top[x]], fp[x]);
    x = fa[top[x]];
  }
  return res + ask(root[d], rt0, 1, n, fp[y] + 1, fp[x]);
}
int K;
int Findl(int rt, int zero, int l, int r, int L, int R) {
  if (R < l || r < L) return -1;
  if (L <= l && r <= R) {
    int tmp = sum[rt] - sum[zero];
    if (tmp < K) return K -= tmp, -1;
  }
  if (l == r) return dfn[l];
  int mid = l + r >> 1;
  int res = Findl(lc[rt], lc[zero], l, mid, L, R);
  if (~res) return res;
  return Findl(rc[rt], rc[zero], mid + 1, r, L, R);
}
int Findr(int rt, int zero, int l, int r, int L, int R) {
  if (R < l || r < L) return -1;
  if (L <= l && r <= R) {
    int tmp = sum[rt] - sum[zero];
    if (tmp < K) return K -= tmp, -1;
  }
  if (l == r) return dfn[l];
  int mid = l + r >> 1;
  int res = Findr(rc[rt], rc[zero], mid + 1, r, L, R);
  if (~res) return res;
  return Findr(lc[rt], lc[zero], l, mid, L, R);
}
void deal(int x, int y, int k, int d) {
  int z = lca(x, y), res = 0, tp = 0, tmp;
  static int sl[100005], sr[100005];
  while (top[x] != top[z]) {
    tmp = res + ask(root[d], rt0, 1, n, fp[top[x]], fp[x]);
    if (tmp >= k)
      return K = k - res,
             print(Findr(root[d], rt0, 1, n, fp[top[x]], fp[x]), '\n');
    res = tmp;
    x = fa[top[x]];
  }
  tmp = res + ask(root[d], rt0, 1, n, fp[z] + 1, fp[x]);
  if (tmp >= k)
    return K = k - res,
           print(Findr(root[d], rt0, 1, n, fp[z] + 1, fp[x]), '\n');
  k -= tmp;
  res = 0;
  x = y;
  while (top[x] != top[z])
    tp++, sl[tp] = fp[top[x]], sr[tp] = fp[x], x = fa[top[x]];
  tp++, sl[tp] = fp[z], sr[tp] = fp[x];
  for (int i = tp; i > 1; --i) {
    tmp = res + ask(root[d], rt0, 1, n, sl[i], sr[i]);
    if (tmp >= k)
      return K = k - res, print(Findl(root[d], rt0, 1, n, sl[i], sr[i]), '\n');
    res = tmp;
  }
  if (sl[1] < sr[1])
    return K = k - res,
           print(Findl(root[d], rt0, 1, n, sl[1], sr[1] - 1), '\n');
  puts("-1");
}
int main() {
  read(n);
  for (int i = 1; i <= n; ++i) {
    read(fa[i]);
    if (fa[i] == 0)
      RT = i;
    else
      Add(fa[i], i);
  }
  dfs1(RT, 0);
  dfs2(RT, RT);
  read(m);
  build(root[0], 1, n);
  for (int i = 1, opt, x, y, k, d; i <= m; ++i) {
    read(opt);
    if (opt == 1)
      read(x), dam[x] = i, modify(root[i], root[i - 1], 1, n, fp[x]),
               range(rt0, 1, n, fp[x]);
    else {
      root[i] = root[i - 1];
      read(x), read(y), read(k), read(d);
      deal(x, y, k + (dam[x] <= d), d);
    }
  }
}
