#include <stdio.h>
#include <string.h>
#define NMAX 100010
long n, m;
long a[NMAX];
long tree[NMAX*3];
#define mid(st, dr) (((st) + (dr)) >> 1)
#define left(i) ((i) << 1)
#define right(i) ((i) << 1)+1
inline int MAX(int a, int b) { return (a > b) ? (a) : (b); }
void update(int n, int st, int dr, int poz, int val)
{
if(st == dr)
{
tree[n] = val;
return ;
}
int m = mid(st, dr);
if(poz <= m)
update(left(n), st, m, poz, val);
else
update(right(n), m+1, dr, poz, val);
tree[n] = MAX(tree[left(n)], tree[right(n)]);
}
long query(int n, int st, int dr, int x, int y)
{
if(x <= st && dr <= y)
return tree[n];
int m = mid(st, dr), ll, rr;
ll = rr = 0;
if(x <= m)
ll = query(left(n), st, m, x, y);
if(m < y)
rr = query(right(n), m+1, dr, x, y);
return MAX(ll, rr);
}
void read()
{
int i;
scanf("%ld %ld", &n, &m);
for(i = 1; i <= n; ++i)
{
scanf("%d", &a[i]);
update(1, 1, n, i, a[i]);
}
}
int main()
{
int i;
long x, y, z;
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
read();
for(i = 1; i <= m; ++i)
{
scanf("%ld %ld %ld", &z, &x, &y);
if(z == 0)
printf("%ld\n", query(1, 1, n, x, y));
else
update(1, 1, n, x, y);
}
return 0;
}