#include <fstream>
#include <algorithm>
#define LG 400000
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
struct Graf { int max, pendingUpdate; };
int n, m;
Graf graf[LG];
void update(int nod, int st, int dr, int val, int intSt, int intDr)
{
if (graf[nod].pendingUpdate)
{
if (nod * 2 < LG)
{
graf[nod * 2].pendingUpdate = graf[nod].pendingUpdate;
graf[nod * 2 + 1].pendingUpdate = graf[nod].pendingUpdate;
}
graf[nod].max = graf[nod].pendingUpdate, graf[nod].pendingUpdate = 0;
}
if (intSt <= st && intDr >= dr)
{
graf[nod].max = val;
if (nod * 2 > LG)
return;
graf[nod * 2].pendingUpdate = val;
graf[nod * 2 + 1].pendingUpdate = val;
}
else
{
int mij = (st + dr) / 2;
if (intSt <= mij && intDr >= st)
update(nod * 2, st, mij, val, intSt, intDr);
if (intDr > mij && intSt <= dr)
update(nod * 2 + 1, mij + 1, dr, val, intSt, intDr);
graf[nod].max = max(graf[nod * 2].max, graf[nod * 2 + 1].max);
}
}
int querry(int nod, int st, int dr, int intSt, int intDr)
{
if (graf[nod].pendingUpdate)
{
if (nod * 2 < LG)
{
graf[nod * 2].pendingUpdate = graf[nod].pendingUpdate;
graf[nod * 2 + 1].pendingUpdate = graf[nod].pendingUpdate;
}
graf[nod].max = graf[nod].pendingUpdate, graf[nod].pendingUpdate = 0;
}
if (intSt <= st && dr <= intDr)
return graf[nod].max;
int mij = (st + dr) / 2;
int vmax = 0;
if (intSt <= mij && intDr >= st)
vmax = querry(nod * 2, st, mij, intSt, intDr);
if (intDr > mij && intSt <= dr)
vmax = max(vmax, querry(nod * 2 + 1, mij + 1, dr, intSt, intDr));
return vmax;
}
int main()
{
int a, b, op, val, poz;
fin >> n >> m;
for (int i = 1; i <= n; i++)
{
fin >> val;
update(1, 1, n, val, i, i);
}
for (int i = 1; i <= m; i++)
{
fin >> op >> a >> b;
if (op)
update(1, 1, n, b, a, a);
else
fout << querry(1, 1, n, a, b) << '\n';
}
return 0;
}