#include <fstream>
using namespace std;
ifstream cin ("arbint.in");
ofstream cout ("arbint.out");
const int MAX = static_cast<const int>(1e5 + 14);
int v [MAX];
int tree [MAX << 2];
void build (int node, int st, int dr)
{
if (st == dr)
{
tree[node] = v[st];
return;
}
int mij = (st + dr) / 2;
build(node * 2, st, mij);
build(node * 2 + 1, mij + 1, dr);
tree[node] = max(tree[node * 2], tree[node * 2 + 1]);
}
void update (int node, int st, int dr, const int pos, const int val)
{
if (st == dr)
{
tree[node] = val;
return;
}
int mij = (st + dr) / 2;
if (pos <= mij)
update(node * 2, st, mij, pos, val);
else update(node * 2 + 1, mij + 1, dr, pos, val);
tree[node] = max(tree[node * 2], tree[node * 2 + 1]);
}
int query (int node, int st, int dr, const int a, const int b)
{
if (a <= st and dr <= b)
return tree[node];
int mij = (st + dr) / 2;
int answer = 0;
if (a <= mij)
answer = max(answer, query(node * 2, st, mij, a, b));
if (b > mij)
answer = max(answer, query(node * 2 + 1, mij + 1, dr, a, b));
return answer;
}
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++ i)
cin >> v [i];
build(1, 1, n);
while (m --)
{
int tip;
cin >> tip;
if (!tip)
{
int a, b;
cin >> a >> b;
cout << query(1, 1, n, a, b) << '\n';
}
else
{
int pos, val;
cin >> pos >> val;
update(1, 1, n, pos, val);
}
}
return 0;
}