#include <fstream>
#include <set>
#include <vector>
#include <bitset>
#include <map>
#include <climits>
#pragma GCC optimize("O3,Ofast,unroll-loops")
using namespace std;
ifstream cin("arbint.in");
ofstream cout("arbint.out");
const int NMAX = 100000;
int Tree[4*NMAX+5],n,k;
void Build(int st,int dr,int node) {
if (st == dr) {
cin>>Tree[node];
return;
}
int mid = (st + dr) / 2;
Build(st,mid,node*2);
Build(mid+1,dr,node*2+1);
Tree[node] = max(Tree[node*2],Tree[node*2+1]);
}
void Update(int st,int dr,int node,int pos,int x) {
if (st == dr) {
Tree[node] = x;
return;
}
int mid = (st + dr) / 2;
if (mid < pos) {
Update(mid+1,dr,node*2+1,pos,x);
}
else {
Update(st,mid,node*2,pos,x);
}
Tree[node] = max(Tree[node*2],Tree[node*2+1]);
}
int ans;
void intQuerry(int st,int dr,int node,int p1,int p2) {
if (st >= p1 && dr <= p2) {
ans = max(ans,Tree[node]);
return;
}
int mid = (st + dr) / 2;
if (mid >= p1) {
intQuerry(st,mid,node*2,p1,p2);
}
if (mid+1 <= p2) {
intQuerry(mid+1,dr,node*2+1,p1,p2);
}
}
int Querry(int p1,int p2) {
ans = LONG_MIN;
intQuerry(1,n,1,p1,p2);
return ans;
}
int main() {
cin>>n>>k;
Build(1,n,1);
for (int i=1; i<=k; i++) {
int a,b,c;
cin>>a>>b>>c;
if (a == 0) {
cout<<Querry(b,c)<<"\n";
}
else {
Update(1,n,1,b,c);
}
}
}