#include <iostream>
#include <fstream>
#include <math.h>
#include <utility>
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
int a[100001], b[100001];
int n, m, cont = 1, root;
pair<int, int> x;
void update(int poz, int val)
{
int secv = poz/root;
if(poz%root)
secv++;
if(val > b[secv])
b[secv] = val;
else
{
if(a[poz] == b[secv])
{
int maxi = -1;
a[poz] = val;
for(int i = root*(secv-1)+1; i <= root*secv; i++)
maxi = max(a[i], maxi);
b[secv] = maxi;
}
}
a[poz] = val;
}
int query(int l, int r)
{
int maxi = -1;
for(int i = l; i <= r; i++)
{
int secv, start, finish;
secv = i/root;
if(i%root)
secv++;
start = root*(secv-1)+1;
finish = root*secv;
if(l <= start && finish <= r)
{
maxi = max(maxi, b[secv]);
i += root-1;
}
else
maxi = max(maxi, a[i]);
}
return maxi;
}
int main()
{
in >> n >> m;
root = sqrt(n);
///For-ul creeaza vectorii a si b - functional
for(int i = 1; i <= n; i++)
{
in >> a[i];
x.first++;
x.second = max(a[i], x.second);
if(x.first == root)
{
b[cont++] = x.second;
x.first = x.second = 0;
}
}
while(m)
{
int rez, aux1, aux2;
in >> rez >> aux1 >> aux2;
if(rez)
{
update(aux1, aux2);
}
else
out << query(aux1, aux2) << '\n';
m--;
}
return 0;
}