#include<iostream>
using namespace std;
struct node
{
int val;
int l,r;
}tree[40000010];
int root[1000010],cnt;
int a[1000010];
int build(int now,int start,int end)
{
if(start==end)
{
tree[now].val=a[start];
return now;
}
int mid=(start+end)/2;
tree[now].l=build(++cnt,start,mid);
tree[now].r=build(++cnt,mid+1,end);
return now;
}
int update(int old,int now,int start,int end,int idx,int val)
{
if(start==end)
{
tree[now].val=val;
return now;
}
int mid=(start+end)/2;
if(idx<=mid)
{
tree[now].l=update(tree[old].l,++cnt,start,mid,idx,val);
tree[now].r=tree[old].r;
return now;
}
else
{
tree[now].l=tree[old].l;
tree[now].r=update(tree[old].r,++cnt,mid+1,end,idx,val);
return now;
}
}
int query(int now,int start,int end,int idx)
{
if(start==end)
{
return tree[now].val;
}
int mid=(start+end)/2;
if(idx<=mid)
return query(tree[now].l,start,mid,idx);
else
return query(tree[now].r,mid+1,end,idx);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
root[0]=build(++cnt,1,n);
int v,opt,idx,val;
for(int i=1;i<=m;i++)
{
cin>>v>>opt>>idx;
if(opt==1)
{
cin>>val;
root[i]=update(root[v],++cnt,1,n,idx,val);
}
else
{
cnt++;
root[i]=cnt;
tree[cnt].l=tree[root[i-1]].l;
tree[cnt].r=tree[root[i-1]].r;
cout<<query(root[v],1,n,idx)<<'\n';
}
}
return 0;
}