#include<stdio.h>
#include<algorithm>
using namespace std;
FILE *in,*out;
//definitions
#define leftSon 2*node
#define rightSon 2*node+1
//constants
const int sz = (int) 4e5+1;
//variables
int n, operations;
int val, poz, type;
int tree[sz];
int lim1,lim2;
//functions
void arb(int node, int left, int right);
void query(int node, int left, int right);
int main(void)
{
in = fopen("arbint.in", "rt");
out = fopen("arbint.out", "wt");
fscanf(in,"%d%d", &n, &operations);
for( poz=1; poz<=n; ++poz)
{
fscanf(in, "%d", &val);
arb(1,1,n);
}
for(int i=1; i<=operations; ++i)
{
fscanf(in, "%d", &type);
if(type)
{
fscanf(in, "%d%d", &poz,&val);
arb(1, 1, n);
}
else
{
fscanf(in, "%d%d", &lim1, &lim2);
val = 0;
query(1, 1, n);
fprintf(out, "%d\n",val);
}
}
fclose(in);
fclose(out);
return 0;
}
void arb(int node, int left, int right)
{
if( left == right)
{
tree[node] = val;
return;
}
int mid = (left+right)/2;
if(poz <= mid)
arb(leftSon, left, mid);
else
arb(rightSon, mid+1, right);
tree[node] = max(tree[leftSon],tree[rightSon]);
}
void query(int node, int left, int right)
{
if( lim1 <= left && right <= lim2)
{
val = max(val, tree[node]);
return;
}
int mid = (left+right) / 2;
if( mid >= lim1)
query(leftSon, left, mid);
if( mid < lim2)
query(rightSon, mid+1, right);
}