#include <cstdio>
#include <algorithm>
#define NMAX 100010*4
using namespace std;
FILE*fin=fopen ("arbint.in", "r");
FILE*fout=fopen ("arbint.out", "w");
int H[NMAX];
int n, m;
void citire();
void actualizare (int, int, int, int, int);
void query (int, int, int, int, int, int&);
int main()
{
int i, val;
int op, a, b;
fscanf(fin, "%d %d", &n, &m);
for (i=1; i<=n; ++i)
{
fscanf(fin, "%d", &val);
actualizare (1, 1, n, i, val);
}
for (i=1; i<=m; ++i)
{
fscanf(fin, "%d %d %d", &op, &a, &b);
if (!op)//query
{
val=0;
query (1, 1, n, a, b, val);
fprintf(fout, "%d\n", val);
}
else
actualizare(1, 1, n, a, b);
}
return 0;
}
void actualizare (int nod, int st, int dr, int where, int val)
{
int mijl;
if (st==dr)
{
H[nod]=val;
return;
}
//vad unde trebuie sa ma duc acum
mijl=(st+dr)/2;//st, dr reprezinta intervalul in care ma aflu eu acum
//where reprezinta intervalul de lungime 1 pe care trebuie sa il modific
if (where<=mijl)
actualizare (2*nod, st, mijl, where, val);
else
actualizare (2*nod+1, mijl+1, dr, where, val);
H[nod]=max(H[2*nod], H[2*nod+1]);
return;
}
void query (int nod, int st, int dr, int left_query, int right_query, int &rez)
{
int mijl;
if (st<=left_query && right_query<=dr)
{
if (H[nod]>rez)
rez=H[nod];
return;
}
mijl=(st+dr)/2;
if (left_query<=mijl)
query (2*nod, st, mijl, left_query, right_query, rez);
if (right_query>mijl)
query (2*nod+1, mijl, dr, left_query, right_query, rez);
return;
}