#include <iostream>
#include <fstream>
#define NUM 100005
using namespace std;
int arb[NUM];
int n, m, a, b, maxim, cod;
ifstream f("arbint.in");
ofstream g("arbint.out");
int left_son(int n)
{
return 2 * n;
}
int right_son(int n)
{
return 2 * n + 1;
}
int father(int n)
{
return n / 2;
}
int maxi(int a, int b)
{
return (a > b ? a : b);
}
void build_max(int n, int st, int dr)
{
if(st == dr)
f >> arb[n];
else
{
int mij = st + (dr - st) / 2;
build_max(left_son(n), st, mij);
build_max(right_son(n), mij + 1, dr);
arb[n] = maxi(arb[left_son(n)], arb[right_son(n)]);
}
}
void update_max(int n, int st, int dr, int poz, int elem)
{
if(st == dr)
arb[n] = elem;
else
{
int mij = st + (dr - st) / 2;
if(poz <= mij)
update_max(left_son(n), st, mij, a, b);
if(poz > mij)
update_max(right_son(n), mij + 1, dr, a, b);
arb[n] = maxi(arb[left_son(n)], arb[right_son(n)]);
}
}
void query_max(int n, int st, int dr, int a, int b)
{
if(a <= st && dr <= b)
{
maxim = maxi(maxim, arb[n]);
}
else
{
int mij = (st + dr) / 2;
if(a <= mij)
query_max(left_son(n), st, mij, a, b);
if(mij < b)
query_max(right_son(n), mij + 1, dr, a, b);
}
}
int main()
{
f >> n >> m;
build_max(1, 1, n);
for(int i = 0; i < m; ++i)
{
f >> cod >> a >> b;
if(!cod)
{
maxim = 0;
query_max(1, 1, n, a, b);
g << maxim << "\n";
}
else
{
update_max(1, 1, n, a, b);
}
}
f.close();
g.close();
}