// aib.cpp : Defines the entry point for the console application.
//
//#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
//const unsigned long long int inf = 1000000001;
int n, m;
bool c;
unsigned long long a, b;
vector <unsigned long long> aib;
unsigned int nextPowerOf2(unsigned int n)
{
unsigned count = 0;
/* First n in the below condition is for the case where n is 0*/
if (n && !(n&(n - 1)))
return n;
while (n != 0)
{
n >>= 1;
count += 1;
}
return 1 << count;
}
//actualizeaza incat sa scape de vechea val din a
inline int ACTUALIZARE(int nod,int st,int dr,int a,unsigned long long b)
{
if ((a <= st) && (dr <= a))
{
aib[nod] = b;//modifica structura auxiliara din nod
return b;
}
else
{
unsigned long long v1, v2;
int mij = (st + dr) / 2;
if (a <= mij)
v1 = ACTUALIZARE(2 * nod, st, mij, a, b);
else
v1 = aib[2 * nod];//--
if (a > mij)
v2 = ACTUALIZARE(2 * nod + 1, mij + 1, dr, a, b);
else
v2 = aib[(2 * nod) + 1];//--
aib[nod] = max(v1,v2);//actualizeaza structura auxiliara din nodul nod
}
return aib[nod];
}
inline int INTEROGARE(int nod, int st, int dr, int a, int b)
{
if ((a <= st) && (dr <= b))
return aib[nod];//returneaza structura auxiliara din nod
else
{
unsigned long long v1 = 0, v2 = 0;
int mij = (st + dr) / 2;
if (a <= mij)
v1 = INTEROGARE(2 * nod, st, mij, a, b);
if (b > mij)
v2 = INTEROGARE(2 * nod + 1, mij + 1, dr, a, b);
return max(v1, v2);//returneaza structura auxiliara din fiul stang combinata cu cea din fiul drept
}
}
int main()
{
in >> n >> m;
unsigned x = nextPowerOf2(2*n-1);
aib.resize(x,0);
for (unsigned i = 1; i <= n; i++)
{
in >> b;
ACTUALIZARE(1, 1, n, i, b);
}
for (unsigned i = 1; i <= m; i++)
{
in >> c >> a >> b;
if (c == 1)
ACTUALIZARE(1, 1, n, a, b);
else
out << INTEROGARE(1, 1, n, a, b) << '\n';
}
return 0;
}