#include <vector>
#include <set>
#define ls u<<1
#define rs u<<1|1
using namespace std;
const int maxn=200005;
int a[maxn];
struct tree{
int val; // 节点值
int mx; // 区间最大值
}tr[4*maxn];
// 向上更新节点信息
void pushup(int u){
tr[u].mx=max(tr[ls].mx,tr[rs].mx);
}
// 构建线段树
void build(int u,int l,int r){
if(l==r){
tr[u]={a[l],a[l]};
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r); // 修正右子树范围
pushup(u);
}
// 更新操作:如果a位置的学生成绩低于b,则更新为b
void change(int u,int l,int r,int idx,int val){
if(l==r){
if(tr[u].val < val){
tr[u].val = val;
tr[u].mx = val;
}
return;
}
int mid=(l+r)>>1;
if(idx<=mid){
change(ls,l,mid,idx,val);
}
else{
change(rs,mid+1,r,idx,val);
}
pushup(u);
}
// 查询操作:查询[a,b]区间内的最大值
int query(int u,int l,int r,int a,int b){
// 当前区间与查询区间无交集
if(r < a || l > b) return 0;
// 当前区间完全在查询区间内
if(a <= l && r <= b) return tr[u].mx;
// 递归查询左右子树
int mid=(l+r)>>1;
return max(query(ls,l,mid,a,b), query(rs,mid+1,r,a,b));
}
int main() {
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
// 构建线段树
build(1,1,n);
// 处理m个操作
while(m--){
char c;
int a,b;
cin>>c>>a>>b;
if(c=='Q'){
// 查询操作
cout<<query(1,1,n,a,b)<<endl;
}
else if(c=='U'){
// 更新操作
change(1,1,n,a,b);
}
}
return 0;
}