#include<fstream>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<iostream>
#include<queue>
#include<bitset>
#include<set>
#include<map>
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
int arbint[5* 100010];
int vec[100010];
void create(int x, int y, int k=1)
{
if (x == y)
{
arbint[k] = vec[x];
return;
}
int mid = (x + y) / 2;
create(x, mid, k * 2);
create(mid + 1, y, k * 2 + 1);
arbint[k] = max(arbint[k * 2], arbint[k * 2 + 1]);
}
void update(int p, int x, int y, int v, int k = 1)
{
if (x == y)
{
arbint[k] = v;
return;
}
int mid = (x + y) / 2;
if (p<=mid)
{
update(p, x, mid, v, k * 2);
}
else
{
update(p, mid + 1, y, v, k * 2 + 1);
}
arbint[k] = max(arbint[k * 2], arbint[k * 2 + 1]);
}
int query(int a, int b, int x, int y, int k = 1)
{
if (a <= x && y <= b)
{
return arbint[k];
}
int mid = (x + y) / 2;
int e1 = -1, e2 = -1;
if (a <= mid)
{
e1 = query(a, b, x, mid, k * 2);
}
if (mid+1 <= b)
{
e2 = query(a, b, mid + 1, y, k * 2 + 1);
}
return max(e1, e2);
}
int main()
{
int N, Q;
in >> N >> Q;
for (int i = 1; i <= N; ++i)
{
in >> vec[i];
}
create(1, N);
for (int i = 1; i <= Q; ++i)
{
int op;
in >> op;
if (op == 0)
{
int x, y;
in >> x >> y;
out << query(x, y, 1, N, 1) << "\n";
}
else
{
int p, v;
in >> p >> v;
update(p, 1, N, v, 1);
}
}
return 0;
}