#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
using namespace std;
#define FILE_IN "arbint.in"
#define FILE_OUT "arbint.out"
int N, M;
int* arb;
static inline int max(int a, int b)
{
return (a > b) ? a : b;
}
static inline void _arbint_set(int nod, int L, int R, int index, int value)
{
if (L == R)
{
arb[nod] = value;
return;
}
int piv = L + (R-L)/2;
if (index <= piv)
{
_arbint_set((nod << 1), L, piv, index, value);
}
else
{
_arbint_set((nod << 1)+1, piv+1, R, index, value);
}
arb[nod] = max(arb[nod << 1], arb[(nod << 1) +1]);
}
static inline void arbint_set(int index, int value)
{
_arbint_set(1, 0, N-1, index, value);
}
static inline int _arbint_max(int nod, int L, int R, int left, int right)
{
if ((left <= L) && (right >= R)) return arb[nod];
int piv = L + (R-L)/2;
int maxx = 0;
if (left <= piv)
maxx = max(maxx, _arbint_max((nod << 1), L, piv, left, right));
if (right >= piv+1)
maxx = max(maxx, _arbint_max((nod << 1)+1, piv+1, R, left, right));
return maxx;
}
static inline int arbint_max(int left, int right)
{
return _arbint_max(1, 0, N-1, left, right);
}
int main()
{
ifstream fisIn(FILE_IN);
ofstream fisOut(FILE_OUT);
fisIn >> N >> M;
int N_orig = N;
int nSup = 1; while (nSup < N) nSup <<= 1;
N = nSup;
arb = new int[N*2];
memset(arb, 0, sizeof(int)*2*N);
for (int i=0; i<N_orig; i++)
{
int x;
fisIn >> x;
arbint_set(i, x);
}
while (M--)
{
int op, a, b;
fisIn >> op >> a >> b;
switch (op)
{
case 0:
fisOut << arbint_max(a-1, b-1) << '\n';
break;
case 1:
arbint_set(a-1, b);
break;
}
}
}