#include <fstream>
using namespace std;
int arbore[400005],vec[100005];
ifstream cin("arbint.in");
ofstream cout("arbint.out");
//ifstream cin("in");
//ofstream cout("out");
void build(int nod, int x,int y);
void update(int nod,int x,int y ,int poz, int val );
int query(int nod, int x, int y ,int a, int b);
int main() {
int n, m;
cin >>n >>m;
int tip, a ,b;
for(int i =1 ;i <=n ;i ++)
{
cin >> vec[i];
}
build(1, 1, n);
for(int i = 1 ;i <= m ;i ++)
{
cin >> tip >> a >> b;
if(tip)
update(1, 1, n, a, b);
else
cout <<query(1, 1, n, a , b )<<'\n';
}
return 0;
}
void build(int nod, int x,int y)
{
if(y == x)
{
arbore[nod] = vec[x];
return;
}
int mij = (x + y)/ 2;
build(nod * 2 , x, mij);
build(nod* 2 + 1, mij + 1, y);
arbore[nod] = max(arbore[nod * 2], arbore[nod * 2 + 1]);
}
void update(int nod,int x,int y ,int poz, int val )
{
if(x == y) {
arbore[nod] = val;
return;
}
int mij = (x + y) / 2;
if(poz <= mij)
{
update(nod * 2, x, mij, poz, val);
}
else
update(nod * 2 + 1, mij + 1, y, poz,val);
arbore[nod] = max(arbore[nod * 2], arbore[nod * 2 + 1]);
}
int query(int nod, int x, int y ,int a, int b)
{
int val1= 0 , val2 = 0;
if(a <= x and y <= b)
{
return arbore[nod];
}
int mij = (x + y )/ 2;
if(a <= mij)
{
val1 = query(nod * 2, x, mij, a ,b);
}
if(mij < b)
val2 = query(nod* 2 + 1, mij + 1, y, a, b);
return max(val1,val2);
}