#include <fstream>
#include <vector>
using namespace std;
ifstream cin("arbint.in");
ofstream cout("arbint.out");
using VI = vector<int>;
int n, q;
VI arb;
void Build(int x, int st, int dr);
int Query(int x, int st, int dr, int a, int b);
void Update(int x, int st, int dr, int a, int b);
int main()
{
cin >> n >> q;
arb = VI(n * 4 + 1);
Build(1, 1, n);
int op, a, b;
while(q--)
{
cin >> op >> a >> b;
if (op == 0)
cout << Query(1, 1, n, a, b) << '\n';
else
Update(1, 1, n, a, b);
}
}
int Query(int x, int st, int dr, int a, int b)
{
if (st >= a && dr <= b)
return arb[x];
int mx = 0;
int mj = (st + dr) / 2;
if (a <= mj)
mx = Query(2 * x, st, mj, a, b);
if (b > mj)
mx = max(mx, Query(2 * x + 1, mj + 1, dr, a, b));
return mx;
}
void Update(int x, int st, int dr, int a, int b)
{
if (st == dr)
{
arb[x] = b;
return;
}
int mj = (st + dr) / 2;
if (a <= mj)
Update(2 * x, st, mj, a, b);
else
Update(2 * x + 1, mj + 1, dr, a, b);
arb[x] = max(arb[2 * x], arb[2 * x + 1]);
}
void Build(int x, int st, int dr)
{
if (st == dr)
{
cin >> arb[x];
return;
}
int mj = (st + dr) / 2;
Build(2 * x, st, mj);
Build(2 * x + 1, mj + 1, dr);
arb[x] = max(arb[2 * x], arb[2 * x + 1]);
}