#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int nums[100000];
int nrElem, nrQuery, i, tipOperatie, nr1, nr2;
vector <int> rez, arbore(400000, -1);
int constructie(int st, int dr, int poz)
{
if (st == dr)
{
arbore[poz] = nums[dr];
return nums[dr];
}
int maxst = constructie(st, st+(dr-st)/2, poz*2+1);
int maxdr = constructie(st+(dr-st)/2+1, dr, poz*2+2);
arbore[poz] = max(maxst, maxdr);
return arbore[poz];
}
int modificare(int ceModif, int val, int poz, int st, int dr)
{
if (ceModif > dr || ceModif < st) return arbore[poz];
if (st == dr) {arbore[poz] = val; return arbore[poz];}
int maxst = modificare(ceModif, val, poz*2+1, st, st+(dr-st)/2);
int maxdr = modificare(ceModif, val, poz*2+2, st+(dr-st)/2+1, dr);
arbore[poz] = max(maxst, maxdr);
return arbore[poz];
}
int queryy(int st, int dr, int poz, int nr1, int nr2)
{
if (nr1 > dr || nr2 < st) return -1;
if (nr1 <= st && nr2 >= dr) return arbore[poz];
return max(queryy(st, (st+dr)/2, poz*2+1, nr1, nr2), queryy((st+dr)/2+1, dr, poz*2+2, nr1, nr2));
}
int main()
{
fin >> nrElem >> nrQuery;
rez.reserve(nrQuery);
//nums.assign(nrElem, 0);
for (i = 0; i < nrElem; ++i)
fin >> nums[i];
constructie(0, nrElem-1, 0);
//modificare(2, 2, 0, 0, nrElem-1);
//for (i= 0; i < 20; i++)
// fout << arbore[i] << ' ' << i << '\n';
while(nrQuery--)
{
fin >> tipOperatie >> nr1 >> nr2;
if (tipOperatie == 0)
{
--nr1; --nr2;
i = queryy(0, nrElem-1, 0, nr1, nr2);
rez.push_back(i);
}
else
{
--nr1;
modificare(nr1, nr2, 0, 0, nrElem-1);
}
}
for (auto i : rez)
fout << i << '\n';
return 0;
}