#include <cstdio>
#include <climits>
#include <algorithm>
#define left (2*nod)
#define right (2*nod+1)
using namespace std;
const int Nmax = 100010;
int n , m , i , x , y , tip;
int arb[3*Nmax];
void update(int nod , int st , int dr , int val , int poz)
{
if (st >= dr) {arb[nod] = val; return;}
int mij = (st + dr) >> 1;
if (poz <= mij) update(left , st , mij , val , poz);
else update(right , mij + 1 , dr , val , poz);
arb[nod] = max(arb[left] , arb[right]);
}
int query(int nod , int st , int dr , int a , int b)
{
if (a <= st && dr <= b) return arb[nod];
int mij = (st + dr) >> 1;
int val1 = (a <= mij) ? query(left , st , mij , a , b) : INT_MIN;
int val2 = (mij < b) ? query(right , mij + 1 , dr , a , b) : INT_MIN;
return max(val1 , val2);
}
int main()
{
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
scanf("%d %d", &n, &m);
for (i = 1; i <= n; update(1 , 1 , n , x , i) , ++i)
scanf("%d", &x);
for ( ; m ; --m)
{
scanf("%d %d %d", &tip , &x , &y);
if (!tip) printf("%d\n", query(1 , 1 , n , x , y));
else update(1 , 1 , n , y , x);
}
return 0;
}