#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int v[100001], arb[400001];
void arbore(int nod, int st, int dr)
{
if(st==dr)
{
arb[nod]=v[st];
return;
}
int mij=(st+dr)/2;
arbore(2*nod, st, mij);
arbore(2*nod+1, mij+1, dr);
arb[nod]=fmax(arb[nod*2], arb[2*nod+1]);
}
void update_arb(int nod,int st, int dr, int poz, int val)
{
if(st==dr) // am gasit
{
arb[nod]=val;
return;
}
int mij=(st+dr)/2;
if(poz<=mij)
update_arb(2*nod, st, mij, poz, val); // jum stanga
else
update_arb(2*nod+1, mij+1, dr, poz, val); // jum dreapta
arb[nod]=fmax(arb[2*nod], arb[2*nod+1]);
}
int max_arb(int nod, int st, int dr, int a, int b)
{
if (a<=st && dr<=b) // complet in interval
return arb[nod];
int mij=(st+dr)/2;
int val_max=-1;
if (a<=mij)
val_max=fmax(val_max, max_arb(2*nod, st, mij, a, b));
if (mij<b)
val_max=fmax(val_max, max_arb(2*nod+1, mij+1, dr, a, b));
return val_max;
}
int main()
{
FILE *f, *g;
if((f=fopen("arbint.in", "r"))==NULL)
{
fprintf(stderr, "eroare deschidere fisier1\n");
exit(1);
}
if((g=fopen("arbint.out", "w"))==NULL)
{
fprintf(stderr, "eroare deschidere fisier2\n");
exit(1);
}
int N, M;
if(fscanf(f, "%d %d", &N, &M)!=2)
return 0;
for (int i=1; i<=N; i++)
{
if(fscanf(f,"%d", &v[i])!=1)
return 0;
}
int a,b, tip;
arbore(1,1,N); // creeaza arborele cu val maxime
for (int i=0; i<M; i++)
{
if(fscanf(f, "%d %d %d", &tip, &a, &b)!=3)
return 0;
if(tip==1)
{
update_arb(1, 1, N, a, b);
}
else
{
int rez=max_arb(1,1,N,a,b);
fprintf(g,"%d\n", rez);
}
}
fclose(f);
fclose(g);
return 0;
}