#include <fstream>
#define max(a, b) a > b ? a : b
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
long long int tree[400005], v[100005];
int n, m;
bool task;
void read();
long long int query(int node, int x, int y, int left, int right);
void update(int node, int pos, int val, int left, int right);
int main()
{
read();
return 0;
}
void read()
{
int i;
long long int a, b;
fin >> n >> m;
for (i = 1; i <= n; i++)
fin >> v[i];
for (i = 1; i <= n; i++)
update(1, i, v[i], 1, n);
for (i = 1; i <= m; i++)
{
fin >> task >> a >> b;
if (!task)
fout << query(1, 1, n, a, b) << '\n';
else
update(1, a, b, 1, n);
}
}
long long int query(int node, int left, int right, int x, int y)
{
int lo = 0, hi = 0;
if (x <= left && right <= y)
return tree[node];
else
{
int mid = (left + (right - left) / 2);
if (x <= mid)
lo = query(2 * node, left, mid, x, y);
if (mid < y)
hi = query(2 * node + 1, mid + 1, right, x, y);
return max(lo, hi);
}
}
void update(int node, int pos, int val, int left, int right)
{
if (left == right)
tree[node] = val;
else
{
int mid = (left + (right - left) / 2);
if (pos <= mid)
update(2 * node, pos, val, left, mid);
else
update(2 * node + 1, pos, val, mid + 1, right);
tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
}