#include<bits/stdc++.h>
using namespace std;
struct node {
int ls,rs,num;
} tree[1000001];
int a[1000001],n,q,cnt,ro[1000001];
int newpoint(int k) {
cnt++;
tree[cnt]=tree[k];
return cnt;
}
int build(int l,int r,int num) {
num=++cnt;
if(l==r) {
tree[num].num=a[l];
return cnt;
}
int mid=(l+r)>>1;
tree[num].ls=build(l ,mid,tree[num].ls);
tree[num].rs=build(mid+1,r ,tree[num].rs);
return num;
}
int update(int l,int r,int p,int change,int val) {
change=newpoint(change);
if(l==r) {
tree[change].num=val;
// return change;
} else {
int mid=(l+r)>>1;
if(change<=mid)tree[change].ls=update(l ,mid,tree[change].ls,change,val);
else tree[change].rs=update(mid+1,r ,tree[change].rs,change,val);
}
return change;
}
int query(int l,int r,int change,int z1) {
// change=newpoint(change);
if(l==r) {
return tree[change].num;
// return;
}
int mid=(l+r)>>1;
if(z1<=mid)return query(l ,mid,tree[change].ls,z1);
else return query(mid+1,r ,tree[change].rs,z1);
// return;
}
int x,opt,y,z;
int main() {
cin>>n>>q;
for(int i=1; i<=n; i++) {
cin>>a[i];
}
ro[0]=build(1,n,1);
for(int i=1; i<=q; i++) {
cin>>x>>opt>>y;
if(opt==1) {
cin>>z;
ro[i]=update(1,n,ro[x],y,z);
}
if(opt==2) {
cout<<query(1,n,ro[x],y)<<endl;
ro[i]=ro[x];
}
}
return 0;
}
thk