#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100000;
set<int> tree[4 * MAXN];
int lazy[4 * MAXN];
int L, T, O;
void build(int node, int start, int end) {
if (start == end) {
tree[node].insert(1);
lazy[node] = 0;
} else {
int mid = (start + end) / 2;
build(2 * node, start, mid);
build(2 * node + 1, mid + 1, end);
tree[node].insert(1);
lazy[node] = 0;
}
}
void lazy1(int node, int start, int end) {
if (lazy[node] != 0) {
tree[node].clear();
tree[node].insert(lazy[node]);
if (start != end) {
lazy[2 * node] = lazy[node];
lazy[2 * node + 1] = lazy[node];
}
lazy[node] = 0;
}
}
void update(int node, int start, int end, int l, int r, int color) {
lazy1(node, start, end);
if (start > r || end < l) {
return;
}
if (start >= l && end <= r) {
lazy[node] = color;
lazy1(node, start, end);
return;
}
int mid = (start + end) / 2;
update(2 * node, start, mid, l, r, color);
update(2 * node + 1, mid + 1, end, l, r, color);
tree[node].clear();
for (int c : tree[2 * node]) {
tree[node].insert(c);
}
for (int c : tree[2 * node + 1]) {
tree[node].insert(c);
}
}
set<int> query(int node, int start, int end, int l, int r) {
lazy1(node, start, end);
if (start > r || end < l) {
return set<int>();
}
if (start >= l && end <= r) {
return tree[node];
}
int mid = (start + end) / 2;
set<int> lc = query(2 * node, start, mid, l, r);
set<int> rc = query(2 * node + 1, mid + 1, end, l, r);
for (int color : rc) {
lc.insert(color);
}
return lc;
}
int main() {
cin >> L >> T >> O;
build(1, 1, L);
for (int i = 0; i < O; i++) {
char type;
int A, B, C;
cin >> type >> A >> B;
if (A > B)
swap(A, B);
if (type == 'C') {
cin >> C;
update(1, 1, L, A, B, C);
} else if (type == 'P') {
set<int> result = query(1, 1, L, A, B);
cout << result.size() << endl;
}
}
return 0;
}