#include
#define LL(a) ((a)<<1)
#define RR(a) ((a)<<1|1)
#define N 600001
#define MAX(a,b) (((a) > (b)) ? (a):(b))
//inline int MAX(int a, int b){return ((a > b) ? a:b);}
typedef struct NodeTag {
int st, ed, value;
}Node;
Node tt[N]; // segment tree
int max, num[200001];
int build(int place, int st, int ed)
{
int mid = (st+ed)/2, a, b;
tt[place].st = st;
tt[place].ed = ed;
if(st == ed)
return tt[place].value = num[st];
a = build(LL(place), st, mid);
b = build(RR(place), mid+1, ed);
return tt[place].value = MAX(a,b);
}
void update(int place, int st, int ed, int value)
{
if(tt[place].st == st && tt[place].ed == ed)
{
tt[place].value = value;
// place >>= 1;
// while(place > 0)
// {
// int a = tt[LL(place)].value,
// b = tt[RR(place)].value;
// tt[place].value = MAX(a,b);
// place >>= 1;
// }
}else{
int mid = (tt[place].st + tt[place].ed) / 2;
if(ed <= mid) update(LL(place), st, ed, value);
else if(st >= mid+1) update(RR(place), st, ed, value);
else{}
tt[place].value = MAX(tt[LL(place)].value, tt[RR(place)].value);
}
}
int query(int place, int st, int ed)
{
int mid = (tt[place].st + tt[place].ed)/2;
if(tt[place].st == st && tt[place].ed == ed)
return tt[place].value;
else {
if(ed <= mid) return query(LL(place), st, ed);
else if(st >= mid+1)return query(RR(place), st, ed);
else {
int a = query(LL(place), st, mid),
b = query(RR(place), mid+1, ed);
return MAX(a,b);
}
}
}
int main()
{
int n, m, i, a, b;
char op[3];
while(scanf("%d", &n) != EOF)
{
scanf("%d", &m);
for(i = 1; i <= n; ++i)scanf("%d", num+i);
build(1, 1, n);
while(m--){
scanf("%s%d%d", op, &a, &b);
switch (op[0]) {
case 'Q':
printf("%d\n", query(1,a,b));
break;
case 'U':
update(1, a, a, b);
break;
default:
break;
}
}
}
}