#include <bits/stdc++.h>
using namespace std;
const int nmax = 100009;
int A[nmax];
class SegmentTree
{
private :
int ls[4 * nmax] , rs[4 * nmax] , lo[4 * nmax] , hi[4 * nmax] , aint[4 * nmax];
vector < int > nodes;
void getIntervals(int x , int l , int r , int lq , int rq)
{
if (lq <= l && r <= rq)
{
nodes.push_back(x);
return;
}
int c = (l + r) / 2;
propagate(x);
if (lq <= c) getIntervals(ls[x] , l , c , lq , rq);
if (c < rq) getIntervals(rs[x] , c + 1 , r , lq , rq);
refresh(x);
}
void refresh(int x)
{
aint[x] = max(aint[ls[x]] , aint[rs[x]]);
}
void build(int x , int l , int r)
{
lo[x] = l , hi[x] = r;
if (l == r)
{
aint[x] = A[l];
return;
}
int c = (l + r) / 2;
ls[x] = x + x + 1 , rs[x] = x + x + 2;
build(ls[x] , l , c);
build(rs[x] , c + 1 , r);
refresh(x);
}
void propagate(int x)
{
//
}
public :
int N;
void init(int stSize)
{
N = stSize;
build(0 , 0 , N);
}
void update(int x , int l , int r , int lq , int rq , int val)
{
if (lq <= l && r <= rq)
{
aint[x] = val;
return ;
}
int c = (l + r) / 2;
propagate(x);
if (lq <= c) update(ls[x] , l , c , lq , rq , val);
if (c < rq) update(rs[x] , c + 1 , r , lq , rq , val);
refresh(x);
}
int query(int l , int r)
{
nodes.clear(); getIntervals(0 , 0 , N , l , r);
int bst = aint[nodes[0]];
for (int i = 0 ; i < nodes.size() ; ++i)
bst = max(bst , aint[nodes[i]]);
return bst;
}
} solver;
int main()
{
freopen("arbint.in" , "r" , stdin);
freopen("arbint.out" , "w" , stdout);
int N , M;
scanf("%d" , &N);
scanf("%d" , &M);
for (int i = 0 ; i < N ; ++i)
cin >> A[i];
solver.init(N - 1);
for (int i = 0 ; i < M ; ++i)
{
int T;
scanf("%d" , &T);
if (T == 1)
{
int pos , val;
scanf("%d" , &pos) , pos--;
scanf("%d" , &val);
solver.update(0 , 0 , N - 1 , pos , pos , val);
}
else
{
int l , r;
scanf("%d" , &l) , l--;
scanf("%d" , &r) , r--;
printf("%d\n" , solver.query(l , r));
}
}
return 0;
}