#include <bits/stdc++.h>
using namespace std;
const long long INF = (long long)-4e18;
struct SegTree
{
int n;
vector<long long> tree;
void init(int _n)
{
n=_n;
tree.assign(4 * n + 4, 0);
}
void build(const vector<long long> &a, int node, int l, int r)
{
if (l == r)
{
tree[node] = a[l];
return;
}
int mid = (l + r) / 2;
build(a, node * 2, l, mid);
build(a, node * 2 + 1, mid + 1, r);
tree[node] = max(tree[node * 2], tree[node * 2 + 1]);
}
void build(const vector<long long> &a)
{
build(a, 1, 1, n);
}
void pointUpdate(int node, int l, int r, int pos, long long val)
{
if (l == r)
{
tree[node] = val;
return;
}
int mid = (l + r) / 2;
if (pos <= mid) pointUpdate(node * 2, l, mid, pos, val);
else pointUpdate(node * 2 + 1, mid + 1, r, pos, val);
tree[node] = max(tree[node * 2], tree[node * 2 + 1]);
}
void pointUpdate(int pos, long long val)
{
pointUpdate(1, 1, n, pos, val);
}
long long rangeQuery(int node, int l, int r, int ql, int qr)
{
if (qr < l || r < ql)
{
return INF;
}
if (ql <= l && r <= qr)
{
return tree[node];
}
int mid = (l + r) / 2;
long long leftMin = rangeQuery(node * 2, l, mid, ql, qr);
long long rightMin = rangeQuery(node * 2 + 1, mid + 1, r, ql, qr);
return max(leftMin, rightMin);
}
long long rangeQuery(int l, int r)
{
return rangeQuery(1, 1, n, l, r);
}
};
int main()
{
int n, q;
cin >> n >> q;
vector<long long> a(n + 1);
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
SegTree ST;
ST.init(n);
ST.build(a);
while (q--)
{
int type;
cin >> type;
if (type == 1)
{
int pos;
long long x;
cin >> pos >> x;
ST.pointUpdate(pos, x);
}
else if (type == 0)
{
int l, r;
cin >> l >> r;
cout << ST.rangeQuery(l, r) << "\n";
}
}
return 0;
}