#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
struct sd{
sd* ls;
sd* rs;
int val;
}tr[N*22];
int top=1;
int n,m,a[N];
sd *root[N];
sd *clone(sd *now){
tr[++top]=*now;
return &tr[top];
}
void build(sd *now,int l,int r){
if(l>r) return;
if(l==r) {now->val=a[l];return;}
now->ls=&tr[++top];
now->rs=&tr[++top];
int mid=(l+r)>>1;
build(now->ls,l,mid);
build(now->rs,mid+1,r);
}
sd *update(sd *now,int l,int r,int pos,const int val){
now=clone(now);
if(l==r){
now->val=val;
return now;
}
else{
int mid=(l+r)>>1;
if(pos<=mid) now->ls=update(now->ls,l,mid,pos,val);
else now->rs=update(now->rs,mid+1,r,pos,val);
}
return now;
}
int query(sd *now,int l,int r,int pos){
if(l==r) return now->val;
int mid=(l+r)>>1;
if(pos<=mid) return query(now->ls,l,mid,pos);
else return query(now->rs,mid+1,r,pos);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(&tr[1],1,n);
root[0]=&tr[1];
for(int i=1;i<=m;i++){
int v,op,pos,val;
scanf("%d%d%d",&v,&op,&pos);
if(op==1){
scanf("%d",&val);
root[i]=update(root[v],1,n,pos,val);
}
else{
root[i]=root[v];
printf("%d\n",query(root[v],1,n,pos));
}
}
return 0;
}