#include <fstream>
#define buffLen 131071
#define aiLen 262145
using namespace std;
ifstream cin;
ofstream cout;
char buff[buffLen];
int index;
int ai[aiLen];
inline void read(int & num)
{
num = 0;
while(buff[index] < '0' || '9' < buff[index])
if( ++ index == buffLen)
{
index = 0;
cin.getline(buff, buffLen, '!');
}
while('0' <= buff[index] && buff[index] <= '9')
{
num = num * 10 + buff[index] - '0';
if( ++ index == buffLen)
{
index = 0;
cin.getline(buff, buffLen, '!');
}
}
}
inline void read(int & a, int & b)
{
read(a);
read(b);
}
inline void read(int & a, int & b, int & c)
{
read(a);
read(b);
read(c);
}
inline int max(int a, int b)
{
if(a > b) return a;
return b;
}
inline void update(int nod, int L, int R, int idx, int val)
{
if(L == idx && idx == R)
{
ai[nod] = val;
return;
}
int M = L + (R - L) / 2;
if(idx <= M) update(2 * nod, L, M, idx, val);
else update(2 * nod + 1, M + 1, R, idx, val);
ai[nod] = max(ai[2 * nod], ai[2 * nod + 1]);
}
inline int query(int nod, int L, int R, int a, int b)
{
if(a <= L && R <= b) return ai[nod];
int M = L + (R - L) / 2;
int ret1 = 0;
int ret2 = 0;
if(a <= M) ret1 = query(2 * nod, L, M, a, b);
if(b > M) ret2 = query(2 * nod + 1, M + 1, R, a, b);
return max(ret1, ret2);
}
int main()
{
cin.open("arbint.in");
cout.open("arbint.out");
// cin.getline(buff, buffLen, '!');
int N, M;
cin >> N >> M;
for(int i = 1; i <= N; ++ i)
{
int x;
cin >> x;
update(1, 1, N, i, x);
}
while(M -- )
{
int x, a, b;
cin >> x >> a >> b;
if(x == 0)
cout << query(1, 1, N, a, b) << '\n';
else
update(1, 1, N, a, b);
}
cin.close();
cout.close();
return 0;
}