#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
template<class T>
using ordered_set = tree<T, null_type, less<T>,
rb_tree_tag, tree_order_statistics_node_update>;
template<class T, class U>
using ordered_map = tree<T, U, less<T>, rb_tree_tag,
tree_order_statistics_node_update>;
#define ll long long
#define ld long double
#define MOD 998244353
#define MAXN 250000
#define SIZE 100
#define pb push_back
ll power(ll a, ll b){
if (b == 0) return 1;
ll res = power(a, b / 2);
if (b % 2 == 1) return res * res % MOD * a % MOD;
return res * res % MOD;
// if (b % 2 == 1) return res * res * a;
// return res * res;
}
int idx = 1;
void dfs(vector<vector<int>> &g, int curr, int par, vector<int> &order, vector<int> &childs, vector<int> &posToOrder){
vector<pair<int, int>> arr;
for (auto &p : g[curr]){
if (par == p) continue;
arr.pb({childs[p], p});
}
sort(arr.begin(), arr.end());
for (auto &p : arr){
dfs(g, p.second, curr, order, childs, posToOrder);
}
order[idx] = curr;
posToOrder[curr] = idx;
idx++;
}
void getChildNum(vector<vector<int>> &g, int curr, int par, vector<int> &childs){
int minChild = curr;
for (auto &p : g[curr]){
if (p == par) continue;
getChildNum(g, p, curr, childs);
minChild = min(minChild, childs[p]);
}
childs[curr] = minChild;
}
int updet(vector<int> &segTree, int idx, int l, int r, int upVal){
if (upVal == 0) return 0;
if (l == r){
segTree[idx] = 1;
return l;
}
int mid = (r - l) / 2 + l;
int take = min(upVal, (mid - l + 1) - segTree[idx * 2]);
int last = updet(segTree, idx * 2, l, mid, take);
upVal -= take;
if (upVal != 0){
last = updet(segTree, idx * 2 + 1, mid + 1, r, upVal);
}
segTree[idx] = segTree[idx * 2] + segTree[idx * 2 + 1];
return last;
}
int query(vector<int> &segTree, int idx, int l, int r, int pos){
if (l == r) return segTree[idx];
int mid = (r - l) / 2 + l;
if (pos <= mid) return query(segTree, idx * 2, l, mid, pos);
return query(segTree, idx * 2 + 1, mid + 1, r, pos);
}
void delet(vector<int> &segTree, int idx, int l, int r, int deletPos){
if (l == r){
segTree[idx] = 0;
return;
}
int mid = (r - l) / 2 + l;
if (deletPos <= mid) delet(segTree, idx * 2, l, mid, deletPos);
else delet(segTree, idx * 2 + 1, mid + 1, r, deletPos);
segTree[idx] = segTree[idx * 2] + segTree[idx * 2 + 1];
}
signed main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n, q;
cin >> n >> q;
vector<vector<int>> parents(n + 1, vector<int>(20, 0));
vector<vector<int>> g(n + 1);
int root;
for (int i = 1; i <= n; i++){
int a;
cin >> a;
parents[i][0] = a;
if (a == 0) root = i;
else{
g[a].pb(i);
}
}
// cout << "EY\n";
for (int j = 1; j < 20; j++){
for (int i = 1; i <= n; i++){
int nextPos = parents[i][j - 1];
parents[i][j] = parents[nextPos][j - 1];
}
}
// cout << "EY\n";
vector<bool> balls(n + 1, 0);
vector<int> order(n + 1, -1);
vector<int> posToOrder(n + 1);
vector<int> childs(n + 1, n + 5);
// cout << "TES\n";
getChildNum(g, root, 0, childs);
dfs(g, root, 0, order, childs, posToOrder);
// for (int i = 1; i <= n; i++){
// cout << order[i] << " ";
// }
// cout << " AAA\n";
vector<int> segTree(4 * n, 0);
// cout << "TES\n";
while(q--){
int type, k;
cin >> type >> k;
if (type == 1){
int last = updet(segTree, 1, 1, n, k);
cout << order[last] << "\n";
}
else{
int cnt = 0;
for (int i = 19; i >= 0; i--){
int next = parents[k][i];
if (next == 0) continue;
// cout << next << " HEHE\n";
// cout << posToOrder[next] << " AWAAW\n";
int val = query(segTree, 1, 1, n, posToOrder[next]);
if (val){
cnt += (1 << i);
k = next;
}
}
delet(segTree, 1, 1, n, posToOrder[k]);
cout << cnt << "\n";
}
}
return 0;
}