#include <bits/stdc++.h>
using namespace std;
const int maxn = 110000;
int n, Q, rt;
struct Talt {
  int tot;
  struct Tsqy {
    int s;
    Tsqy *l;
    inline void set(Tsqy *_l, int _s) { l = _l, s = _s; }
  } * pos[maxn], buf[maxn * 2];
  inline void add(int a, int b) {
    buf[++tot].set(pos[a], b), pos[a] = buf + tot;
  }
} alt;
struct Tseg {
  int S;
  Tseg *l, *r;
  inline void update() { S = l->S + r->S; }
} * St[maxn], *Null;
struct Tmemory {
  int n;
  Tseg a[maxn * 30];
  inline Tseg *operator()() {
    a[n].l = a[n].r = Null;
    return a + n++;
  }
} newS;
Tseg *add(Tseg *p, int a, int v, int x = 0, int y = n) {
  Tseg *q = newS();
  if (x + 1 == y) return q->S = p->S + v, q;
  int mid = x + y >> 1;
  a < mid ? (q->l = add(p->l, a, v, x, mid), q->r = p->r)
          : (q->r = add(p->r, a, v, mid, y), q->l = p->l);
  return q->update(), q;
}
int get(Tseg *p, Tseg *q, int a, int b, int x = 0, int y = n) {
  if (x == a && y == b) return q->S - p->S;
  int mid = x + y >> 1;
  return b <= mid   ? get(p->l, q->l, a, b, x, mid)
         : a >= mid ? get(p->r, q->r, a, b, mid, y)
                    : get(p->l, q->l, a, mid, x, mid) +
                          get(p->r, q->r, mid, b, mid, y);
}
namespace Ninit {
void init() {
  int i, a1;
  scanf("%d", &n);
  for (i = 1; i <= n; ++i) {
    scanf("%d", &a1);
    if (!a1)
      rt = i;
    else
      alt.add(a1, i);
  }
}
}  // namespace Ninit
namespace Nsolve {
int A[maxn];
struct Ttre {
  int F[maxn][20], D[maxn], T[maxn];
  void set() {
    int i, j;
    for (j = 1; j <= 17; ++j)
      for (i = 1; i <= n; ++i) F[i][j] = F[F[i][j - 1]][j - 1];
  }
  int lca(int a, int b) {
    for (; T[a] != T[b]; a = F[T[a]][0])
      if (D[T[a]] < D[T[b]]) swap(a, b);
    return D[a] < D[b] ? a : b;
  }
} Tt;
struct Tseq {
  static int n;
  int l, r;
} B[maxn];
int Tseq::n;
namespace Nprep {
int G[maxn], S[maxn], A[maxn];
void dfs(int x) {
  Talt::Tsqy *p;
  int i;
  B[x].l = B[0].n++, S[x] = 1, G[x] = 0;
  for (p = alt.pos[x]; p; p = p->l) {
    Tt.D[p->s] = Tt.D[x] + 1, Tt.F[p->s][0] = x;
    dfs(p->s), S[x] += S[p->s];
    if (!G[x] || S[p->s] > S[G[x]]) G[x] = p->s;
  }
  B[x].r = B[0].n;
  if (x == rt)
    for (i = x; i; i = G[i]) Tt.T[i] = x;
  for (p = alt.pos[x]; p; p = p->l)
    if (p->s != G[x])
      for (i = p->s; i; i = G[i]) Tt.T[i] = p->s;
}
void solve() {
  int i;
  Tt.D[rt] = 1, dfs(rt), Tt.set();
  Null = newS(), St[0] = Null;
  Null->S = 0, Null->l = Null->r = Null;
}
}  // namespace Nprep
namespace Nfind {
int x, y;
int length(int a, int t) {
  if (Tt.D[a] < Tt.D[t]) return 0;
  return (Tt.D[a] - get(St[x], St[y], 0, B[a].l + 1)) -
         (Tt.D[t] - get(St[x], St[y], 0, B[t].l + 1)) + (A[t] <= x ? 1 : 0);
}
int bound(int a, int b, int k) {
  int i, Fc;
  for (i = 17; i >= 0; --i)
    if (Tt.D[Tt.F[a][i]] > Tt.D[b]) {
      Fc = length(Tt.F[a][0], Tt.F[a][i]);
      if (Fc < k) a = Tt.F[a][i], k -= Fc;
    }
  return Tt.F[a][0];
}
int found(int a, int b, int k, int _x, int _y) {
  int t = Tt.lca(a, b);
  x = _x, y = _y;
  if (length(Tt.F[a][0], t) + length(Tt.F[b][0], t) - (A[t] <= x ? 1 : 0) < k)
    return -1;
  if (length(Tt.F[a][0], t) >= k)
    return bound(a, Tt.F[t][0], k);
  else {
    k -= length(Tt.F[a][0], t);
    return bound(b, t, length(Tt.F[b][0], t) + (A[t] <= x ? 0 : 1) - k);
  }
}
}  // namespace Nfind
using Nfind::found;
void solve() {
  Tseg *pSt;
  int t, k0, ci, ai, bi, ki, yi;
  Nprep::solve();
  scanf("%d", &Q);
  for (pSt = St[0], t = 1; t <= Q; ++t) {
    scanf("%d", &k0);
    if (k0 == 1) {
      scanf("%d", &ci), A[ci] = t;
      if (B[ci].r < n) pSt = add(pSt, B[ci].r, -1);
      St[t] = pSt = add(pSt, B[ci].l, 1);
    } else {
      scanf("%d%d%d%d", &ai, &bi, &ki, &yi), St[t] = pSt;
      printf("%d\n", found(ai, bi, ki, yi, t));
    }
  }
}
}  // namespace Nsolve
int main() {
  Ninit::init();
  Nsolve::solve();
  return 0;
}
