#include <bits/stdc++.h>
//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx2,bmi,bmi2,popcnt,lzcnt")
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
const int nmax = 100001;
int arr[nmax];
int aint[nmax * 4];
int n,q;
int build(int node = 1, int left = 1, int right = n) {
if (left == right) {
aint[node] = arr[left];
} else {
const int mid = static_cast<long long>((left + right) / 2);
aint[node] = max(build(2*node,left,mid),
build(2*node+1,mid+1,right));
}
return aint[node];
}
int update(int target, int value,
int node = 1, int left = 1, int right = n) {
if (left == right) {
aint[node] = value;
} else {
const int mid = static_cast<long long>((left + right) / 2);
if (target <= mid) {
aint[node] = max(update(target,value,2*node,left,mid),aint[2*node+1]);
} else {
aint[node] = max(aint[2*node],update(target,value,2*node+1,mid+1,right));
}
}
return aint[node];
}
int query(int qleft, int qright,
int node = 1, int left = 1, int right = n) {
if (qleft <= left and right <= qright) {
return aint[node];
} else {
const int mid = static_cast<long long>((left + right) / 2);
if (qright <= mid) {
return query(qleft,qright,2*node,left,mid);
}
if (mid < qleft){
return query(qleft,qright,2*node+1,mid+1,right);
}
return max(query(qleft,qright,2*node,left,mid),
query(qleft,qright,2*node+1,mid+1,right));
}
}
int main() {
fin >> n >> q;
for (int i = 1; i <= n; i++) {
fin >> arr[i];
}
build();
while (q--) {
int t,a,b;
fin >> t >> a >> b;
if (!t) {
fout << query(a,b) << '\n';
} else {
update(a,b);
}
}
return 0;
}