#include <fstream>
#define MaxN 100005
#define EPS 1e-12
using namespace std;
ifstream cin("arbint.in");
ofstream cout("arbint.out");
int AINT[3*MaxN], v[MaxN], N, M, pos, val, st, dr;
void build(int nod, int st, int dr)
{
if (st == dr)
{
AINT[nod] = v[st];
}
else
{
int mid = (st + dr) / 2;
build(2*nod, st, mid);
build(2*nod+1, mid + 1, dr);
AINT[nod] = max(AINT[2*nod], AINT[2*nod+1]);
}
}
void update(int nod, int val, int pos, int st, int dr)
{
if (st == dr)
{
AINT[nod] = val;
}
else
{
int mid = (st+dr)/2;
if (pos <= mid)
{
update(2*nod, val, pos, st, mid);
}
else
{
update(2*nod+1, val, pos, mid + 1, dr);
}
AINT[nod] = max(AINT[2*nod], AINT[2*nod+1]);
}
}
void query(int nod, int st, int dr, int q_st, int q_dr, int &ans)
{
if (st >= q_st && dr <= q_dr) /// [st,dr] este cuprins in [q_st, q_dr]
{
ans = max(ans, AINT[nod]);
}
else
{
int mid = (st+dr)/2;
if (q_st <= mid) /// intervalul de query se intersecteaza la stanga
query(2*nod, st, mid, q_st, q_dr, ans);
if (mid+1 <= q_dr) /// intervalul de query se intersecteaza la dreapta
query(2*nod+1, mid+1, dr, q_st, q_dr, ans);
}
}
int main()
{
cin >> N >> M;
for (int i = 1; i <= N; i++)
{
cin >> v[i];
}
build(1, 1, N);
for (int i = 1; i <= M; i++)
{
int tip;
cin >> tip;
if (tip == 1)
{
int pos, val;
cin >> pos >> val;
update(1, val, pos, 1, N);
}
else
{ val = -1;
int a, b;
cin >> a >> b;
query(1, 1, N, a, b, val);
cout << val << "\n";
}
}
return 0;
}