#include<stdio.h>
#include<string.h>
#define R(x) x<<1|1
#define L(x) x<<1
#define MID(x,y) (x+y)>>1
#define max(a,b) a>b?a:b
const int MAX=200010;
struct {int s,l,r;}node[3*MAX];
int c[MAX];
int get_val()
{
int ret(0);
char c;
while((c=getchar())==' '||c=='\n'||c=='\r');
ret=c-'0';
while((c=getchar())!=' '&&c!='\n'&&c!='\r')
ret=ret*10+c-'0';
return ret;
}
void init()
{
memset(node,0,sizeof(node));
}
void build(int p,int l,int r)
{
node[p].l=l;
node[p].r=r;
if(l==r-1)
{
node[p].s=c[l];
return ;
}
int mid=MID(l,r);
build(L(p),l,mid);
build(R(p),mid,r);
node[p].s=max(node[L(p)].s,node[R(p)].s);
}
void update(int p,int l,int r,int score)
{
if(node[p].l==l&&node[p].r==r)
{
node[p].s=score;
return ;
}
int mid=MID(node[p].l,node[p].r);
if(l>=mid)
update(R(p),l,r,score);
else
if(r<=mid)
update(L(p),l,r,score);
else
{
update(R(p),mid,r,score);
update(L(p),l,mid,score);
}
node[p].s=max(node[L(p)].s,node[R(p)].s);
}
int query(int p,int l,int r)
{
if(node[p].l>=l&&node[p].r<=r)
return node[p].s;
int mid=MID(node[p].l,node[p].r);
if(l>=mid)
return query(R(p),l,r);
else
if(r<=mid)
return query(L(p),l,r);
else
return max(query(L(p),l,mid),query(R(p),mid,r));
}
int main()
{
int n,m,x,y;
char s[3];
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<n;i++)
c[i]=get_val();
init();
build(1,0,n);
while(m--)
{
scanf("%s",s);
x=get_val();y=get_val();
if(s[0]=='U')
update(1,x-1,x,y);
else
{
int ans=query(1,x-1,y);
printf("%d\n",ans);
}
}
}
return 0;
}