#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:10000000")
using namespace std;
const int maxn = 100500, maxlog = 17;
struct Node {
  int L, R;
  int val;
};
struct Tree {
  Tree() {}
  Tree(const vector<int>& a) {
    szTree = 1;
    while (szTree < a.size()) {
      szTree *= 2;
    }
    nodes.assign(szTree * 2, Node());
    for (int i = szTree; i < szTree; i++) {
      nodes[i].val = a[i - szTree];
    }
    for (int i = szTree; i < szTree * 2; i++) nodes[i].L = nodes[i].R = i;
    for (int i = szTree - 1; i >= 1; i--) {
      nodes[i].L = i + i;
      nodes[i].R = i + i + 1;
      nodes[i].val = nodes[i + i].val + nodes[i + i + 1].val;
    }
    versions.assign(1, 0);
    roots.assign(1, 1);
  }
  int upd(int v, int cl, int cr, int pos, int add) {
    int mid = (cl + cr) / 2;
    int newV = nodes.size();
    Node w = nodes[v];
    nodes.push_back(w);
    if (cl == cr) {
      w.val += add;
      w.L = w.R = newV;
    } else {
      if (pos <= mid) {
        w.L = upd(nodes[v].L, cl, mid, pos, add);
      } else {
        w.R = upd(nodes[v].R, mid + 1, cr, pos, add);
      }
      w.val = nodes[w.L].val + nodes[w.R].val;
    }
    nodes[newV] = w;
    return newV;
  }
  int getQ(int root, int l, int r) { return get(root, 0, szTree - 1, l, r); }
  vector<int> roots;
  vector<Node> nodes;
  vector<int> versions;
  int szTree;

