#include <bits/stdc++.h>
//#pragma GCC optimize("Ofast")
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
//const int INF = 0x3F3F3F3F;
int t[200000];
//int v[100001], t[400001];
/*void Build(int i, int tl, int tr)
{
if (tl == tr)
t[i] = v[tl];
else
{
int mid;
mid = (tl + tr) / 2;
Build(i * 2, tl, mid);
Build(i * 2 + 1, mid + 1, tr);
t[i] = max(t[i * 2], t[i * 2 + 1]);
}
}*/
/*int Compute(int i, int tl, int tr, int l, int r)
{
if (l > r)
return -INF;
if (l == tl && r == tr)
return t[i];
int mid;
mid = (tl + tr) / 2;
return max(Compute(i * 2, tl, mid, l, min(mid, r)), Compute(i * 2 + 1, mid+1, tr, max(mid+1, l), r));
}*/
/*void Update(int i, int tl, int tr, int pos, int val)
{
if (tl == tr)
t[i] = val;
else
{
int mid;
mid = (tl + tr) / 2;
if (pos <= mid)
Update(i * 2, tl, mid, pos, val);
else
Update(i * 2 + 1, mid + 1, tr, pos, val);
t[i] = max(t[i * 2], t[i * 2 + 1]);
}
}*/
int Compute(int l, int r, int n)
{
int ans;
ans = 0;
for (l += n, r += n; l < r; l /= 2, r /= 2)
{
if (l % 2)
ans = max(ans, t[l++]);
if (r % 2)
ans = max(ans, t[--r]);
}
return ans;
}
void Update(int pos, int val, int n)
{
for (t[pos += n] = val; pos > 1; pos /= 2)
t[pos / 2] = max(t[pos], t[pos ^ 1]);
}
int main()
{
/*int n, Q, i, task, a, b;
fin >> n >> Q;
for (i = 1; i <= n; ++i)
fin >> v[i];
Build(1, 1, n);
while (Q--)
{
fin >> task >> a >> b;
if (!task)
fout << Compute(1, 1, n, a, b) << '\n';
else
Update(1, 1, n, a, b);
}
fout.close();*/
int n, Q, i, task, a, b;
fin >> n >> Q;
for (i = 0; i < n; ++i)
fin >> t[n + i];
for (i = n - 1; i; --i)
t[i] = max(t[i * 2], t[i * 2 + 1]);
while (Q--)
{
fin >> task >> a >> b;
if (!task)
fout << Compute(a-1, b, n) << '\n';
else
Update(a-1, b, n);
}
return 0;
}