#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define mid ((l+r)>>1)
using namespace std;
const int N = 1e6+10;
inline int read(){
int ref=0,x=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')x=-1;ch=getchar();}
while(isdigit(ch)){ref=ref*10+ch-'0';ch=getchar();}
return ref*x;
}
int n,m;
int rt[N],val[N],tot;
int a[N];
struct tree{
int val,ls,rs;
}t[N<<4];
void build(int &x,int l,int r){
x=++tot;
if(l==r){
t[x].val=a[l];
return ;
}
build(t[x].ls,l,mid);
build(t[x].rs,mid+1,r);
}
void updata(int &x,int last,int l,int r,int pos,int k){
x=++tot;
t[x]=t[last];
if(l==r){
t[x].val=k;
return ;
}
if(pos<=mid) updata(t[x].ls,t[last].ls,l,mid,pos,k);
else updata(t[x].rs,t[last].rs,mid+1,r,pos,k);
}
int query(int x,int l,int r,int pos){
if(l==r) return t[x].val;
if(pos<=mid) return query(t[x].ls,l,mid,pos);
else return query(t[x].rs,mid+1,r,pos);
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++) a[i]=read();
build(rt[0],1,n);
for(int i=1;i<=m;i++){
int op,x,y,z;
x=read(),op=read();
if(op==1){
y=read(),z=read();
updata(rt[i],rt[x],1,n,y,z);
}
else {
y=read();
rt[i]=rt[x];
int ans=query(rt[x],1,n,y);
printf("%d\n",ans);
}
}
return 0;
}