#include <iostream>
#include <fstream>
#include <limits.h>
#define leftN 2*nod
#define rightN 2*nod+1
#define MAX 100000
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
int arb[4*MAX+1];
int v[MAX+1];
int n,m,a,b,t;
void build(int nod, int left, int right) {
if(left == right) {
arb[nod] = v[left];
//cout << arb[nod] << "[" << left << ", " << right << "]" << '\n';
return;
}
int mid = (left+right)/2;
build(leftN, left, mid);
build(rightN, mid+1, right);
arb[nod] = max(arb[leftN], arb[rightN]);
//cout << arb[nod] << "[" << left << ", " << right << "]" << '\n';
}
void update(int nod, int left, int right, int pos, int val) {
if(left == right) {
arb[nod] = val;
return;
}
int mid = (left+right)/2;
if(pos <= mid)
update(leftN, left, mid, pos, val);
else
update(rightN, mid+1, right, pos, val);
arb[nod] = max(arb[leftN], arb[rightN]);
}
void query(int nod, int left, int right, int start, int finish, int &mx) {
if(left >= start && right <= finish) {
mx = max(mx, arb[nod]);
return;
}
int mid = (left + right)/2;
if(a <= mid)
query(leftN, left, mid, start, finish, mx);
if(b > mid)
query(rightN, mid+1, right, start, finish, mx);
}
void inorder(int nod, int left, int right) {
if(arb[nod] == 0)
return;
inorder(leftN, left, (left+right)/2);
cout << arb[nod] << " [ " << left << ", " << right << " ]" << '\n';
inorder(rightN, (left+right)/2+1, right);
}
int main() {
in >> n >> m;
for(int i = 1; i <= n; i++) {
in >> v[i];
}
build(1, 1, n);
for(int i = 1; i <= m; i++) {
in >> t >> a >> b;
if(t == 0) {
int mx = -1;
query(1, 1, n, a, b, mx);
out << mx << '\n';
} else {
update(1, 1, n, a, b);
}
}
return 0;
}