#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std;
int N,M,a[1000001];
int top;
int root[100001];
struct ne{
int l,r,v;
}tree[100001];
int xj(int n){
tree[++top]=tree[n];
return top;
}
int bulid(int l,int r,int n){
n=++top;
if(l==r){
tree[n].v=a[l];
return top;
}
int m=(l+r)/2;
tree[n].l=bulid(l,m,tree[n].l);
tree[n].r=bulid(m+1,r,tree[n].r);
return n;
}
int chance(int l,int r,int n,int v,int x){
n=xj(n);
if(l==r){
tree[n].v=v;
}else{
int m=(r+l)/2;
if(x<=m){
tree[n].l=chance(l,m,tree[n].l,v,x);
}else{
tree[n].r=chance(m+1,r,tree[n].r,v,x);
}
}
return n;
}
int find(int l,int r,int n,int x){
if(l==r){
return tree[n].v;
}else{
int m=(r+l)/2;
if(x<=m){
return find(l,m,tree[n].l,x);
}else{
return find(m+1,r,tree[n].r,x);
}
}
}
int main(){
cin >>N>>M;
for(int i=1;i<=N;i++){
cin >>a[i];
}
root[0]=bulid(1,N,0);
for(int i=1;i<=M;i++){
int v,t,loc,value;
cin >>v>>t>>loc;
if(t==1){
cin >>value;
root[i]=chance(1,N,root[v],loc,value);
}
if(t==2){
cout <<find(1,N,root[v],loc)<<endl;
}
}
return 0;
}