#include <iostream>
#include <cstdio>
#include <algorithm>
#define N 100005
using namespace std;
int n, x, y, vec[N];
class Arbore
{
private:
int a[4 * N],sol;
public:
Arbore();
void set_sol();
int get_sol();
void creare(int st, int dr, int poz);
void update(int st, int dr, int poz);
void cautare(int st, int dr, int poz);
};
Arbore::Arbore()
{
sol = 0;
}
void Arbore::set_sol()
{
sol = 0;
}
int Arbore::get_sol()
{
return sol;
}
void Arbore::creare(int st, int dr, int poz)
{
if(st == dr)
{
a[poz] = vec[st];
return;
}
int mij = (st + dr) >> 1;
creare(st, mij, 2 * poz);
creare(mij + 1, dr, 2 * poz + 1);
a[poz] = max(a[2 * poz], a[2 * poz + 1]);
}
void Arbore::update(int st, int dr, int poz)
{
if(st == dr)
{
a[poz] = y;
return;
}
int mij = (st + dr) >> 1;
if(x <= mij)
{
update(st, mij, 2 * poz);
}
else
{
update(mij + 1, dr, 2 * poz + 1);
}
a[poz] = max(a[2 * poz], a[2 * poz + 1]);
}
void Arbore::cautare(int st, int dr, int poz)
{
if(st >= x && dr <= y)
{
sol = max(a[poz], sol);
return;
}
int mij = (st + dr) >> 1;
if(x <= mij)
{
cautare(st, mij, poz * 2);
}
if(y > mij)
{
cautare(mij + 1, dr, poz * 2 + 1);
}
}
void citire()
{
Arbore arb;
int tmp;
scanf("%d %d\n",&n,&tmp);
for(int i = 1 ; i <= n ; ++i)
{
scanf("%d ",&vec[i]);
}
arb.creare(1, n, 1);
int p;
for(int i = 0 ; i < tmp ; ++i)
{
scanf("%d %d %d\n",&p,&x,&y);
if(!p)
{
arb.set_sol();
arb.cautare(1,n,1);
printf("%d\n",arb.get_sol());
}
else
{
arb.update(1,n,1);
}
}
}
int main()
{
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
citire();
return 0;
}