#include<stdio.h>
#define size 1000100
#define maxNum(a,b) a>b?a:b
typedef struct node
{
int left,right;
int max;
};
int num[size],id,maxValue;
node tree[size];
void creat(int left,int right,int no)/**建树*/
{
int mid=(left+right)/2;
tree[no].left=left;
tree[no].right=right;
if(left==right)/**当区间为单个元素的时候,录入对应的值*/
{
tree[no].max=num[id++];
return ;
}
creat(left,mid,no*2);/**递归处理左子树*/
creat(mid+1,right,no*2+1);/**递归处理右子树*/
tree[no].max=maxNum(tree[no*2].max,tree[no*2+1].max);/**更新父亲结点*/
}
void update(int no,int idx,int value)/**修改和更新*/
{
int mid=(tree[no].left+tree[no].right)/2;
if(tree[no].left==tree[no].right)
{
tree[no].max=value;
return ;
}
if(idx>mid)/**如果需更新的结点编号大于当前区间,递归处理右子树*/
update(no*2+1,idx,value);
if(idx<=mid)/**继续处理左子树*/
update(no*2,idx,value);
tree[no].max=maxNum(tree[no*2].max,tree[no*2+1].max);/**回溯的时候顺便更新下父亲结点*/
}
void query(int left,int right,int no)/**问答函数,原理和更新函数类似*/
{
int mid=(tree[no].left+tree[no].right)/2;
if(left<=tree[no].left&&tree[no].right<=right)
{
maxValue=maxNum(maxValue,tree[no].max);
return ;
}
if(left<=mid)
query(left,right,no*2);
if(right>mid)
query(left,right,no*2+1);
}
int main()
{
char order;
int n,m;
while(~scanf("%d%d",&n,&m))
{
int i,a,b;
maxValue=-1;
id=0;
for(i=0;i<n;i++)
scanf("%d",&num[i]);
creat(1,n,1);/**建树的时候从区间1-N(即总区间)开始往下*/
for(i=0;i<m;i++)
{
scanf("\n%c%d%d",&order,&a,&b);
if(order=='U')
update(1,a,b);/**插入和更新下标从1(即最顶层的结点)开始往下*/
if(order=='Q')
{
query(a,b,1);
printf("%d\n",maxValue);
maxValue=-1;
}
}
}
return 0;
}