#include <fstream>
#include <vector>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, q, maxQuery;
vector <int> aint, v;
void Read();
void SolveQueries();
void Build(int, int, int);
void Update(int, int, int, const int&, const int&);
void Query(int node, int left, int right, const int& queryLeft, const int& queryRight);
int main()
{
Read();
SolveQueries();
fin.close();
fout.close();
return 0;
}
void Read()
{
fin >> n >> q;
aint = vector <int> (4 * n);
v = vector <int> (n + 1);
for (int i = 1; i <= n; ++i)
{
fin >> v[i];
}
Build(1, 1, n);
}
void Update(int node, int left, int right, const int& pos, const int& val)
{
if (left == right)
{
aint[node] = val;
return;
}
int mid = (left + right) / 2;
if (pos <= mid)
Update (node * 2, left, mid, pos, val);
else Update (node * 2 + 1, mid + 1, right, pos, val);
aint[node] = max(aint[node * 2], aint[node * 2 + 1]);
}
void SolveQueries()
{
int p, x, y;
while (q--)
{
fin >> p >> x >> y;
if (p)
{
Update(1, 1, n, x, y);
}
else
{
maxQuery = -0x3f3f3f3f;
Query(1, 1, n, x, y);
fout << maxQuery << '\n';
}
}
}
void Query(int node, int left, int right, const int& queryLeft, const int& queryRight)
{
if (queryLeft <= left && queryRight >= right)
{
maxQuery = max(maxQuery, aint[node]);
return;
}
int mid = (left + right) / 2;
if (queryLeft <= mid)
Query(2 * node, left, mid, queryLeft, queryRight);
if (queryRight >= mid + 1)
Query(2 * node + 1, mid + 1, right, queryLeft, queryRight);
}
void Build(int node, int left, int right)
{
if (left == right)
{
aint[node] = v[left];
return;
}
int mid = (left + right) / 2;
Build (node * 2, left, mid);
Build (node * 2 + 1, mid + 1, right);
aint[node] = max (aint[node * 2], aint[node * 2 + 1]);
}