#include <fstream>
using namespace std;
namespace PhD {
class SegmentTreeElement
{
private:
//long long value;
public:
virtual void change(void *other)
{
//value = other.value;
}
virtual void combine(void * a, void * b)
{
//value = (a.value > b.value) ? a.value : b.value;
}
//virtual long long get(value);
};
template <class T>
class SegmentTree
{
private:
T* arbore;
long long arboreSize;
long long coordonateFixer;
void update(long long node, long long left, long long right, long long *a, long long *b, T* val)
{
if (*a <= left && *b >= right) // [a, b] includes [left, right]
{
arbore[node].change(val);
return;
}
long long mid = (left + right) / 2;
if (*a <= mid)
{
update(2*node, left, mid, a, b, val);
}
if (*b > mid)
{
update(2*node + 1, mid + 1, right, a, b, val);
}
arbore[node].combine(&arbore[2*node], &arbore[2*node+1]);
}
T query(long long node, long long left, long long right, long long *a, long long *b)
{
if (*a <= left && *b >= right)
{
return arbore[node];
}
long long mid = (left + right) / 2;
if (*a <= mid)
{
T q1 = query(2*node, left, mid, a, b);
if (*b > mid)
{
T q2 = query(2*node + 1, mid + 1, right, a, b);
T temp;
temp.combine(&q2, &q1);
return temp;
}
return q1;
}
else if (*b > mid)
{
return query(2*node + 1, mid + 1, right, a, b);
}
}
public:
// change value in [a, b]
void changeValue(long long a, long long b, T & value)
{
a -= coordonateFixer;
b -= coordonateFixer;
update(1, 1, arboreSize, &a, &b, &value);
}
// get value in [a, b]
T getValue(long long int a, long long int b)
{
a -= coordonateFixer;
b -= coordonateFixer;
return query(1, 1, arboreSize, &a, &b);
}
SegmentTree(long long left, long long right)/*:maxSize(s+1)*/
{
coordonateFixer = left - 1;
long long int s = right - left + 1;
arboreSize = s;
for (s = 1; s < arboreSize; s <<= 1);
arbore = new T[s*2];
}
~SegmentTree()
{
delete[] arbore;
}
};
}
class STMaxLL : public PhD::SegmentTreeElement
{
public:
long long value;
virtual void change(void * other)
{
value = ((STMaxLL*) other)->value;
}
virtual void combine(void * a, void * b)
{
STMaxLL * x = (STMaxLL*) a;
STMaxLL * y = (STMaxLL*) b;
value = (x->value > y->value) ? x->value : y->value;
}
};
int main()
{
FILE * fin = fopen("arbint.in", "r");
FILE * fout = fopen("arbint.out", "w");
int n, m;
fscanf(fin, "%d%d", &n, &m);
PhD::SegmentTree<STMaxLL> arbore(1, n);
STMaxLL tmp;
for (int i = 1; i <= n; ++i)
{
fscanf(fin, "%lld", &(tmp.value));
arbore.changeValue(i, i, tmp);
}
long long int x, y, z;
while (m--)
{
fscanf(fin, "%lld%lld%lld", &x, &y, &z);
if (x)
{
tmp.value = z;
arbore.changeValue(y, y, tmp);
} else {
fprintf(fout, "%lld\n", arbore.getValue(y, z).value);
}
}
fclose(fin);
fclose(fout);
return 0;
}