use std::io;
use std::collections::{HashSet, HashMap};
use rand::*;
fn main() {
let mut input = String::new();
io::stdin().read_line(&mut input).expect("Failed to read input");
let startdata: Vec<usize> = input.split_ascii_whitespace().map(|e| e.parse::<usize>().unwrap()).collect();
let mut instructions: Vec<(usize, usize, bool)> = vec!();
// Kerää ohjeet vektoriin
for instructionindex in 0..startdata[3] {
let mut stepinput = String::new();
io::stdin().read_line(&mut stepinput).expect("Failed to read input");
let instruction = parse_input(&stepinput);
instructions.push(instruction);
/*let op = random_bool(0.5);
let index = random_range(0..startdata[1]);
let color = random_range(0..startdata[2]);
let instruction = (index, color, op);
instructions.push(instruction);*/
}
instructions.reverse();
dedup(&mut instructions);
instructions.reverse();
if startdata[2] == 1 {
let mut rowsfilled: usize = 0;
let mut colsfilled: usize = 0;
let mut color: usize = 0;
for instruction in instructions {
if instruction.2 {
rowsfilled += 1;
color += startdata[1];
color -= colsfilled;
} else {
colsfilled += 1;
color += startdata[0];
color -= rowsfilled;
}
}
println!("{}", color);
} else {
let mut rowhash: HashMap<usize, usize> = HashMap::new();
let mut colhash: HashMap<usize, usize> = HashMap::new();
let mut colors: HashMap<usize, usize> = HashMap::new();
for instruction in instructions {
//println!("Running: {} {} {}", instruction.0, instruction.1, instruction.2);
let mut found_index = false;
if instruction.2 {
rowhash.entry(instruction.1).and_modify(|val| *val += 1).or_insert(1);
colors.entry(instruction.1).and_modify(|val| *val += startdata[1]).or_insert(startdata[1]);
for col in colhash {
colors.entry(col.0).and_modify(|val| *val -= col.1);
}
} else {
colhash.entry(instruction.1).and_modify(|val| *val += 1).or_insert(1);
colors.entry(instruction.1).and_modify(|val| *val += startdata[1]).or_insert(startdata[0]);
for row in rowhash {
colors.entry(row.0).and_modify(|val| *val -= row.1);
}
}
}
for key in 0..startdata[2] {
match colors.get(&key) {
Some(s) => {println!("{}", s);}
None => {println!("0");}
}
}
}
}
pub fn parse_input(input: &String) -> (usize, usize, bool) {
let datavector: Vec<&str> = input.split_ascii_whitespace().collect();
let command = match datavector[0] {
"R" => true,
"C" => false,
_ => false,
};
let index = datavector[1].parse::<usize>().unwrap();
let color = datavector[2].parse::<usize>().unwrap();
return (index-1, color-1, command);
}
fn dedup(v: &mut Vec<(usize, usize, bool)>) {
let mut set = HashSet::new();
v.retain(|x| set.insert((x.0, x.2)));
}