#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
template<class type, class operation> class SegmentTree
{
private:
vector<type> segval;
operation op;
int n;
void build_(int node, int left, int right, vector<type>& elements);
void update_(int node, int left, int right, int pos, type val);
type rangeVal_(int node, int left, int right, int qleft, int qright);
void resize(int n);
public:
void build(vector<type>& elements);
void update(int pos, type val);
type rangeVal(int left, int right);
};
int main()
{
struct max_
{
long long operator()(long long a, long long b)
{
return max(a, b);
}
};
int n, q;
SegmentTree<long long, max_> nums;
vector<long long> temp;
fin >> n >> q;
temp.resize(n);
for(int i = 0; i < n; i++)
{
fin >> temp[i];
}
nums.build(temp);
for(int i = 0; i < q; i++)
{
long long type, a, b;
fin >> type >> a >> b;
if(type == 0)
{
a--;
b--;
fout << nums.rangeVal(a, b) << '\n';
}
else
{
a--;
nums.update(a, b);
}
}
return 0;
}
template<class type, class operation> void SegmentTree<type, operation>::build(vector<type>& elements)
{
this->resize(elements.size());
this->build_(1, 0, this->n - 1, elements);
}
template<class type, class operation> void SegmentTree<type, operation>::update(int pos, type val)
{
this->update_(1, 0, this->n - 1, pos, val);
}
template<class type, class operation> type SegmentTree<type, operation>::rangeVal(int left, int right)
{
return this->rangeVal_(1, 0, this->n - 1, left, right);
}
template<class type, class operation> void SegmentTree<type, operation>::build_(int node, int left, int right, vector<type>& elements)
{
if(left == right)
{
this->segval[node] = elements[left];
return;
}
int middle = left + (right - left) / 2;
this->build_(node * 2, left, middle, elements);
this->build_(node * 2 + 1, middle + 1, right, elements);
this->segval[node] = this->op(this->segval[node * 2], this->segval[node * 2 + 1]);
}
template<class type, class operation> void SegmentTree<type, operation>::update_(int node, int left, int right, int pos, type val)
{
if(left == right)
{
this->segval[node] = val;
return;
}
int middle = left + (right - left) / 2;
if(pos <= middle)
{
this->update_(node * 2, left, middle, pos, val);
}
else
{
this->update_(node * 2 + 1, middle + 1, right, pos, val);
}
this->segval[node] = this->op(this->segval[node * 2], this->segval[node * 2 + 1]);
}
template<class type, class operation> type SegmentTree<type, operation>::rangeVal_(int node, int left, int right, int qleft, int qright)
{
if(qleft <= left && right <= qright)
{
return this->segval[node];
}
int middle = left + (right - left) / 2;
type bestL, bestR;
bool foundL = false, foundR = false;
if(qleft <= middle)
{
foundL = true;
bestL = this->rangeVal_(node * 2, left, middle, qleft, qright);
}
if(qright >= middle + 1)
{
foundR = true;
bestR = this->rangeVal_(node * 2 + 1, middle + 1, right, qleft, qright);
}
if(foundL && foundR)
{
return this->op(bestL, bestR);
}
else if(foundL)
{
return bestL;
}
else
{
return bestR;
}
}
template<class type, class operation> void SegmentTree<type, operation>::resize(int n)
{
this->segval.resize(4 * n + 1);
this->n = n;
}