#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
class node{
public:
int val, left, right, lt, rt;
node(){};
node(int v1, int l1, int r1, int lt1, int rt1){
val = v1;
left = l1;
right = r1;
lt = lt1;
rt = rt1;
}
};
int init[100005];
vector<node> t;
void make(int x){
if(t[x].left == t[x].right){
t[x].val = init[t[x].left];
return;
}
t[x].lt = t.size();
t.push_back(node(0, t[x].left, (t[x].right + t[x].left) >> 1, 0, 0));
t[x].rt = t.size();
t.push_back(node(0, (((t[x].right + t[x].left) >> 1) + 1), t[x].right, 0, 0));
make(t[x].lt);
make(t[x].rt);
t[x].val = max(t[t[x].lt].val, t[t[x].rt].val);
}
void update(int pos, int val, int x){
if(t[x].left == t[x].right){
t[x].val = val;
return;
}
if(t[t[x].lt].right >= pos)
update(pos, val, t[x].lt);
else
update(pos, val, t[x].rt);
t[x].val = max(t[t[x].lt].val, t[t[x].rt].val);
}
int query(int l, int r, int x){
if(r < t[x].left || l > t[x].right)
return -1;
if(l <= t[x].left && r >= t[x].right)
return t[x].val;
return max(query(l, r, t[x].lt), query(l, r, t[x].rt));
}
int main(){
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
int n, m;
scanf("%d%d", &n, &m);
t.push_back(node(0, 1, n, 0, 0));
for(int i = 1; i <= n; ++i)
scanf("%d", &init[i]);
make(0);
for(int i = 1; i <= m; ++i){
int tip, x, y;
scanf("%d%d%d", &tip, &x, &y);
if(tip == 0)
printf("%d\n", query(x, y, 0));
else
update(x, y, 0);
}
return 0;
}