#include <iostream>
#include <fstream>
using namespace std;
#define NMAX 100005
#define LOGNMAX 20
int N, M, A[NMAX], T[(1 << LOGNMAX)];
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 start, int finish)
{
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, start, finish);
p2 = query(2 * nod + 2, b + (e-b) / 2 + 1, e, start, finish);
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()
{
ifstream in("arbint.in");
ofstream out("arbint.out");
in >> N >> M;
for(int i = 0; i < N; ++i)
in >> A[i];
preprocess();
for(int i = 0; i < M; ++i)
{
int cod, a, b;
in >> cod >> a >> b;
if(cod == 0)
{
out << A[query(0, 0, N - 1, a - 1, b - 1)] << endl;
}
else
{
A[a - 1] = b;
update(0, 0, N - 1, a - 1);
}
}
return 0;
}