#include <fstream>
using namespace std;
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
ifstream cin ("arbint.in");
ofstream cout ("arbint.out");
int v[100005];
int tree[400005];
int n, m;
static inline int max(int a, int b)
{
return (a >= b ? a : b);
}
void make(int nod, int st, int dr)
{
if (st == dr)
{
tree[nod] = v[st];
} else
{
int mij = (st + dr) >> 1;
make(nod << 1, st, mij);
make(nod << 1 | 1, mij + 1, dr);
tree[nod] = max(tree[nod << 1], tree[nod << 1 | 1]);
}
}
int ans;
void query(int nod, int st, int dr, int a, int b)
{
if (a <= st && dr <= b)
{
ans = max(ans, tree[nod]);
} else
{
int mij = (st + dr) >> 1;
if (a <= mij)
{
query(nod << 1, st, mij, a, b);
}
if (b > mij)
{
query(nod << 1 | 1, mij + 1, dr, a, b);
}
}
}
void update(int nod, int st, int dr, int pos, int val)
{
if (st == dr)
{
tree[nod] = val;
v[st] = val;
} else
{
int mij = (st + dr) >> 1;
if (pos <= mij)
{
update(nod << 1, st, mij, pos, val);
} else
{
update(nod << 1 | 1, mij + 1, dr, pos, val);
}
tree[nod] = max(tree[nod << 1], tree[nod << 1 | 1]);
}
}
int op, a, b;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> v[i];
}
make(1, 1, n);
for (int i = 1; i <= m; i++)
{
cin >> op >> a >> b;
if (op == 0)
{
ans = 0;
query(1, 1, n, a, b);
cout << ans << '\n';
} else
{
update(1, 1, n, a, b);
}
}
return 0;
}