#include <bits/stdc++.h>
using namespace std;
ifstream fin ("arbint.in");
ofstream fout ("arbint.out");
const int NMAX = 100005;
int a[NMAX], arbint[4 * NMAX], n, Q;
inline void BUILD(int node, int left, int right)
{
if(left == right)
{
arbint[node] = a[right];
return;
}
int middle;
middle = (left + right) / 2;
BUILD(2 * node, left, middle);
BUILD(2 * node + 1, middle + 1, right);
arbint[node] = max(arbint[2 * node], arbint[2 * node + 1]);
}
inline void UPDATE(int node, int left, int right, int P, int V)
{
if(left == right)
{
arbint[node] = V;
return;
}
int middle;
middle = (left + right) / 2;
if(P <= middle)
UPDATE(2 * node, left, middle, P, V);
else UPDATE(2 * node + 1, middle + 1, right, P, V);
arbint[node] = max(arbint[2 * node], arbint[2 * node + 1]);
}
inline int QUERY(int node, int left, int right, int X, int Y)
{
if(left == X && right == Y)
return arbint[node];
int middle;
middle = (left + right) / 2;
if(Y <= middle) /// intervalul se afla in totalitate in fiul stang
return QUERY(2 * node , left , middle , X , Y);
else if(X > middle) /// intervalul se afla in totalitate in fiul drept
return QUERY(2 * node + 1 , middle + 1 , right , X , Y);
else return max(QUERY(2 * node , left , middle , X , middle) , QUERY(2 * node + 1, middle + 1 , right , middle + 1 , Y)); /// se afla in cei doi fii
}
int main()
{
int x , y , op;
fin >> n >> Q;
for(int i = 1 ; i <= n ; i++)
fin >> a[i];
BUILD(1, 1, n);
while(Q -- )
{
fin >> op >> x >> y;
if(op == 1)
UPDATE(1 , 1 , n , x , y);
else fout << QUERY(1 , 1 , n , x , y) << "\n";
}
fin.close();
fout.close();
return 0;
}