#include <stdio.h>
#include <stdlib.h>
#define N_MAX 400000
int tree[N_MAX];
int v[N_MAX];
int max(int a, int b)
{
if (a > b)
return a;
else
return b;
}
void build(int nod, int st, int dr)
{
if (st == dr)
{
tree[nod] = v[st];
}
else
{
int mij = (st + dr) / 2;
build(2 * nod, st, mij);
build(2 * nod + 1, mij + 1, dr);
tree[nod] = max(tree[2 * nod], tree[2 * nod + 1]);
}
}
void update(int nod, int st, int dr, int pos, int val)
{
if (st == dr)
{
tree[nod] = val;
}
else
{
int mij = (st + dr) / 2;
if (pos <= mij)
update(2 * nod, st, mij, pos, val);
else
update(2 * nod + 1, mij + 1, dr, pos, val);
tree[nod] = max(tree[2 * nod], tree[2 * nod + 1]);
}
}
void query(int nod, int st, int dr, int x, int y, int *ans)
{
if (x <= st && dr <= y)
{
*ans = max(*ans, tree[nod]);
}
else
{
int mij = (st + dr) / 2;
if (x <= mij)
query(2 * nod, st, mij, x, y, ans);
if (y > mij)
query(2 * nod + 1, mij + 1, dr, x, y, ans);
}
}
int main()
{
int M, N;
FILE *fin = NULL, *fout = NULL;
fin = fopen("arbint.in", "r");
fout = fopen("arbint.out", "w");
// Citire :
fscanf(fin, "%d %d", &N, &M);
for (int i = 1; i <= N; ++i)
fscanf(fin, "%d", &v[i]);
build(1, 1, N);
// Rezolvare :
int k, st, dr, val = 0;
for (int i = 0; i < M; ++i)
{
fscanf(fin, "%d", &k);
fscanf(fin, "%d", &st);
fscanf(fin, "%d", &dr);
if (k == 0)
{
val = -1;
query(1, 1, N, st, dr, &val);
fprintf(fout, "%d\n", val);
}
else
{
update(1, 1, N, st, dr);
}
}
return 0;
}