#include <fstream>
#define in "arbint.in"
#define out "arbint.out"
#define Max_Size 100003
std :: ifstream f(in);
std :: ofstream g(out);
int N, M, maxim;
int A[Max_Size], Arb[Max_Size * 3];
void Build_Tree(int node, int st, int dr)
{
if(st == dr) Arb[node] = A[st];
else
{
int mij = (st + dr) >> 1;
Build_Tree(2 * node, st, mij);
Build_Tree(2 * node + 1, mij + 1, dr);
Arb[node] = std :: max(Arb[2 * node], Arb[2 * node + 1]);
}
}
void Search(int node, int st, int dr, int x, int y)
{
if(x <= st && dr <= y)
maxim = std :: max(maxim, Arb[node]);
else
{
int mij = (st + dr) >> 1;
if(x <= mij) Search(2 * node, st, mij, x, y);
if(y > mij) Search(2 * node + 1, mij + 1, dr, x, y);
}
}
void Update(int node, int st, int dr, int poz, int el)
{
if(st == dr) Arb[node] = el;
else
{
int mij = (st + dr) >> 1;
if(poz <= mij) Update(2 * node, st, mij, poz, el);
else
if(poz > mij) Update(2 * node + 1, mij + 1, dr, poz, el);
Arb[node] = std :: max(Arb[2 * node], Arb[2 * node + 1]);
}
}
int main()
{
f >> N >> M;
for(int i = 1; i <= N; ++i) f >> A[i];
Build_Tree(1, 1, N);
for(int tip, x, y, i = 1; i <= M; ++i)
{
f >> tip >> x >> y;
if(!tip)
{
maxim = -1;
Search(1, 1, N, x, y);
g << maxim << '\n';
}
else Update(1, 1, N, x, y);
}
g.close();
return 0;
}