#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
int l, r, sum,_max;
}dp[200005*4];
void Creat(int l, int r, int i)//初始化线段树
{
dp[i].l = l;
dp[i].r = r;
dp[i].sum = dp[i]._max = 0;
if (l == r)//当为最小子区间时输入值
{
scanf("%d", &dp[i].sum);
dp[i]._max = dp[i].sum;
return;
}
int mid = (l + r) / 2;//分半
Creat(l, mid, i * 2);
Creat(mid + 1, r, i * 2 + 1);
dp[i]._max = max(dp[i * 2]._max, dp[i * 2 + 1]._max);//第i层的最大值更新
}
void Change(int a, int b, int i)//将第a个位置改成b
{
if (dp[i].l == dp[i].r)
{
dp[i]._max = b;
return;
}
int mid = (dp[i].l + dp[i].r) / 2;
if (a <= mid)
{
Change(a, b, i * 2);
}
else
{
Change(a, b, i * 2 + 1);
}
dp[i]._max = max(dp[i * 2]._max, dp[i * 2 + 1]._max);//修改值
}
int Find(int l, int r, int i)
{
if (l == dp[i].l&&dp[i].r == r)
{
return dp[i]._max;
}
int mid = (dp[i].l + dp[i].r) / 2;
if (r <= mid)
{
return Find(l, r, i * 2);
}
else if (l > mid)
{
return Find(l, r, i * 2 + 1);
}
else
{
return max(Find(l, mid, i * 2), Find(mid + 1, r, i * 2 + 1));
}
}
int main()
{
int n, m;
while (cin >> n >> m)
{
Creat(1, n, 1);
char st[2];
for (int i = 0; i < m; i++)
{
scanf("%s", st);
int a, b;
scanf("%d%d", &a, &b);
if (st[0] == 'Q')
{
cout << Find(a, b, 1) << endl;
}
else
{
Change(a, b, 1);
}
}
}
return 0;
}