#include <iostream>
#include <fstream>
#include <limits.h>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, M, v[100001], m[200001];
int maxim(int a, int b){
return (a > b)? a : b;
}
void arbore(int nod, int st, int dr){
int mid = st + (dr - st) / 2;
if(st == dr) m[nod] = v[st];
else {
arbore(2 * nod, st, mid);
arbore(2 * nod + 1, mid + 1, dr);
m[nod] = maxim(m[2 * nod], m[2 * nod + 1]);
}
}
void update (int nod, int st, int dr,int a, int b)
{
if(st == dr)
m[nod] = b;
else{
int mij = (st + dr) / 2;
if(mij >= a)
update(2 * nod, st, mij, a, b);
else
update(2*nod + 1, mij + 1, dr, a, b);
m[nod] = maxim(m[2 * nod], m[2 * nod + 1]);
}
}
int query (int nod, int st, int dr, int a, int b)
{
if(a <= st && b>= dr)
return m[nod];
else
{
int answer = INT_MIN;
int mij = (st + dr)/2;
if(a <= mij)
answer = maxim(answer , query(2 * nod, st, mij, a, b));
if(b >= mij + 1)
answer = maxim(answer , query(2 * nod + 1, mij + 1, dr, a, b));
return answer;
}
}
int main()
{
int i, x, a, b;
fin>>n>>M;
for(i = 1; i <= n; ++i){
fin>>v[i];
}
arbore(1, 1, n);
for(i = 1; i <= M; ++i){
fin>>x>>a>>b;
if(x){
update(1, 1, n, a, b);
}
else {
fout<<query(1, 1, n, a, b)<<'\n';;
}
}
return 0;
}