#include <stdio.h>
#include <math.h>
#include <iostream>
#include <string>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <queue>
#include<cstdlib>
using namespace std;
#define NMAX 100001
int N, M;
int ArbInt[5 * NMAX];
int X, start, finish, val, pos, maxim;
inline int Maxim(int a, int b)
{
if ( a > b )
return a;
return b;
}
void Actualizare(int nod, int st, int dr)
{
if ( st == dr )
{
ArbInt[nod] = val;
return;
}
int mid = (st + dr) / 2;
if ( pos <= mid )
Actualizare (2 * nod, st, mid);
else
Actualizare (2 * nod + 1, mid + 1, dr);
ArbInt[nod] = Maxim ( ArbInt[2 * nod], ArbInt[2 * nod + 1] );
}
void Interogare (int nod, int st, int dr)
{
if ( start <= st && dr <= finish )
{
if ( maxim < ArbInt[nod] )
maxim = ArbInt[nod];
return;
}
int mid = (st + dr) / 2;
if ( start <= mid )
Interogare (2 * nod, st, mid);
if ( mid < finish )
Interogare (2 * nod + 1, mid + 1, dr);
}
int main()
{
FILE *f = fopen("arbint.in", "r");
FILE *g = fopen("arbint.out" , "w");
fscanf (f, "%d %d", &N, &M);
for ( int i = 1; i <= N; i++ )
{
fscanf (f, "%d", &X);
pos = i;
val = X;
Actualizare (1, 1, N);
}
int cod, A, B;
for ( int i = 1; i <= M; i++ )
{
fscanf(f, "%d %d %d", &cod, &A, &B);
if ( cod == 0 )
{
maxim = -1;
start = A; finish = B;
Interogare (1, 1, N);
fprintf(g, "%d\n", maxim);
}
else
{
pos = A;
val = B;
Actualizare (1, 1, N);
}
}
fclose(f); fclose(g);
return 0;
}