#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
const int INF = (1 << 30);
const int nMax = 100005 * 20;
class arbint
{
public:
arbint(int sz)
{
n = sz;
int lg = ceil(log2(n));
arb = new int[1 << lg + 1];
}
inline void Update(int ind, int val)
{
Update(ind, val, 1, 1, n);
}
inline int MaxQuery(int start, int finish)
{
return MaxQuery(start, finish, 1, n, 1);
}
inline int MinQuery(int start, int finish)
{
return MinQuery(start, finish, 1, n, 1);
}
private:
int *arb;
int n;
void Update(int ind, int val, int nod, int st, int dr)
{
if(st == dr)
{
arb[nod] = val;
return;
}
int mid = (st + dr) / 2;
if(ind <= mid)
Update(ind, val, nod * 2, st, mid);
else
Update(ind, val, nod * 2 + 1, mid + 1, dr);
arb[nod] = max(arb[nod*2], arb[nod*2+1]);
}
int MaxQuery(int start, int finish, int st, int dr, int nod = 1)
{
if(start <= st && finish >= dr)
return arb[nod];
int mid = (st + dr) / 2;
int ret = -INF;
if(start <= mid)
ret = max(ret, MaxQuery(start, finish, st, mid, nod * 2));
if(finish > mid)
ret = max(ret, MaxQuery(start, finish, mid + 1, dr, nod * 2 + 1));
return ret;
}
int MinQuery(int start, int finish, int st, int dr, int nod = 1)
{
if(start <= st && finish >= dr)
return arb[nod];
int mid = (st + dr) / 2;
int ret = -INF;
if(start <= mid)
ret = min(ret, MinQuery(start, finish, st, mid, nod * 2));
if(finish > mid)
ret = min(ret, MinQuery(start, finish, mid + 1, dr, nod * 2 + 1));
return ret;
}
};
int main()
{
int n, m;
ifstream in("arbint.in");
ofstream out("arbint.out");
in >> n >> m;
arbint arb(n);
int x;
for(int i = 1; i <= n; ++i)
{
in >> x;
arb.Update(i, x);
}
int c, a, b;
for(int i = 1; i <= m; ++i)
{
in >> c >> a >> b;
if(c == 0)
out << arb.MaxQuery(a, b) << "\n";
else
arb.Update(a, b);
}
return 0;
}