#include <fstream>
using namespace std;
const int lInt = 400500;
class TreeStructure
{
int n, m;
int ArbInt[lInt];
public :
void Compute()
{
ifstream inputFile("arbint.in");
ofstream outputFile("arbint.out");
inputFile >> n >> m;
for(int x, i = 1; i <= n; ++i)
{
inputFile >> x;
UpdateTree(1, make_pair(1, n), i, x);
}
for(int type,x, y, i = 1; i <= m; ++i)
{
inputFile >> type >> x >> y;
if(type == 0) {
int solution = -1;
Querry(1, make_pair(1, n), make_pair(x, y), &solution);
outputFile << solution << '\n';
}
else {
UpdateTree(1, make_pair(1, n), x, y);
}
}
outputFile.close();
inputFile.close();
}
void UpdateTree(int nod, pair<int, int> extr, int idx, int x)
{
if(extr.first == extr.second) {
ArbInt[nod] = x;
return;
}
int mid = (extr.first + extr.second) >> 1;
if(idx <= mid)
UpdateTree(2 * nod, make_pair(extr.first, mid), idx, x);
else
UpdateTree(2 * nod + 1, make_pair(mid + 1, extr.second), idx, x);
ArbInt[nod] = max(ArbInt[2 * nod], ArbInt[2 * nod + 1]);
}
void Querry(int nod, pair < int , int > extr, pair < int, int > curInt, int *solution)
{
if(curInt.first <= extr.first && extr.second <= curInt.second) {
*solution = max(*solution, ArbInt[nod]);
return;
}
int mid = (extr.first + extr.second) >> 1;
if(curInt.first <= mid)
Querry(2 * nod, make_pair(extr.first, mid), curInt, solution);
if(mid < curInt.second)
Querry(2 * nod + 1, make_pair(mid + 1, extr.second), curInt, solution);
}
};
int main()
{
TreeStructure xObj;
xObj.Compute();
return 0;
}