#include <fstream>
#include <vector>
#include <utility>
#define leftSon node*2
#define rightSon node*2 + 1
using namespace std;
class staticIntervalTree
{
private:
int tree[2000010], treeSize, maximum;
void trueUpdate(int val, int node, int left, int right, int pos)
{
if(left == right)
tree[node] = val;
else
{
int mid = (left + right) / 2;
if(pos <= mid)
trueUpdate(val, leftSon, left, mid, pos);
else
trueUpdate(val, rightSon, mid + 1, right, pos);
tree[node] = max(tree[leftSon], tree[rightSon]);
}
}
void trueQuery(int node, int left, int right, int start, int stop)
{
if(start <= left && stop >= right)
maximum = max(maximum, tree[node]);
else
{
int mid = (left + right) / 2;
if(start <= mid)
trueQuery(leftSon, left, mid, start, stop);
if(stop > mid)
trueQuery(rightSon, mid + 1, right, start, stop);
}
}
public:
staticIntervalTree(int inSize)
{
treeSize = inSize;
for(int i = 0; i <= inSize; ++i)
tree[i] = 0;
}
void update(int value, int position)
{
trueUpdate(value, 1, 1, treeSize, position);
}
int query(int start, int stop)
{
maximum = 0;
trueQuery(1, 1, treeSize, start, stop);
return maximum;
}
int size()
{
return treeSize;
}
};
int main()
{
int noElements, noOperations;
ifstream in("arbint.in");
in >> noElements >> noOperations;
staticIntervalTree tr(noElements);
for(int i = 1, inTemp; i <= noElements; ++i)
{
in >> inTemp;
tr.update(inTemp, i);
}
ofstream out("arbint.out");
for(int i = 0, inOperator; i < noOperations; ++i)
{
in >> inOperator;
if(inOperator == 1)
{
int inTemp, inPos;
in >> inPos >> inTemp;
tr.update(inTemp, inPos);
}
else
{
int start, stop;
in >> start >> stop;
out << tr.query(start, stop) << "\n";
}
}
in.close();
out.close();
return 0;
}