//
// main.cpp
// arbori de intervale
//
// Created by Vlad Calomfirescu on 14.05.2021.
//
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin ("arbint.in");
ofstream fout ("arbint.out");
int v[500009];
void update (int st, int dr, int f, int poz, int a)
{
int mij = (st + dr) / 2;
if (st == dr)
{
v[poz] = a;
return;
}
if (f > mij)
{
update (mij + 1, dr, f, poz * 2 + 1, a);
v[poz] = max (v[poz * 2], v[poz * 2 + 1]);
}
else
{
update (st, mij, f, poz * 2, a);
v[poz] = max (v[poz * 2], v[poz * 2 + 1]);
}
}
int qr (int st, int dr, int poz, int ST, int DR)
{
if (DR < st || ST > dr)
return 0;
if (ST >= st && DR <= dr)
return v[poz];
return max (qr (st, dr, poz * 2, ST, (ST + DR) / 2),
qr (st, dr, poz * 2 + 1, (ST + DR) / 2 + 1, DR));
}
int main ()
{
int n, q;
fin >> n >> q;
for (int f = 1, a; f <= n; f++)
{
fin >> a;
update (1, n, f, 1, a);
}
while (q--)
{
int cer, a, b;
fin >> cer >> a >> b;
if (!cer)
fout << qr (a, b, 1, 1, n) << '\n';
else
update (1, n, a, 1, b);
}
return 0;
}