#include <fstream>
using namespace std;
ifstream fin ("arbint.in");
ofstream fout ("arbint.out");
int n, m, maxim, V[2 * 100010];
inline int Left_Son(int &x)
{
return (x << 1);
}
inline int Right_Son(int &x)
{
return ((x << 1) + 1);
}
void Update(int nod, int left, int right, int &value, int &poz)
{
if (left == right)
{
V[nod] = value;
return;
}
int mid = (left + right) >> 1;
if (poz <= mid)
{
Update(Left_Son(nod), left, mid, value, poz);
}
else
{
Update(Right_Son(nod), mid + 1, right, value, poz);
}
V[nod] = max (V[Left_Son(nod)], V[Right_Son(nod)]);
}
void Query(int nod, int left, int right, int &start, int &finish)
{
if (start <= left && finish >= right)
{
maxim = max (maxim, V[nod]);
return;
}
int mid = (left + right) >> 1;
if (start <= mid)
{
Query(Left_Son(nod), left, mid, start, finish);
}
if (finish > mid)
{
Query(Right_Son(nod), mid + 1, right, start, finish);
}
}
int main()
{
fin >> n >> m;
for (int i = 1, x; i <= n; i++)
{
fin >> x;
Update(1, 1, n, x, i);
}
for (int i = 1, tip, a, b; i <= m; i++)
{
fin >> tip >> a >> b;
switch (tip)
{
case 0 :
{
maxim = -1;
Query(1, 1, n, a, b);
fout << maxim << '\n';
break;
}
case 1 :
{
Update(1, 1, n, b, a);
break;
}
}
}
fout.close();
return 0;
}