#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
#define endl '\n'
using namespace std;
const int N = 4e5 + 10;
int n, m;
int a[N];
struct node
{
int l, r;
int sum;//这个是在当前区间每个数的或
int maxx;//当前区间的最大值
} tree[N << 2];
inline void pushup(int p)
{
tree[p].maxx = max(tree[p << 1].maxx, tree[p << 1 | 1].maxx);
tree[p].sum = tree[p << 1].sum | tree[p << 1 | 1].sum;//中间的竖就是或
return ;
}
void build(int p, int l, int r)
{
tree[p].l = l, tree[p].r = r;
if (l == r)
{
tree[p].sum = a[l];
tree[p].maxx = a[l];
return ;
}
int mid = (l + r) >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
// pushup(p);
tree[p].maxx = max(tree[p << 1].maxx, tree[p << 1 | 1].maxx);
tree[p].sum = tree[p << 1].sum | tree[p << 1 | 1].sum;//中间的竖就是或
}
void update1(int p, int l, int r, int value)
{
if (tree[p].l > r || tree[p].r < l)
return ;
if (tree[p].l == tree[p].r)
{
tree[p].sum = tree[p].maxx & value;
tree[p].maxx = tree[p].maxx & value;
return ;
}
//这一步就是题解的亮点,所有的数的|所得的数,&其中任何一个数还是等于他自己,
//所以如果value & sum 还是 == sum, 那么value就相当与sum的作用,因为那些1没变
if ((tree[p].sum & value) == tree[p].sum)
return ;
update1(p << 1, l, r, value);
update1(p << 1 | 1, l, r, value);
pushup(p);
}
void update2(int p, int idx, int value)
{
if (tree[p].l > idx || tree[p].r < idx)//不满足区间要求的直接return
return ;
if (tree[p].l == tree[p].r && tree[p].l == idx)
{
tree[p].sum = value;
tree[p].maxx = value;
return ;
}
update2(p << 1, idx, value);
update2(p << 1 | 1, idx, value);
pushup(p);
}
int query(int p, int l, int r)
{
if (tree[p].l > r || tree[p].r < l)//不满足区间要求的直接return,这样剩下的点全在l,r里,所以有下面的l==r直接可以return
return -1;
if (l <= tree[p].l && tree[p].r <= r)
{
return tree[p].maxx;
}
//不断的往下执行,
//-1 和 -1 比较
//1. -1 和 一个tree[p].maxx比较
//2. 一个tree[p].maxx和另一个tree[p].maxx比较
//所以直接取max
return max(query(p << 1, l, r), query(p << 1 | 1, l, r));
}
int main()
{
IOS; cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; ++i)
{
cin >> a[i];
}
build(1, 1, n);
for (int i = 1; i <= m; ++i)
{
string op;
cin >> op;
if (op[0] == 'A')
{
int l, r, v;
cin >> l >> r >> v;
update1(1, l, r, v);
}
else if (op[0] == 'U')
{
int x, v;
cin >> x >> v;
update2(1, x, v);
}
else if (op[0] == 'Q')
{
int l, r;
cin >> l >> r;
int maxx = query(1, l, r);
cout << maxx << endl;
}
}
return 0;
}