#include <fstream>
#include <vector>
using namespace std;
ifstream cin("arbint.in");
ofstream cout("arbint.out");
const int MAXN = 1e5;
/* Given an array A with n elements and 2 type of online operations:
* 1. 0 a b - compute the maximum in the range A[a..b]
* 2. 1 a b - change the value of element on position a to be b
* Return the result for the forst type of operation
*/
template <class T>
class SegmentTree {
typedef T (*functionType) (T, T);
public:
SegmentTree(vector<T> &a, functionType _f):
f (_f), num_elem (a.size()), st(4*num_elem+1){
build_segment_tree(1, 0, num_elem-1, a);
}
void update_element(int pos, T value){
update(1, 0, num_elem-1, pos, value);
}
T query_segment(int x, int y) {
query(1, 0, num_elem-1, x, y);
return ans;
}
private:
functionType f;
vector<T> st;
int num_elem;
T ans;
void build_segment_tree(int node, int left, int right, vector<T> &a){
if (left == right) {
st[node] = a[left];
return;
}
int mid = (right+left) >> 1;
int left_son = node << 1;
int right_son = left_son+1;
build_segment_tree(left_son, left, mid, a);
build_segment_tree(right_son, mid+1, right, a);
st[node] = f(st[left_son], st[right_son]);
}
void update(int node, int left, int right, int pos, T value){
if (left == right){
st[node] = value;
return;
}
int mid = (right+left) >> 1;
int left_son = node << 1;
int right_son = left_son+1;
if (pos <= mid)
update(left_son, left, mid, pos, value);
else update(right_son, mid+1, right, pos, value);
st[node] = f(st[left_son], st[right_son]);
}
void query(int node, int left, int right, int x, int y){
if (x <= left && right <= y){
// the first range to be taken into
// consideration when computing the result
if (left == x) ans = st[node];
else ans = f(ans, st[node]);
return;
}
int mid = (right+left) >> 1;
int left_son = node << 1;
int right_son = left_son + 1;
if (x <= mid) query(left_son, left, mid, x, y);
if (mid < y) query(right_son, mid+1, right, x, y);
}
};
int my_max(int a, int b){
if (a > b)
return a;
return b;
}
int main() {
int n, m;
cin >> n >> m;
vector<int> a(n, 0);
for (int i = 0; i < n; ++ i){
cin >> a[i];
}
SegmentTree <int> ds(a, my_max);
while(m--){
int type, x, y;
cin >> type >> x >> y;
x--;
if (type == 0)
cout << ds.query_segment(x, --y) << "\n";
else ds.update_element(x, y);
}
return 0;
}