#include <fstream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <unordered_map>
#define NMAX 100003
using namespace std;
int n,q;
int v[NMAX],arb[4*NMAX];
ifstream fin("arbint.in");
ofstream fout("arbint.out");
void build(int nod, int st, int dr)
{
if (st == dr)
{
arb[nod] = v[st];
return;
}
int mij = (st + dr) / 2;
build(2 * nod+1, mij+1, dr);
build(2 * nod , st, mij);
arb[nod] = max(arb[2 * nod], arb[2 * nod + 1]);
}
int qry(int nod, int st, int dr, int qSt, int qDr)
{
if (qSt <= st && dr <= qDr)
{
return arb[nod];
}
int mij = (st + dr) / 2;
if (qDr <= mij)
{
return qry(2*nod, st, mij, qSt, qDr);
}
if (mij + 1 <= qSt)
{
return qry(2*nod+1, mij+1, dr, qSt, qDr);
}
return max(qry(2*nod, st, mij, qSt, qDr), qry(2*nod+1, mij + 1, dr, qSt, qDr));
}
void upd(int nod, int st, int dr, int poz, int val)
{
if (st == dr)
{
arb[nod] = val;
return;
}
int mij = (st + dr) / 2;
if (poz <= mij)
{
upd(2 * nod, st, mij, poz, val);
}
else {
upd(2 * nod+1, mij+1, dr, poz, val);
}
arb[nod] = max(arb[2 * nod], arb[2 * nod + 1]);
}
int main()
{
fin >> n >> q;
for (int i = 1; i <= n; i++)
{
fin >> v[i];
}
build(1, 1, n);
for (int i = 1; i <= q; i++)
{
int cer;
fin >> cer;
if (cer == 0)
{
//e query
int st, dr;
fin >> st >> dr;
fout << qry(1, 1, n, st, dr)<<"\n";
}
else {
int poz, val;
fin >> poz >> val;
upd(1, 1, n, poz, val);
}
}
return 0;
}