#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <fstream>
#include <set>
#include <stack>
#include <queue>
#include <list>
using namespace std;
typedef long long int64;
typedef vector<int> vec;
typedef vector<int64> vec64;
#define db(x) cout << "> " << #x << ": " << x << "\n";
// // // // // // // // // // // // // // // // // // //
ifstream in ("arbint.in");
ofstream out ("arbint.out");
int q, n;
int partsize;
vec arr (100001);
vec part (100001);
void update(int indx, int val){
int tm = 0;
if (val >= arr[indx]){
part[(indx - 1) / partsize + 1] = val;
arr[indx] = val;
}
else{
arr[indx] = val;
for (int i = ((indx - 1) / partsize) * partsize + 1; i < ((indx - 1) / partsize) * partsize + 1 + partsize; i++){
tm = max(tm, arr[i]);
//db(i);
}
part[(indx-1) / partsize + 1] = tm;
}
}
int range(int l, int r){
int rs = -1;
while (l <= r && l % partsize != 0){
rs = max(rs, arr[l]);
l++;
}
int indx =(l - 1) / partsize + 1;
while (l + partsize <= r){
rs = max(rs, part[indx]);
l++;
indx++;
}
while (l <= r){
rs = max(rs, arr[l]);
l++;
}
return rs;
}
int main(){
in >> n >> q;
for (int i = 1; i <= n; i++){
in >> arr[i];
}
partsize = sqrt(n);
int indx = 1;
for (int i = 1; i <= n;i ++){
if (i % partsize == 0){
indx++;
}
part[indx] = max(part[indx], arr[i]);
}
while (q--){
int a,x,y;
in >> a >> x >> y;
if (a == 0){
out << range(x,y) << "\n";
}
else
update(x,y);
}
return 0;
}