 private:
  int get(int v, int cl, int cr, int l, int r) {
    if (cl > r || cr < l) return 0;
    if (cl >= l && cr <= r) return nodes[v].val;
    int mid = (cl + cr) / 2;
    return get(nodes[v].L, cl, mid, l, r) + get(nodes[v].R, mid + 1, cr, l, r);
  }
};
vector<int> g[maxn];
int parent[maxlog][maxn];
int szSubTree[maxn];
vector<Tree> trees;
int tin[maxn], tout[maxn], timer = 0;
void dfs_start(int v) {
  tin[v] = timer++;
  szSubTree[v] = 1;
  for (int t = 0; t < (int)(g[v].size()); ++t) {
    int to = g[v][t];
    dfs_start(to);
    szSubTree[v] += szSubTree[to];
  }
  tout[v] = timer++;
}
vector<vector<int> > listVert;
int col[maxn], num[maxn];
void dfs_hl(int v, bool inTree) {
  if (!inTree) {
    listVert.push_back(vector<int>());
  }
  listVert.back().push_back(v);
  col[v] = listVert.size() - 1;
  num[v] = listVert.back().size() - 1;
  int maxq = -1, numBig = -1;
  for (int i = 0; i < (int)(g[v].size()); ++i) {
    int to = g[v][i];
    if (szSubTree[to] > maxq) {
      maxq = szSubTree[to];
      numBig = to;
    }
  }
  if (numBig != -1) {
    dfs_hl(numBig, true);
  }
  for (int i = 0; i < (int)(g[v].size()); ++i) {
    int to = g[v][i];
    if (to != numBig) dfs_hl(to, false);
  }
}
int getLca(int v, int u) {
  if (tin[v] > tin[u]) swap(v, u);
  if (tin[v] <= tin[u] && tout[v] >= tout[u]) return v;
  for (int i = maxlog - 1; i >= 0; i--) {
    int newV = parent[i][v];
    if (tin[newV] <= tin[u] && tout[newV] >= tout[u]) {
    } else
      v = newV;
  }
  return parent[0][v];
}
int getKth(int v, int lca, int& k, int y) {
  int ans = -1;
  while (true) {
    Tree& curTree = trees[col[v]];
    int curRoot = curTree.roots.back();
    int prevRoot = curTree.roots[upper_bound(curTree.versions.begin(),
                                             curTree.versions.end(), y) -
                                 curTree.versions.begin() - 1];
    if (col[v] == col[lca]) {
      int availVert =
          (num[v] - num[lca] + 1) - (curTree.getQ(curRoot, num[lca], num[v]) -
                                     curTree.getQ(prevRoot, num[lca], num[v]));
      if (k <= availVert) {
        int le = num[lca], ri = num[v] + 1;
        while (le + 1 < ri) {
          int mid = (le + ri) / 2;
          if ((num[v] - mid + 1) - (curTree.getQ(curRoot, mid, num[v]) -
                                    curTree.getQ(prevRoot, mid, num[v])) >
              k - 1)
            le = mid;
          else
            ri = mid;
        }
        ans = listVert[col[v]][le];
        break;
      } else
        k -= availVert;
      break;
    } else {
      int availVert = num[v] + 1 -
                      (curTree.getQ(curRoot, 0, num[v]) -
                       curTree.getQ(prevRoot, 0, num[v]));
      if (k <= availVert) {
        int le = 0, ri = num[v] + 1;
        while (le + 1 < ri) {
          int mid = (le + ri) / 2;
          if ((num[v] - mid + 1) - (curTree.getQ(curRoot, mid, num[v]) -
                                    curTree.getQ(prevRoot, mid, num[v])) >
              k - 1)
            le = mid;
          else
            ri = mid;
        }
        ans = listVert[col[v]][le];
        break;
      } else
        k -= availVert;
      v = parent[0][listVert[col[v]][0]];
    }
  }
  return ans;
}
int gangsta[maxn];
int main() {
  int root;
  int n, m;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int x;
    scanf("%d", &x);
    parent[0][i] = x;
    if (x == 0)
      root = i;
    else
      g[x].push_back(i);
  }
  parent[0][root] = root;
  for (int i = 1; i < maxlog; i++)
    for (int j = 1; j <= n; j++) parent[i][j] = parent[i - 1][parent[i - 1][j]];
  dfs_start(root);
  dfs_hl(root, false);
  trees.resize(listVert.size());
  for (int i = 0; i < (int)(trees.size()); ++i) {
    trees[i] = Tree(vector<int>(listVert[i].size(), 0));
  }
  scanf("%d", &m);
  for (int year = 1; year <= m; year++) {
    int type;
    scanf("%d", &type);
    if (type == 1) {
      int c;
      scanf("%d", &c);
      gangsta[c] = year;
      Tree& curTree = trees[col[c]];
      int newRoot =
          curTree.upd(curTree.roots.back(), 0, curTree.szTree - 1, num[c], 1);
      curTree.roots.push_back(newRoot);
      curTree.versions.push_back(year);
    } else {
      int v, u, k, y;
      scanf("%d%d%d%d", &v, &u, &k, &y);
      int lca = getLca(v, u);
      int ans = -1;
      if (v == lca) {
        int tmp = 1e9;
        int w = getKth(u, lca, tmp, y);
        if (gangsta[v] <= y) tmp++;
        if (gangsta[u] <= y) tmp++;
        if (1e9 - tmp >= k) {
          int cK = (1e9 - tmp) - k + 1;
          if (gangsta[u] <= y) cK++;
          ans = getKth(u, lca, cK, y);
          assert(ans != -1);
        }
      }
      if (u == lca) {
        if (gangsta[v] <= y) k++;
        ans = getKth(v, lca, k, y);
        if (ans == u) ans = -1;
      }
      if (v != lca && u != lca) {
        if (gangsta[v] <= y) k++;
        ans = getKth(v, lca, k, y);
        if (ans == -1) {
          int tmp = 1e9;
          int w = getKth(u, lca, tmp, y);
          if (gangsta[u] <= y) tmp++;
          if (gangsta[lca] <= y) tmp++;
          if (1e9 - tmp >= k) {
            int cK = (1e9 - tmp) - k + 1;
            if (gangsta[u] <= y) cK++;
            ans = getKth(u, lca, cK, y);
            assert(ans != lca);
            assert(ans != -1);
          }
        }
      }
      printf("%d\n", ans);
    }
  }
  return 0;
}
