#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
int n,m,x,y;
int valori[100100];
class arbore_pe_intervale
{
private:
int solution;
public:
void creat(int pos, int left, int right);
void update(int pos , int left , int right);
void query(int pos , int left , int right);
int arbore[400100];
int getsolution();
arbore_pe_intervale();
void setsolution();
};
arbore_pe_intervale::arbore_pe_intervale()
{
solution = 0;
}
void arbore_pe_intervale :: setsolution()
{
solution = 0;
}
int arbore_pe_intervale:: getsolution()
{
return solution;
}
void arbore_pe_intervale::creat(int pos ,int left ,int right)
{
if(left == right)
{
arbore[pos] = valori[left];
return;
}
int middle = (left + right) / 2;
creat(2 * pos, left , middle);
creat(2 * pos + 1 , middle + 1 , right);
arbore[pos] =max(arbore[2*pos],arbore[2*pos+1]);
}
void arbore_pe_intervale::query(int pos , int left ,int right)
{
if(x <= left && y >= right)
{
solution = max(arbore[pos],solution);
return;
}
int middle = (left + right)/2;
if( x <= middle)
query(2*pos , left , middle);
if( y > middle)
query(2*pos +1 , middle + 1, right);
}
void arbore_pe_intervale::update(int pos , int left , int right)
{
if(left == right)
{
arbore[pos] = y;
return;
}
int middle = (left + right )/2;
if(x <= middle)
update(2*pos,left,middle);
else
update(2*pos+1,middle + 1,right);
arbore[pos]= max(arbore[2*pos],arbore[2*pos+1]);
}
void read()
{
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
arbore_pe_intervale object;
scanf("%d %d",&n,&m);
for(int i = 1; i <= n ; i++)
scanf("%d ",&valori[i]);
object.creat(1,1,n);
for(int i = 0 ; i < m ; i++)
{
bool task;
int a;
scanf("%d %d %d",&a,&x,&y);
task = a;
if(task == false)
{
object.query(1,1,n);
int sol = object.getsolution();
printf("%d\n",sol);
}
else
{
object.setsolution();
object.update(1,1,n);
}
}
}
int main()
{
read();
return 0;
}