#include <bits/stdc++.h>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, m, x;
int maxim; //folositor in cazul in care intervalul cerut se desparte pe ramura stanga si dreapta a radacinii
int arb[400001];
void inlocuire(int lim_st, int lim_dr, int nod, int val, int poz)
{
if (lim_st == lim_dr)
arb[nod] = val;
else
{
int lim_m = (lim_st+lim_dr)/2;
if (poz <= lim_m)
inlocuire(lim_st,lim_m,nod*2,val,poz);
else
inlocuire(lim_m+1,lim_dr,nod*2+1,val,poz);
arb[nod] = max(arb[nod*2],arb[nod*2+1]);
}
}
void gasireMax(int lim_st,int lim_dr, int nod, int a, int b)
{
if (a <= lim_st && lim_dr <= b)
maxim = max(arb[nod],maxim);
else
{
int lim_m = (lim_st+lim_dr)/2;
if (a <= lim_m)
gasireMax(lim_st,lim_m,nod*2,a,b);
if (b > lim_m)
gasireMax(lim_m+1,lim_dr,nod*2+1,a,b);
}
}
int main()
{
fin>>n>>m;
for (int i = 1; i <= n; i++)
{
fin>>x;
inlocuire(1,n,1,x,i);
}
for (int i = 0; i < m; i++)
{
int com, a, b;
fin>>com>>a>>b;
if (!com)
{
maxim = -1;
gasireMax(1,n,1,a,b);
fout<<maxim<<'\n';
}
else
{
inlocuire(1,n,1,b,a);
}
}
}