rt
#include<bits/stdc++.h>
using namespace std;
typedef long long LL; //不开long long见祖宗
const LL N=1e5+10;
LL tree[4*N],a[N],add[4*N],n; //节点数最多4N
void build(LL l,LL r,LL k){//l:左端点 r:右端点 k:节点编号
if(l==r){//如果是叶子节点(叶子节点的左右端点相等,即长度为1)
tree[k]=a[l];//赋值
return;
}
LL mid=(l+r)>>1;//取中间值,分割
build(l,mid,2*k);//拆分左子树
build(mid+1,r,2*k+1);//拆分右子树
tree[k]=max(tree[2*k],tree[2*k+1]);//pushup:回溯时利用子节点更新父节点(此处维护最大值)
}
void change(LL k,LL l,LL r,LL v){//修改一个节点
tree[k]+=v*(r-l+1);//修改值
add[k]+=v;//标记
}
void down(LL k,LL l,LL r){//标记下放
if(add[k]!=0){
LL mid=(l+r)>>1;
change(k*2,l,mid,add[k]);//下放到左孩子
change(k*2+1,mid+1,r,add[k]);//下放到右孩子
add[k]=0;//父节点标记清空
}
}
void update(LL k,LL l,LL r,LL x,LL y,LL v){//把节点p的值改为x l:左端点 r:右端点 k:当前节点编号
if(l>=x && r<=y){//如果无需继续递归就停止
change(k,l,r,v);//修改该节点的值
return;
}
//如果区间没有完全包含在修改范围内(需要继续递归)
down(k,l,r);//标记下放给左右子树
LL mid=(l+r)>>1;//分割
if(x<=mid) update(2*k,l,mid,x,y,v);//左子树
if(y>mid) update(2*k+1,mid+1,r,x,y,v);//右子树
tree[k]=tree[2*k]+tree[2*k+1];//加和维护
}
LL quary(LL k,LL l,LL r,LL x,LL y){//查询x到y的区间最大值
if(l>=x && r<=y){//如果当前的区间完全包含在查询区间中时,不需要继续递归
return tree[k];//直接返回答案
}
down(k,l,r); //要递归左右子树,所以下放标记
LL mid=(l+r)>>1;//分割
LL res=0;//记录和
if(x<=mid){//左区间有覆盖
res=max(res,quary(2*k,l,mid,x,y));//递归左子树
}
if(y>mid){//右区间有覆盖
res=max(res,quary(2*k+1,mid+1,r,x,y));//递归右子树
}
return res;//返回和
}
LL m;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,n,1);
for(LL i=1;i<=m;i++){
char t;
cin>>t;
if(t=='U'){
LL x,y,k;
cin>>x>>k;
int v=quary(1,1,n,x,x);
if(v<k) update(1,1,n,x,x,k-v);
}else{
LL x,y;
cin>>x>>y;
cout<<quary(1,1,n,x,y)<<endl;
}
}
return 0;
}