#include <iostream>
#include <fstream>
#define MAX_N 100005
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n;
int m;
int values[MAX_N] = { 0 };
int tree[2 * MAX_N] = { 0 };
int Max(int a, int b)
{
if (a > b)
return a;
return b;
}
void _fastcall InsertTree(int node, int left, int right, int& a, int& b)
{
if (left == right)
{
tree[node] = values[left];
}
else
{
int middle = (left + right) / 2;
if (a <= middle)
{
InsertTree(node * 2, left, middle, a, b);
}
if(b > middle)
{
InsertTree((node * 2) + 1, middle + 1, right, a, b);
}
tree[node] = Max(tree[node * 2], tree[(node * 2) + 1]);
}
}
int _fastcall Query(int node, int left, int right, int& a, int& b)
{
if (a <= left && right <= b)
{
return tree[node];
}
else
{
int val = 0;
int middle = (left + right) / 2;
if (a <= middle)
{
val = Query(node * 2, left, middle, a, b);
}
if (b > middle)
{
val = Max(Query((node * 2) + 1, middle + 1, right, a, b), val);
}
return val;
}
}
int main(void)
{
fin >> n >> m;
for (int i = 1; i <= n; i++)
{
fin >> values[i];
}
int t = 1;
InsertTree(1, 1, n, t, n);
for (int i = 1; i <= m; i++)
{
int task;
int a, b;
fin >> task >> a >> b;
if (!task)
{
fout << Query(1, 1, n, a, b) << endl;
}
else
{
values[a] = b;
InsertTree(1, 1, n, a, a);
}
}
fin.close();
fout.close();
return 0;
}