// arbint.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <fstream>
#include <algorithm>
#define NMAX 100010
#define ARBMAX 300010
using namespace std;
ifstream f("arbint.in");
ofstream g("arbint.out");
int n, m, arb[ARBMAX];
void Update(int pozitie, int val, int st, int dr, int nod)
{
int mij = (st + dr)/2;
if (st == dr) arb[nod] = val;
else
if (pozitie <= mij)
{
Update(pozitie, val, st, mij, nod*2);
arb[nod] = max(arb[2*nod], arb[2*nod+1]);
}
else
{
Update(pozitie, val, mij + 1, dr, nod * 2 + 1);
arb[nod] = max(arb[2 * nod], arb[2 * nod + 1]);
}
}
void Citeste()
{
int x;
f >> n>>m;
for (int i = 1; i <= n; ++i)
{
f >> x;
Update(i, x, 1, n, 1);
}
}
int query(int start, int final, int st, int dr, int nod)
{
int mij = (st + dr) / 2;
if (final<st || start>dr) return 0;
else
if (start <= st && final >= dr) return arb[nod];
else
return max(query(start, final, st, mij, nod * 2), query(start, final, mij + 1, dr, nod * 2 + 1));
}
void Rezolva()
{
int op, i, x, y;
for (i = 1; i <= m; ++i)
{
f >> op >> x >> y;
if (op == 1) Update(x, y, 1, n, 1);
else g << query(x, y, 1, n, 1)<<"\n";
}
}
int main()
{
Citeste();
Rezolva();
f.close();
g.close();
return 0;
}