#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define inf 0x0f0f0f0f
using namespace std;
const int N=200010;
const int M=5010;
struct Tree{
int l,r,max,value;
}tree[N*4];
void Build(int v, int l, int r)
{
tree[v].l=l;
tree[v].r=r;
tree[v].max=tree[v].value=0;
if (l==r)
return;
int mid=(l+r)/2;
if (l<=mid)
{
Build(v*2,l,mid);
}
if (r>mid)
{
Build(v*2+1,mid+1,r);
}
}
void Update(int v , int l, int r, int add)
{
if (l<=tree[v].l && r>=tree[v].r){
tree[v].max=tree[v].value=add;
return;
}
int mid=(tree[v].l+tree[v].r)/2;
if (l<=mid){
Update(v*2,l,r,add);
}
if (r>mid){
Update(v*2+1,l,r,add);
}
tree[v].max=max(tree[v*2].max,tree[v*2+1].max);
}
int Query(int v, int l, int r)
{
int ans1=0,ans2=0;
if (l<=tree[v].l && r>=tree[v].r){
return tree[v].max;
}
int mid=(tree[v].l+tree[v].r)/2;
if (l<=mid){
ans1=Query(v*2,l,r);
}
if (r>mid){
ans2=Query(v*2+1,l,r);
}
return max(ans1,ans2);
}
int main()
{
int n,m,k,l,r;
char c;
while (scanf("%d%d",&n,&m)!=EOF)
{
Build(1,1,n);
for (int i=1;i<=n;i++)
{
scanf("%d",&k);
Update(1,i,i,k);
}
for (int i=1;i<=m;i++)
{
cin >> c >> l >> r;
if (c=='Q')
printf("%d\n",Query(1,l,r));
else
Update(1,l,l,r);
}
}
return 0;
}