#include <cstdio>
#include <cassert>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
const int kbad = -1e9;
template<class T, class lel>
class node{
public:
T key;
bool tcdl, tcdr;//to carry down left, to carry down right
node(){lt = rt = NULL;};
node(T key1, int l1, int r1){
tcdl = tcdr = false;
lt = rt = NULL;
key = key1;
l = l1;
r = r1;
if(l1 != r1){
lt = new node(key1, l1, (l1 + r1) >> 1);
rt = new node(key1, ((l1 + r1) >> 1) + 1, r1);
}
}
void update(T x, int lu, int ru, lel &cmp){
if(l == r)
tcdl = tcdr = false;
if(tcdl){
tcdl = false;
lt->key = key;
lt->tcdl = true;
lt->tcdr = true;
}
if(tcdr){
tcdr = false;
rt->key = key;
rt->tcdl = true;
rt->tcdr = true;
}
if(lu > r || ru < l)
return;
else if(lu > l || ru < r){
lt->update(x, lu, ru, cmp);
rt->update(x, lu, ru, cmp);
key = cmp(rt->key, lt->key);
return;
}
tcdl = true;
tcdr = true;
key = x;
}
T query(int lq, int rq, lel &cmp){
if(l == r)
tcdl = tcdr = false;
if(tcdl){
tcdl = false;
lt->key = key;
lt->tcdl = true;
lt->tcdr = true;
}
if(tcdr){
tcdr = false;
rt->key = key;
rt->tcdl = true;
rt->tcdr = true;
}
if(l >= lq && r <= rq)
return key;
if(l > rq || r < lq)
return cmp.undesirable();
return cmp(lt->query(lq, rq, cmp), rt->query(lq, rq, cmp));
}
private:
int l, r;
node<T, lel> *lt, *rt;
};
template<class T>
class gr{
public:
T undesirable(){
return kbad;
}
T operator()(T x, T y){
if(x < y)
return y;
return x;
}
};
gr<int> cmp;
int main(){
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
int n, m;
scanf("%d%d", &n, &m);
node<int, gr<int> > t(0, 1, n);
int x;
for(int i = 1; i <= n; ++i){
scanf("%d", &x);
t.update(x, i ,i, cmp);
}
int tip, y;
for(int i = 1; i <= m; ++i){
scanf("%d%d%d", &tip, &x, &y);
if(tip == 0)
printf("%d\n", t.query(x, y, cmp));
else
t.update(y, x, x, cmp);
}
return 0;
}