#include <bits/stdc++.h>
#define nmax 100005
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, m;
int arbint[4*nmax + 30], v[nmax];
void construct_arbint(int positie_in_arbint, int leftie, int rightie)
{
if(leftie == rightie)
arbint[positie_in_arbint] = v[leftie];
else
{
int mij = (leftie + rightie) >> 1;
int pos = (positie_in_arbint << 1);
construct_arbint(pos, leftie, mij);
construct_arbint(pos + 1, mij + 1, rightie);
arbint[positie_in_arbint] = max(arbint[pos], arbint[pos + 1]);
}
}
int afla_maximul(int positie, int stanga_tree, int dreapta_tree, int stanga, int dreapta)
{
if(stanga > dreapta)
return -1;
if(stanga_tree == stanga && dreapta_tree == dreapta)
return arbint[positie];
int mijloc = ((stanga_tree + dreapta_tree) >> 1);
int ret1 = -1, ret2 = -1;
ret1 = afla_maximul((positie << 1), stanga_tree, mijloc, stanga, min(dreapta, mijloc));
ret2 = afla_maximul((positie << 1) + 1, mijloc + 1, dreapta_tree, max(stanga, mijloc + 1), dreapta);
return (ret1 > ret2) ? ret1 : ret2;
}
void update_tree(int pos, int st, int dr, int indice, int val_noua)
{
if(st == dr)
{
arbint[pos] = val_noua;
return;
}
int pos2 = (pos << 1), mij = ((st + dr) >> 1);
if(indice > mij)
update_tree(pos2 + 1, mij + 1, dr, indice, val_noua);
else
update_tree(pos2, st, mij, indice, val_noua);
arbint[pos] = max(arbint[pos2], arbint[pos2 + 1]);
}
int main()
{
int i, operatie, a, b;
fin >> n >> m;
for(i = 0; i < n; i++)
fin >> v[i];
construct_arbint(1, 0, n - 1);
for(i = 0; i < m; i++)
{
fin >> operatie >> a >> b;
if(operatie == 0)
fout << afla_maximul(1, 0, n-1, a-1, b-1) << endl;
else
update_tree(1, 0, n-1, a-1, b);
}
return 0;
}