// Arbori de intervale.cpp : Defines the entry point for the console application.
//
//#include "stdafx.h"
#include "stdio.h"
FILE *f=fopen("arbint.in", "r");
FILE *g=fopen("arbint.out", "w");
typedef struct arbore
{
int x, y;
};
arbore arb[1000001];
int n, v[100001], m, imax;
int poz[100001];
int w[1000001];
int maxaf=0;
int maxim(int x, int y)
{
if (x>y) return x;
return y;
}
void read()
{
fscanf(f, "%d%d", &n, &m);
for (int i=1; i<=n; ++i)
fscanf(f, "%d", &v[i]);
}
void init(int x, int y, int i)
{
if (i>imax) imax=i;
arb[i].x=x;
arb[i].y=y;
int mid=(x+y)/2;
if (x<=mid && x!=y)
init(x, mid, i*2);
if (y>mid)
init (mid+1, y, i*2+1);
}
void init2()
{
for (int j=imax; j>=1; --j)
{
if (arb[j].x==arb[j].y)
{
w[j]=v[arb[j].x];
poz[arb[j].x]=j;
}
else
w[j]=maxim(w[j*2], w[j*2+1]);
}
}
void uparb(int x)
{
int t=x/2;
while (t>0)
{
w[t]=maxim(w[t*2], w[t*2+1]);
t=t/2;
}
}
void actualizare(int nod, int st, int dr, int a, int b)
{
if (a<=st && b>=dr)
maxaf=maxim(maxaf, w[nod]);
else
{
int mid=(st+dr)/2;
if (st<=mid && st!=dr)
actualizare(nod*2, st, mid, a, b);
if (dr>mid)
actualizare(nod*2+1, mid+1, dr, a, b);
}
}
void program()
{
for (int j=1; j<=m; ++j)
{
int x, a, b;
fscanf(f, "%d%d%d", &x, &a, &b);
if (x==1)
{
w[poz[a]]=b;
uparb(poz[a]);
}
else
{
maxaf=-1;
actualizare(1, 1, n, a, b);
fprintf(g, "%d\n", maxaf);
}
}
}
int main()
{
read();
init(1, n, 1);
init2();
program();
return 0;
}