#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
int i,j,N,M, k;
const int first_left = 1;
int first_right;
vector <int> three_base (200004 , 0);
ifstream fin;
ofstream fout;
void update (int nod, int left, int right, int position , int value){
if(left == right){
three_base[nod] = value;
return;
}
int half = (left + right) /2;
if (position <= half)
update ((2 *nod) , left, half, position, value);
else
update ((2*nod + 1) , half+1 , right, position , value);
three_base[nod] = max(three_base[2*nod] , three_base[(2*nod + 1)]);
}
int query (int nod, int left, int right,int a,int b){
int to_return = -1;
if (left == a && right == b)
return three_base[nod];
int half = (left + right) /2;
int max1=0, max2=0;
if (a <= half && b <= half) to_return = query ((2*nod) , left, half, a, b);
if (a <= half && b > half) {
max1 = query ((2*nod) , left, half , a, half);
max2 = query ((2*nod+1), half+1, right, half+1, b);
to_return = max(max1, max2);
}
if (a> half && b> half) to_return = query ((2*nod+1), half+1 ,right, a, b);
return to_return;
}
int main (void){
int aux;
fin.open("arbint.in");
fin>>N>>M;
for (i=1; i < N; i <<= 1) ;
first_right = i;
for (i=1; i<=N; i++){
fin>>aux;
update(1, first_left, first_right, i, aux);
}
fout.open("arbint.out");
for (i=1; i<=M; i++){
fin>>aux;
fin>>j>>k;
switch (aux){
case 0:
fout<<query(1 , first_left, first_right, j, k)<<"\n";
break;
case 1:
update (1, first_left, first_right, j, k);
break;
}
}
fin.close();
fout.close();
return 0;
}