#include<bits/stdc++.h>
#define cint const int
#define uint unsigned int
#define cuint const unsigned int
#define ll long long
#define cll const long long
#define ull unsigned long long
#define cull const unsigned long long
#define sh short
#define csh const short
#define ush unsigned short
#define cush const unsigned short
using namespace std;
int read()
{
int x=0,zf=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')zf=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch-'0');
ch=getchar();
}
return x*zf;
}
int n,q;
int a[1000001];
namespace T{
struct node{
int l,r,ls,rs,num;
};
vector<node>t;
int tot=-1;
int rt[1000001];
int new_ver()
{
t.push_back(node{0,0,0,0,0});
return ++tot;
}
int Build(cint l,cint r)
{
cint p=new_ver();
t[p].l=l;
t[p].r=r;
if(l==r)
{
t[p].num=a[l];
return p;
}
cint mid=l+r>>1;
t[p].ls=Build(l,mid);
t[p].rs=Build(mid+1,r);
return p;
}
void build()
{
rt[0]=Build(1,n);
}
int Update(cint q,cint x,cint y)
{
if(t[q].l>x||t[q].r<x)return q;
cint p=new_ver();
t[p]=t[q];
if(t[p].l==x&&t[p].r==x)
{
t[p].num=y;
return p;
}
t[p].ls=Update(t[p].ls,x,y);
t[p].rs=Update(t[p].rs,x,y);
return p;
}
void update(cint t,cint s,cint x,cint y)
{
rt[t]=Update(rt[s],x,y);
}
int Ask(cint p,cint x)
{
if(t[p].l>x||t[p].r<x)return 0;
if(t[p].l==x&&t[p].r==x)return t[p].num;
return (Ask(t[p].ls,x)|Ask(t[p].rs,x));
}
int ask(cint t,cint s,cint x)
{
rt[t]=rt[s];
return Ask(rt[t],x);
}
}
void query(cint t)
{
cint s=read(),op=read();
if(op==1)
{
cint id=read(),x=read();
T::update(t,s,id,x);
}
else
{
cint id=read();
printf("%d\n",T::ask(t,s,id));
}
}
int main()
{
T::new_ver();
n=read();
q=read();
for(int i=1;i<=n;++i)
{
a[i]=read();
}
T::build();
for(int i=1;i<=q;++i)query(i);
return 0;
}