#include <bits/stdc++.h>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
const int MAXN = 2e5 + 1;
int aint[MAXN * 4], n;
int merge(int x, int y) {
return max(x, y);
}
void build(int node, int st, int dr) {
if (st == dr) {
cin >> aint[node];
return;
}
int mid = (st + dr) / 2;
build(node * 2, st, mid);
build(node * 2 + 1, mid + 1, dr);
aint[node] = merge(aint[node * 2], aint[node * 2 + 1]);
}
void update(int pos, int val, int node, int st, int dr) {
if (st == dr) {
aint[node] = val;
return;
}
int mid = (st + dr) / 2;
if (pos <= mid)
update(pos, val, node * 2, st, mid);
else
update(pos, val, node * 2 + 1, mid + 1, dr);
aint[node] = merge(aint[node * 2], aint[node * 2 + 1]);
}
int query(int x, int y, int node, int st, int dr) {
if (x <= st && dr <= y)
return aint[node];
if (dr < x || y < st)
return 0; // Sau alta valoare de identitate in functie de operatie
int mid = (st + dr) / 2;
int max_st = query(x, y, node * 2, st, mid);
int max_dr = query(x, y, node * 2 + 1, mid + 1, dr);
return merge(max_st, max_dr);
}
int main() {
int m, op;
fin >> n >> m;
build(1, 1, n);
while (m--) {
fin >> op;
if (op == 1) {
int pos, val;
fin >> pos >> val;
update(pos, val, 1, 1, n);
} else {
int st, dr;
fin >> st >> dr;
fout << query(st, dr, 1, 1, n) << '\n';
}
}
return 0;
}