#include <iostream>
#include <fstream>
#include <vector>
#define LL long long
#define MAX 300005
using namespace std;
vector <int> elem;
LL interval_tree[MAX];
int n;
void create_tree(int index, int left, int right) {
if(left == right){
interval_tree[index] = elem[left];
return;
}
int mid = (left + right) / 2;
create_tree(2*index, left, mid);
create_tree(2*index+1, mid+1, right);
interval_tree[index] = max(interval_tree[2*index], interval_tree[2*index+1]);
}
void update_node(int index, int left, int right, int pos, int value) {
if(left == right) {
interval_tree[index] = value;
return;
}
int mid = (left + right) / 2;
if(pos <= mid)
update_node(2*index, left, mid, pos, value);
else
update_node(2*index + 1, mid + 1, right, pos, value);
interval_tree[index] = max(interval_tree[2*index], interval_tree[2*index+1]);
}
LL find_max(int index, int left, int right, int a, int b) {
if(left == a && right == b)
return interval_tree[index];
int mid = (left + right) / 2;
if(a > mid)
return find_max(2*index + 1, mid + 1, right, a, b);
if(b <= mid)
return find_max(2*index, left, mid, a, b);
return max(find_max(2*index, left, mid, a, mid), find_max(2*index+1, mid+1, right, mid+1, b));
}
int main() {
int m, x;
LL a, b;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
fin >> n >> m;
for(int i = 0; i < n; ++i) {
fin >> x;
elem.push_back(x);
}
create_tree(1, 0, n-1);
for(int i = 0; i < m; ++i) {
fin >> x >> a >> b;
if(x == 0) {
fout << find_max(1, 0, n-1, a-1, b-1) << '\n';
}
else {
update_node(1, 0, n-1, a-1, b);
}
}
return 0;
}