#include <stdio.h>
#define nmax 500002
using namespace std;
int n,m,a[nmax],arb[nmax];
void q_max(int nod, int a, int b);
void _update(int nod, int x,int y);
int _max;
int li,ls,dest,val;
void citire()
{
freopen("arbint.in","r",stdin);
scanf("%d %d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
}
void main_loop()
{
for (int i=0;i<m;i++)
{
int t,x,y;
scanf("%d %d %d",&t,&x,&y);
if (t)
{
dest = x;
val = y;
_update(1,1,n);
}
else
{
_max = a[x];
li = x; ls = y;
q_max(1,1,n);
printf("%d\n",_max);
}
}
}
int max(int a, int b)
{
return a>b?a:b;
}
void _update(int nod, int x,int y)
{
int left = (nod << 1),
right = (nod << 1) +1,
mid = (x+y)>>1;
if (x>y)
return ;
if (x == y && x == dest)
{
arb[nod] = val;
a[dest] = val;
return;
}
if (dest <= mid)
_update(left,x,mid);
else
_update(right,mid+1,y);
arb[nod] = max(arb[left],arb[right]);
}
// nod contine intervalul [a,b]
// intervalul cautat este [x,y]
void q_max(int nod, int a, int b)
{
int left = (nod << 1),
right = (nod << 1) +1,
mid = (a+b)>>1;
if (a>b)
return;
// daca intervalul [x,y] este inclus in [a,b]
if (a >= li && b <= ls)
{
// verificam maximul
_max = arb[nod]>_max?arb[nod]:_max;
return;
}
if (li<=mid && ls>=left)
q_max(left,a,mid);
if (ls>mid && li<=right)
q_max(right,mid+1,b);
}
void build(int nod,int x, int y)
{
int left = (nod << 1),
right = (nod << 1) +1,
mid = (x+y)>>1;
if (x>y)
return;
if (x == y)
{
arb[nod] = a[x];
return;
}
build(left,x,mid);
build(right,mid+1,y);
arb[nod] = max(arb[left],arb[right]);
}
int main()
{
freopen("arbint.out","w",stdout);
citire();
build(1,1,n);
main_loop();
return 0;
}