#include <iostream>
#include <fstream>
#define NMAX 100001
using namespace std;
ifstream fin;
ofstream fout;
int n, m; //nr of elements, nr of operations
int array[NMAX];
int tree[4*NMAX];
void read();
void build(int pos, int tl, int tr)
{
if (tl == tr) {
tree[pos] = array[tl];
} else {
int tm = (tl + tr) / 2;
build(pos*2, tl, tm);
build(pos*2 + 1, tm + 1, tr);
tree[pos] = max(tree[pos*2], tree[pos*2 + 1]);
}
}
void update(int pos, int tl, int tr, int posInsert, int valueInsert)
{
if (tl == tr) {
tree[pos] = valueInsert;
} else {
int tm = (tl + tr) / 2;
if (posInsert <= tm)
update(pos*2, tl, tm, posInsert, valueInsert);
else
update(pos*2 + 1, tm + 1, tr, posInsert, valueInsert);
tree[pos] = max(tree[pos*2], tree[pos*2 + 1]);
}
}
int maximum(int pos, int tl, int tr, int l, int r)
{
if(l > r)
return 0;
if (l == tl && r == tr)
return tree[pos];
int tm = (tl + tr) / 2;
return max (maximum(pos*2, tl, tm, l, min(r, tm)),
maximum(pos*2 +1, tm+1, tr, max(l, tm+1), r));
}
void printTree()
{
for (int i = 1; i <= 4*n; i++)
cout << tree[i] << " ";
cout << '\n';
}
int main() {
fin.open("arbint.in");
fout.open("arbint.out");
read();
build(1, 1, n);
//printTree();
for (int i = 1; i <= m; i++)
{
int q, a, b;
fin >> q >> a >> b;
if (q == 0)
{
fout << maximum(1, 1, n, a, b) << '\n';
} else {
int valB = array[b];
array[a] = valB;
update(1, 1, n, a, valB);
//printTree();
}
}
fin.close();
fout.close();
return 0;
}
void read()
{
fin >> n >> m;
for (int i = 1; i <= n; i++)
{
fin >> array[i];
}
}