inlineintread(){ int x = 0; int f = 1; char ch = getchar(); while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();} while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();} return x * f; }
constint maxn = 140000;
int n, m, l, r, t, len, cntq, cntr, Ans; int a[maxn], cnt[1000010], ans[maxn], block[maxn];
structQuery { int l, r, t, id; }q[maxn]; boolcmp(Query a, Query b){ if (block[a.l] != block[b.l]) return block[a.l] < block[b.l]; if (block[a.r] != block[b.r]) return block[a.r] < block[b.r]; return a.t < b.t; }
structChange { int pos, color; }c[maxn];
voidadd(int x){ if (cnt[a[x]] == 0) Ans++; cnt[a[x]]++; } voiddel(int x){ if (cnt[a[x]] == 1) Ans--; cnt[a[x]]--; } voidchg(int t){ if (l <= c[t].pos && c[t].pos <= r) { del(c[t].pos); if (cnt[c[t].color] == 0) Ans++; cnt[c[t].color]++; } swap(a[c[t].pos], c[t].color); }
intmain(){ n = read(); m = read(); len = pow(n, 2.0 / 3.0); for (int i = 1; i <= n; ++i) { a[i] = read(); block[i] = (i - 1) / len + 1; } for (int i = 1; i <= m; ++i) { char opt[10]; scanf("%s", opt); if (opt[0] == 'Q') { q[++cntq].l = read(); q[cntq].r = read(); q[cntq].id = cntq; q[cntq].t = cntr; } else { c[++cntr].pos = read(); c[cntr].color = read(); } } sort(q + 1, q + 1 + cntq, cmp); l = 1; for (int i = 1; i <= cntq; ++i) { while (l < q[i].l) del(l++); while (r > q[i].r) del(r--); while (l > q[i].l) add(--l); while (r < q[i].r) add(++r); while (t < q[i].t) chg(++t); while (t > q[i].t) chg(t--); ans[q[i].id] = Ans; } for (int i = 1; i <= cntq; ++i) { printf("%d\n", ans[i]); } return0; }