#include <cstdio>
const int MAX_SIZE(100000);
int numbers [MAX_SIZE];
int it [MAX_SIZE << 2];
int n, m;
inline void read (void)
{
std::scanf("%d%d",&n,&m);
for (int *iterator(numbers), *end(numbers + n) ; iterator < end ; ++iterator)
std::scanf("%d",iterator);
}
inline int max (int a, int b)
{
if (a > b)
return a;
return b;
}
inline int left_son (int node)
{
return (node << 1) + 1;
}
inline int right_son (int node)
{
return (node << 1) + 2;
}
void build (int index, int left, int right)
{
int middle((left + right) >> 1);
if (left == right)
{
it[index] = numbers[middle];
return;
}
build(left_son(index),left,middle);
build(right_son(index),middle + 1,right);
it[index] = max(it[left_son(index)],it[right_son(index)]);
}
void update (int index, int left, int right, int position, int value)
{
if (left == right)
{
it[index] = value;
return;
}
int middle((left + right) >> 1);
if (position <= middle)
update(left_son(index),left,middle,position,value);
else
update(right_son(index),middle + 1,right,position,value);
it[index] = max(it[left_son(index)],it[right_son(index)]);
}
int query (int index, int left, int right, int ql, int qr)
{
if (ql <= left && right <= qr)
return it[index];
int middle((left + right) >> 1), result(0);
if (ql <= middle)
result = query(left_son(index),left,middle,ql,qr);
if (qr > middle)
result = max(result,query(right_son(index),middle + 1,right,ql,qr));
return result;
}
int main (void)
{
std::freopen("arbint.in","r",stdin);
std::freopen("arbint.out","w",stdout);
read();
build(0,0,n - 1);
int type, a, b;
do
{
std::scanf("%d%d%d",&type,&a,&b);
if (type)
update(0,0,n - 1,a - 1,b);
else
std::printf("%d\n",query(0,0,n - 1,a - 1,b - 1));
--m;
}
while (m);
std::fclose(stdin);
std::fclose(stdout);
return 0;
}