#include <stdio.h>
#include <vector>
using namespace std;
int n, m;
int start, finish, Val, Pos, maxim;
vector<int> arb;
void solve();
void update(int, int, int);
void query(int, int, int);
inline int max(int, int);
int main()
{
solve();
return 0;
}
void solve()
{
int i, x, y, z;
FILE *fin = fopen("arbint.in", "r");
FILE *fout = fopen("arbint.out", "w");
fscanf(fin, "%d%d", &n, &m);
arb.resize(4 * n, 0);
for (i = 1; i <= n; ++i)
{
fscanf(fin, "%d", &x);
Pos = i;
Val = x;
update(1, 1, n);
}
for (i = 1; i <= m; ++i)
{
fscanf(fin, "%d%d%d", &x, &y, &z);
if (x == 0)
{
maxim = -1;
start = y;
finish = z;
query(1, 1, n);
fprintf(fout, "%d\n", maxim);
}
else
{
Pos = y;
Val = z;
update(1, 1, n);
}
}
fclose(fin);
fclose(fout);
}
void update(int nod, int st, int dr)
{
if (st == dr)
{
arb[nod] = Val;
return;
}
int mid = (st + dr) / 2;
if (Pos <= mid)
{
update(2 * nod, st, mid);
}
else
{
update(2 * nod + 1, mid + 1, dr);
}
arb[nod] = max(arb[2*nod], arb[2*nod+1]);
}
void query(int nod, int st, int dr)
{
if (start <= st && dr <= finish)
{
if (maxim < arb[nod])
{
maxim = arb[nod];
}
return;
}
int mid = (st + dr) / 2;
if (start <= mid)
{
query(2 * nod, st, mid);
}
if (mid < finish)
{
query(2 * nod + 1, mid + 1, dr);
}
}
inline int max(int a, int b)
{
return (a > b) ? a : b;
}