#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> arbore(400020); //4*n
// x e valoare stanga data de problema
// y e valoare dreapta data de problema
int valoare_maxima(int x, int y, int nod_curent, int stanga, int dreapta)
{
if(x <= stanga && dreapta <= y)
return arbore[nod_curent];
int mijloc = (stanga+dreapta)/2, maxim=0;
if(x<=mijloc) //se duce in stanga
maxim=max(maxim, valoare_maxima(x, y, nod_curent*2, stanga, mijloc));
if(y>mijloc) //se duce in dreapta
maxim=max(maxim, valoare_maxima(x, y, nod_curent*2+1, mijloc+1, dreapta));
return maxim;
}
//stanga si dreapta sunt capetele intervalului
//pozitia e un nr de ordine
void inserare(int x, int nod_curent, int stanga, int dreapta, int pozitie)
{
if (stanga == dreapta) {
// a pus valoarea x pe frunza
arbore[nod_curent] = x;
// ne intoarcem in sus pe arbore
return;
}
int mijloc = (stanga + dreapta) / 2;
if (pozitie <= mijloc)
{ inserare(x, 2*nod_curent, stanga, mijloc, pozitie);}
else
{ inserare(x, 2*nod_curent+1, mijloc + 1, dreapta, pozitie);}
// tatal ia valoarea maxima dintre fii
arbore[nod_curent] = max(arbore[2*nod_curent], arbore[2*nod_curent+1]);
}
int main() {
ifstream in("arbint.in");
ofstream out("arbint.out");
int n, nr_operatii, x;
in>>n>>nr_operatii;
// cout<<n<<" "<<nr_operatii;
for(int i=1; i<=n; i++)
{
in>>x;
// cout<<x<<" ";
// pozitia e i pentru ca elementul meu trebuie sa se duca pe frunza [i:i]
inserare(x, 1, 1, n, i);
}
for(int i=0; i<nr_operatii; i++)
{
int tip_operatie, element_a, element_b;
in>>tip_operatie>>element_a>>element_b;
// cout<<tip_operatie<<" "<<element_a<<" "<<element_b<<"\n";
if(tip_operatie==0)
{
out<<valoare_maxima(element_a, element_b, 1, 1, n)<<"\n";
}
else{
// pun elementul b pe pozitia a
inserare(element_b, 1, 1, n, element_a);
}
}
in.close(); out.close();
return 0;
}