#include <bits/stdc++.h>
using namespace std;
const int nMax = 100005;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int a[nMax];
int aib[5 * nMax];
int n, Q;
void BUILD(int nod, int left, int right)
{
if (left == right)
{
aib[nod] = a[left];
return;
}
int mid = (left + right) / 2;
BUILD(2 * nod, left, mid);
BUILD(2 * nod + 1, mid + 1, right);
aib[nod] = max(aib[nod * 2], aib[nod * 2 + 1]);
}
void Update(int nod, int left, int right, int poz, int val)
{
if (left == right)
{
aib[nod] = val;
return;
}
int mid = (left + right) / 2;
if (poz <= mid)
Update(nod * 2, left, mid, poz, val);
else Update(nod * 2 + 1, mid + 1, right, poz, val);
aib[nod] = max(aib[nod * 2], aib[nod * 2 + 1]);
}
int Query(int nod, int left, int right, int X, int Y)
{
if (left == X && right == Y)
return aib[nod];
int mid = (left + right) / 2;
if (Y <= mid) /// Intervalul este integral in fiul stang
return Query(2 * nod, left, mid, X, Y);
else if (mid < X) /// Intervalul este integral in fiul drept
return Query(2 * nod + 1, mid + 1, right, X, Y);
else /// Intervalul se imparte pe ambii fii asa ca l impart in 2 maxime
return max(Query(2 * nod , left , mid , X , mid), /// de pe fiul stang
Query(2 * nod + 1, mid + 1 , right , mid + 1 , Y)); /// de pe fiul drept
}
int main()
{
int i, x, y, op;
fin >> n >> Q;
for (i = 1; i <= n; i++)
fin >> a[i];
BUILD(1, 1, n); /// Formam AIB-ul
while(Q--)
{
fin >> op >> x >> y;
if (op == 1) Update(1, 1, n, x, y);
else fout << Query(1, 1, n, x, y) << "\n";
}
fin.close();
fout.close();
return 0;
}