#include <fstream>
#include <vector>
using namespace std;
ifstream fi; // input
ofstream fo; // output
vector<int> vec;
int m, n;
long max(long a, long b)
{
if (a > b) return a;
else return b;
}
int update(int nod, int st, int dr, int a, long b)
{
if ((a == st) && (a == dr))
{
vec[nod] = b;
return b;
}
else
{
int mij = (st + dr) / 2;
long sols = vec[2 * nod];
long sold = vec[2 * nod + 1];
if (a <= mij)
sols = update(2 * nod, st, mij, a, b);
if (a >= (mij + 1))
sold = update(2 * nod + 1, mij + 1, dr, a, b);
return vec[nod] = max(sols, sold);
}
}
int query(int nod, int st, int dr, int a, int b)
{
if ((a <= st) && (dr <= b))
return vec[nod];
else
{
int mij = (st + dr) / 2;
long sols = -1;
long sold = -1;
if (a <= mij)
sols = query(2 * nod, st, mij, a, b);
if (b >= (mij + 1))
sold = query(2 * nod + 1, mij + 1, dr, a, b);
return max(sols, sold);
}
}
int main()
{
vec.push_back(0); // vec[0]
fi.open("arbint.in");
fo.open("arbint.out");
fi >> n;
for (int i = 1; i<= 2*n + 1; i++)
vec.push_back(0);
fi >> m;
// sirul de numere
for (int i = 1; i<= n; i++)
{
int nr;
fi >> nr;
update(1, 0, n-1, i-1, nr);
}
// operatiile
for (int i = 1; i<= m; i++)
{
int tip, a, b;
fi >> tip >> a >> b;
if (tip == 0)
fo << query(1, 0, n-1, a-1, b-1) << "\n";
if (tip == 1)
update(1, 0, n-1, a-1, b);
}
fi.close();
fo.close();
return 0;
}