#include <iostream>
#include <fstream>
using namespace std;
#define NMAX 100005
#define LOGNMAX 20
int N, M, A[NMAX], T[(1 << LOGNMAX)];
int start, finish;
inline void fill(int nod, int b, int e)
{
if(b == e)
{
T[nod] = b;
}
else
{
fill(2 * nod + 1, b, b + (e - b) / 2);
fill(2 * nod + 2, b + (e - b) / 2 + 1, e);
if(A[T[2 * nod + 1]] <= A[T[2 * nod + 2]])
T[nod] = T[2 * nod + 2];
else
T[nod] = T[2 * nod + 1];
}
}
void preprocess()
{
fill(0, 0, N - 1);
}
int query(int nod, int b, int e)
{
int p1, p2;
if(start > e || finish < b)
{
return -1;
}
if(start <= b && finish >= e)
{
return T[nod];
}
p1 = query(2 * nod + 1, b, b + (e-b) / 2);
p2 = query(2 * nod + 2, b + (e-b) / 2 + 1, e);
if(p1 == -1)
return p2;
else if(p2 == -1)
return p1;
else
{
if(A[p1] < A[p2])
return p2;
else
return p1;
}
}
void update(int nod, int b, int e, int pos)
{
if(b == e)
{
T[nod] = b;
}
else
{
if(pos >= b && pos <= b + (e - b) / 2)
{
update(2 * nod + 1, b, b + (e - b) / 2, pos);
}
else
{
update(2 * nod + 2, b + (e - b) / 2 + 1, e, pos);
}
if(A[T[2 * nod + 1]] <= A[T[2 * nod + 2]])
T[nod] = T[2 * nod + 2];
else
T[nod] = T[2 * nod + 1];
}
}
int main()
{
freopen("arbint.in", "rt", stdin);
freopen("arbint.out", "wt", stdout);
scanf("%d %d", &N, &M);
for(int i = 0; i < N; ++i)
scanf("%d", &A[i]);
preprocess();
for(int i = 0; i < M; ++i)
{
int cod, a, b;
scanf("%d %d %d", &cod, &a, &b);
if(cod == 0)
{
start = a - 1;
finish = b - 1;
printf("%d\n", A[query(0, 0, N - 1)]);
}
else
{
A[a - 1] = b;
update(0, 0, N - 1, a - 1);
}
}
return 0;
}