#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
const int NMAX = 100005;
const int INF = 2e9;
int n, m;
int v[NMAX];
vector<int>arb;
void init(int n)
{
int size = 1;
while (size < n)
size <<= 1;
size <<= 1;
arb.assign(size, 0);
}
int merge(int a, int b)
{
return max(a, b);
}
void build(int nod, int st, int dr)
{
if (st == dr)
{
arb[nod] = v[st];
return;
}
int mij = ((st + dr) >> 1);
build(2 * nod, st, mij);
build(2 * nod + 1, mij + 1, dr);
arb[nod] = merge(arb[2 * nod], arb[2 * nod + 1]);
}
void update(int nod, int st, int dr, int pos, int val)
{
if (st == dr)
{
arb[nod] = val;
return;
}
int mij = ((st + dr) >> 1);
if(mij >= pos && pos >= st)
update(2 * nod, st, mij, pos, val);
else if(dr >= pos && pos >= mij+1)
update(2 * nod + 1, mij + 1, dr, pos, val);
arb[nod] = merge(arb[2 * nod], arb[2 * nod + 1]);
}
int query(int nod, int st, int dr, int x, int y)
{
if (x <= st && dr <= y)
return arb[nod];
else if (y < st || x > dr)
return 0;
int mij = ((st + dr) >> 1);
return merge(query(2 * nod, st, mij, x, y), query(2 * nod + 1, mij + 1, dr, x, y));
}
void read()
{
fin >> n >> m;
for (int i = 1; i <= n; i++)
fin >> v[i];
init(n);
build(1, 1, n);
}
void solve()
{
while (m--)
{
int tip, x, y;
fin >> tip >> x >> y;
if (tip == 0)
fout << query(1, 1, n, x, y) << '\n';
else
update(1, 1, n, x, y);
}
}
int main()
{
read();
solve();
return 0;
}