#include<bits/stdc++.h>
#define int long long
#define mid ((l + r) >> 1)
using namespace std;
inline char gc(){
static char buf[10000005],*t1 = buf,*t2 = buf;
return t1 == t2 && (t2 = (t1 = buf) + fread(buf,1,1000000,stdin),t1 == t2) ? EOF : *t1++;
}
int read(){
char c = gc();
int x = 0;
while(c < '0' || c > '9')
c = gc();
while(c >= '0' && c <= '9'){
x = (x << 3) + (x << 1) + c - 48;
c = gc();
}
return x;
}
const int N = 2e5 + 9;
int n,m;
struct OPTION{
int x,y,id;
int pos,opt,val;
} OP[N << 5];
bool cmp_x(OPTION op1,OPTION op2){
return (op1.x ^ op2.x) ? (op1.x < op2.x) : ((op1.y ^ op2.y) ? op1.y < op2.y : ((op1.id ^ op2.id) ? op1.id < op2.id : op1.val > op2.val));
}
bool cmp_y(OPTION op1,OPTION op2){
return ((op1.y ^ op2.y) ? op1.y < op2.y : ((op1.id ^ op2.id) ? op1.id < op2.id : op1.val > op2.val));
}
int opt_cnt,query_cnt;
struct BinaryIndexedTree{
int t[N];
int lowbit(int x){
return x & (-x);
}
int query(int pos){
int ret = 0;
for(int i = pos;i;i -= lowbit(i))
ret += t[i];
return ret;
}
void update(int pos,int v){
for(int i = pos;i <= opt_cnt;i += lowbit(i))
t[i] += v;
}
BinaryIndexedTree(){
memset(t,0,sizeof t);
}
} BIT;
int ans[N];
void CDQ(int l,int r){
if(l >= r)
return;
CDQ(l,mid);CDQ(mid + 1,r);
int i = l,j = mid + 1;
sort(OP + l,OP + mid + 1,cmp_y);
sort(OP + mid + 1,OP + r + 1,cmp_y);
while(j <= r){
while(i <= mid && OP[i].y <= OP[j].y){
if(!OP[i].opt)
BIT.update(OP[i].id,OP[i].val);
i++;
}
if(OP[j].opt)
ans[OP[j].pos] += BIT.query(OP[j].id) * OP[j].opt;
j++;
}
for(int k = l;k < i;k++)
if(!OP[k].opt)
BIT.update(OP[k].id,-OP[k].val);
}
struct option{
int op,l,r,x;
} Tmp[N];
int a[N];
int tmp[N],top;
int last[N],pre[N];
set<int> s[N];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n >> m;
for(int i = 1;i <= n;i++){
cin >> a[i];
tmp[++top] = a[i];
}
for(int i = 1;i <= m;i++){
string op;
int x,y;
cin >> op >> x >> y;
if(op == "Q"){
Tmp[i] = (option){1,x,y,0};
}
else if(op == "R"){
Tmp[i] = (option){2,x,x,y};
tmp[++top] = y;
}
}
sort(tmp + 1,tmp + top + 1);
top = unique(tmp + 1,tmp + top + 1) - tmp - 1;
for(int i = 1;i <= top;i++)
s[i].insert(0);
for(int i = 1;i <= n;i++){
a[i] = lower_bound(tmp + 1,tmp + top + 1,a[i]) - tmp;
pre[i] = last[a[i]];
OP[++opt_cnt] = (OPTION){i,pre[i],1,0,0,1};
last[a[i]] = i;
}
for(int i = 1;i <= m;i++){
if(Tmp[i].op == 1){
query_cnt++;
OP[++opt_cnt] = (OPTION){Tmp[i].l - 1,Tmp[i].l - 1,i,query_cnt,-1,0};
OP[++opt_cnt] = (OPTION){Tmp[i].r,Tmp[i].l - 1,i,query_cnt,1,0};
}
else if(Tmp[i].op == 2){
OP[++opt_cnt] = (OPTION){Tmp[i].l,pre[Tmp[i].l],i,0,0,-1};
Tmp[i].x = lower_bound(tmp + 1,tmp + top + 1,Tmp[i].x) - tmp;
s[a[Tmp[i].l]].erase(Tmp[i].l);
a[Tmp[i].l] = Tmp[i].x;
s[a[Tmp[i].l]].insert(Tmp[i].l);
pre[Tmp[i].l] = *--s[a[Tmp[i].l]].find(Tmp[i].l);
OP[++opt_cnt] = (OPTION){Tmp[i].l,pre[Tmp[i].l],i,0,0,1};
}
}
sort(OP + 1,OP + opt_cnt + 1,cmp_x);
CDQ(1,opt_cnt);
for(int i = 1;i <= query_cnt;i++)
cout << ans[i] << '\n';
return 0;
}