#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<deque>
#include<set>
#include<stack>
#include<bitset>
#include<cstring>
#define ll long long
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a<b)?a:b)
using namespace std;
const int INF=0x3f3f3f3f,N=1000010;
int rt[20*N],a[N];
struct hjt_segment{
int lc[20*N],rc[20*N],val[20*N],size;
void build(int *a,int &rt,int l,int r){
rt=++size;
if(l==r){val[rt]=a[l];return;}
int mid=(l+r)>>1;
build(a,lc[rt],l,mid);
build(a,rc[rt],mid+1,r);
}
inline void ins(int &rt,int pre,int l,int r,int q,int v){
rt=++size;
lc[rt]=lc[pre],rc[rt]=rc[pre],val[rt]=val[pre];
if(l==r){val[rt]=v;return;}
int mid=(l+r)>>1;
if(q<=mid) ins(lc[rt],lc[pre],l,mid,q,v);
else ins(rc[rt],rc[pre],mid+1,r,q,v);
}
inline int query(int rt,int l,int r,int q){
if(l==r) return val[rt];
int mid=(l+r)>>1;
if(q<=mid) return query(lc[rt],l,mid,q);
else return query(rc[rt],mid+1,r,q);
}
}t;
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
t.build(a,rt[0],1,n);
for(int i=1;i<=m;i++){
int pre,opt,x;
scanf("%d%d%d",&pre,&opt,&x);
if(opt==1){int v;scanf("%d",&v);t.ins(rt[i],rt[pre],1,n,x,v);}
if(opt==2){printf("%d\n",t.query(rt[pre],1,n,x));rt[i]=rt[pre];}
}
return 0;
}