#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;
}