#include <bits/stdc++.h>
#define nmax 300001
#define inf 100000000000000000
#define int long long
using namespace std;
struct AINT
{
int aint[4 * nmax], lazy[4 * nmax];
void build(int v[], int ind, int st, int dr)
{
lazy[ind] = 0;
if (st == dr)
aint[ind] = v[st];
else
{
build(v, 2 * ind, st, (st + dr) / 2);
build(v, 2 * ind + 1, (st + dr) / 2 + 1, dr);
aint[ind] = max(aint[2 * ind], aint[2 * ind + 1]);
}
}
void propag(int ind, int st, int dr)
{
if (lazy[ind])
{
aint[ind] = lazy[ind];
if (st != dr)
lazy[2 * ind] = lazy[ind], lazy[2 * ind + 1] = lazy[ind];
lazy[ind] = 0;
}
}
void update(int ind, int val, int stu, int dru, int st, int dr)
{
propag(ind, st, dr);
if (stu <= st && dru >= dr)
{
lazy[ind] = val;
propag(ind, st, dr);
}
else
{
int mij = (st + dr) / 2;
if (stu <= mij)
update(2 * ind, val, stu, dru, st, mij);
if (dru > mij)
update(2 * ind + 1, val, stu, dru, mij + 1, dr);
propag(2 * ind, st, mij), propag(2 * ind + 1, mij + 1, dr);
aint[ind] = max(aint[2 * ind], aint[2 * ind + 1]);
}
}
int query(int ind, int stq, int drq, int st, int dr)
{
propag(ind, st, dr);
if (st >= stq && dr <= drq)
return aint[ind];
else
{
int mij = (st + dr) / 2, maxx = -inf;
if (st != dr)
propag(2 * ind, st, mij), propag(2 * ind + 1, mij + 1, dr);
if (stq <= mij)
maxx = max(maxx, query(2 * ind, stq, drq, st, mij));
if (drq > mij)
maxx = max(maxx, query(2 * ind + 1, stq, drq, mij + 1, dr));
return maxx;
}
}
};
AINT x;
int v[nmax];
signed main()
{
ifstream cin("arbint.in");
ofstream cout("arbint.out");
int n, m, a, b, c, i, d;
cin >> n >> m;
for (i = 1; i <= n; i++)
cin >> v[i];
x.build(v, 1, 1, n);
while (m)
{
cin >> c >> a >> b;
if (c == 0)
cout << x.query(1, a, b, 1, n) << '\n';
else
{
x.update(1, b, a, a, 1, n);
}
m--;
}
return 0;
}