#ifndef LOCAL
#pragma optimize(2)
#endif
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using PII = pair<int, int>;
#define x first
#define y second
#define zjj master
const int N = 200020, INF = 0x3f3f3f3f;
int n, m;
template<class INFO, class TAG>
class lazy_segment_tree {
int n;
vector<INFO> tr_node;
vector<TAG> tag;
void push_up(int p) {
tr_node[p] = tr_node[p << 1] + tr_node[p << 1 | 1];
}
void lazy(int p, TAG val, int ges) {
tag[p].lazy(tr_node[p], val, ges);
}
void push_down(int p, int l, int r) {
int mid = l + r >> 1;
int lges = mid - l + 1;
int rges = r - mid;
lazy(p << 1, tag[p], lges);
lazy(p << 1 | 1, tag[p], rges);
tag[p].clear();
}
void build(int p, int l, int r, const vector<INFO>& a) {
if (l == r) {
tr_node[p] = a[l];
return;
}
int mid = l + r >> 1;
build(p << 1, l, mid, a);
build(p << 1 | 1, mid + 1, r, a);
push_up(p);
}
void __add(int p, const int tl, const int tr, int l, int r, TAG val) {
if (tl <= l && tr >= r) {
lazy(p, val, r - l + 1);
return;
}
int mid = l + r >> 1;
push_down(p, l, r);
if (tl <= mid) {
__add(p << 1, tl, tr, l, mid, val);
}
if (tr > mid) {
__add(p << 1 | 1, tl, tr, mid + 1, r, val);
} push_up(p);
}
INFO __query(int p, const int tl, const int tr, int l, int r) {
INFO ans = INFO();
if (tl <= l && tr >= r) {
return tr_node[p];
}
int mid = l + r >> 1;
push_down(p, l, r);
if (tl <= mid) {
ans = ans + __query(p << 1, tl, tr, l, mid);
}
if (tr > mid) {
ans = ans + __query(p << 1 | 1, tl, tr, mid + 1, r);
}
push_up(p);
return ans;
}
public:
explicit lazy_segment_tree(const vector<INFO>& a, int n)
: tr_node(vector<INFO>(n * 4)), tag(vector<TAG>(n * 4)), n(n) {
build(1, 1, n, a);
}
void add(int l, int r, TAG val) {
__add(1, l, r, 1, n, val);
}
INFO query(int l, int r) {
return __query(1, l, r, 1, n);
}
void add(int p, TAG val) {
__add(1, p, p, 1, n, val);
}
INFO find(int i) {
return query(i, i);
}
};
struct info{
unsigned int color_state;
int ans;
info(unsigned int a = (1 << 1), int b = 1) : color_state(a), ans(b) {}
info operator+(const info& b) {
info res;
res.color_state = (color_state | b.color_state);
res.ans = __builtin_popcount(res.color_state);
return res;
}
};
struct tag{
int color_ind;
tag(int a = 1) : color_ind(a) {}
void clear() {
color_ind = 0;
}
void lazy(info& a, const tag& val, int ges) {
if(val.color_ind == 0) return;
color_ind = val.color_ind;
a.color_state = (1 << color_ind);
a.ans = 1;
}
};
void solve()
{
int q;
cin >> n >> m >> q;
lazy_segment_tree<info, tag> tree(vector<info>(n + 1, info(1 << 1, 1)), n);
while (q--) {
char ty;
cin >> ty;
if (ty == 'C') {
int l, r, c; cin >> l >> r >> c;
if (l > r) swap(l, r);
tree.add(l, r, tag(c));
} else {
int l, r; cin >> l >> r;
if (l > r) swap(l, r);
cout << __builtin_popcount(tree.query(l, r).color_state) << '\n';
}
}
}
signed main()
{
#ifdef LOCAL
freopen("in.in", "r", stdin);freopen("out.out", "w", stdout);
#endif
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T = 1;
while (T--) solve();
return 0;
}