#include <fstream>
#include <vector>
#include <cmath>
const int INF = 1e9+10;
using namespace std;
ifstream cin("arbint.in");
ofstream cout("arbint.out");
vector <int> arb;
vector <int> v;
int n, m, var;
/*void print_r(vector <auto> v)
{
for(int i = 0; i<v.size(); i++)
{
cout<<v[i]<<' ';
}
cout<<'\n';
}*/
void coutarb(vector <int> arb, int st, int dr, int ind)
{
if(st>dr) return;
cout<<st<<'-'<<dr<<" = "<<arb[ind]<<'\n';
if(st==dr) return;
int mid = (st + dr) / 2;
coutarb(arb, st, mid, ind*2);
coutarb(arb, mid+1, dr, ind*2+1);
}
void buildArb(vector <int> &arb, vector <int> v, int st, int dr, int ind)
{
if(st>dr || arb[ind]) return;
if(st==dr)
{
arb[ind] = v[st];
return;
}
int mid = (st + dr) / 2;
buildArb(arb, v, st, mid, ind*2), buildArb(arb, v, mid+1, dr, ind*2+1);
arb[ind]=max(arb[ind*2], arb[ind*2+1]);
}
void buildArb(vector <int> &arb, vector <int> v)
{
arb[0] = v.size();
buildArb(arb, v, 0, v.size()-1, 1);
}
void update(vector <int> &arb, int pos, int val, int st, int dr, int ind)
{
if(st==dr) arb[ind] = val;
if(st>=dr) return;
int mid = (st + dr) / 2;
if(mid>=pos) update(arb, pos, val, st, mid, ind*2);
else update(arb, pos, val, mid+1, dr, ind*2+1);
arb[ind]=max(arb[ind*2], arb[ind*2+1]);
}
void update(vector <int> &arb, int pos, int val)
{
update(arb, pos, val, 0, arb[0]-1, 1);
}
int query(vector <int> arb, int a, int b, int st, int dr, int ind)
{
if(st>dr) return -INF;
int mid = (st + dr) / 2, maxim=-INF;
if(st>=a && dr<=b) return arb[ind];
if(a<=mid) maxim=max(maxim, query(arb, a, b, st, mid, ind*2));
if(b>mid) maxim=max(maxim, query(arb, a, b, mid+1, dr, ind*2+1));
return maxim;
}
int query(vector <int> arb, int a, int b)
{
return query(arb, a, b, 0, arb[0]-1, 1);
}
void readit()
{
cin>>n>>m;
arb.resize(n*4);
v.reserve(n);
for(int i = 0; i < n; i++)
cin>>var, v.push_back(var);
buildArb(arb, v);
}
int main()
{
readit();
for(int i = 1; i<=m; i++)
{
int qry, a, b;
cin>>qry>>a>>b;
if(qry) update(arb, a-1, b);
else cout<<query(arb, a-1, b-1)<<'\n';
}
return 0;
}