//注意题意:文件结束......
//数组清零应放在循环里
思路见树状数组求区间最大值
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 300000+5;
int a[N], c[N];//原数组和存放最大值
int n, m;
int lowbit(int x)
{
return x&(-x);
}
void Update(int x)
{
int l;
while(x <= n){
c[x] = a[x];
l = lowbit(x);
for(int i=1; i<l; i <<= 1){
c[x] = max(c[x], c[x-i]);
}
x += lowbit(x);
}
}
void Update(int i, int val)
{
while (i <= n)
{
c[i] = max(c[i], val);
i += lowbit(i);
}
}
int Query(int x, int y)
{
int ans = 0;
while (y >= x){
if(y-lowbit(y) < x){
ans = max(a[y], ans);
y --;
}
while(y-lowbit(y) >= x){
ans = max(c[y], ans);
y -= lowbit(y);
}
}
return ans;
}
int main()
{
while(~scanf("%d%d", &n, &m)){
memset(c, 0, sizeof(c));
for(int i=1; i<=n; i++){
scanf("%d", a+i);
// Update(i);
Update(i, a[i]);
}
getchar();
// for(int i=0; i<m; i++)//不知道为什么 i每次在数据处理了以后都会变为0....
while(m--){
char c[1];
int x, y;
scanf("%s", c);
//getchar();
// cout << c << endl ;
// if(strcmp(c.c_str(), "Q") == 0){
if(!strcmp(c, "Q")){
scanf("%d%d",&x,&y);
printf("%d\n", Query(x, y));
}
else {
scanf("%d%d",&x,&y);
a[x] = y;
//Update(x);
Update(x, a[x]);
}
}
}
return 0;
}