Problem:
Score : 500 points

Problem Statement

AtCoDeer is thinking of painting an infinite two-dimensional grid in a checked pattern of side K.
Here, a checked pattern of side K is a pattern where each square is painted black or white so that each connected component of each color is a K × K square.
Below is an example of a checked pattern of side 3:

AtCoDeer has N desires.
The i-th desire is represented by x_i, y_i and c_i.
If c_i is B, it means that he wants to paint the square (x_i,y_i) black; if c_i is W, he wants to paint the square (x_i,y_i) white.
At most how many desires can he satisfy at the same time?

Constraints

1 ≤ N ≤ 10^5

1 ≤ K ≤ 1000

0 ≤ x_i ≤ 10^9

0 ≤ y_i ≤ 10^9

If i ≠ j, then (x_i,y_i) ≠ (x_j,y_j).

c_i is B or W.

N, K, x_i and y_i are integers.

Input

Input is given from Standard Input in the following format:

N K
x_1 y_1 c_1
x_2 y_2 c_2
:
x_N y_N c_N

Output

Print the maximum number of desires that can be satisfied at the same time.

Sample Input 1

4 3
0 1 W
1 2 W
5 3 B
5 4 B

Sample Output 1

4

He can satisfy all his desires by painting as shown in the example above.

Sample Input 2

2 1000
0 0 B
0 1 W

Sample Output 2

2

Sample Input 3

6 2
1 2 B
2 1 W
2 2 B
1 0 B
0 6 W
4 5 W

Sample Output 3

4

Solution in Rust (1.15.1) (judge verdict: Accepted)

#![allow(unused_imports)]
use std::io::{ self, Write };
use std::str::FromStr;
use std::cmp::{ min, max };
use std::collections::{ BinaryHeap, VecDeque };

#[allow(unused_macros)]
macro_rules! trace {
    ($var:expr) => {
        let _ = writeln!(&mut std::io::stderr(), ">>> {} = {:?}", stringify!($var), $var);
    };
    ($($args:expr),*) => { trace!(($($args),*)) }
}

#[allow(unused_macros)]
macro_rules! put {
    ($var:expr) => {
        let _ = writeln!(&mut std::io::stdout(), "{}", $var);
    };
    ($var:expr, $($args:expr),*) => {
        let _ = write!(&mut std::io::stdout(), "{} ", $var);
        put!($($args),*);
    };
}

fn sum(i0: usize, j0: usize, i1: usize, j1: usize, ac: &Vec<Vec<usize>>) -> usize {
    if i0 == 0 && j0 == 0 {
        ac[i1][j1]
    } else if i0 == 0 {
        ac[i1][j1] - ac[i1][j0-1]
    } else if j0 == 0 {
        ac[i1][j1] - ac[i0-1][j1]
    } else {
        ac[i1][j1] + ac[i0-1][j0-1] - ac[i0-1][j1] - ac[i1][j0-1]
    }
}

fn main() {
    let mut sc = Scanner::new();
    let n: usize = sc.cin();
    let k: usize = sc.cin();
    let k2 = 2 * k;
    let k3 = 3 * k;

    let mut bs = vec![vec![0; k3]; k3];

    for _ in 0..n {
        let mut x: usize = sc.cin();
        let mut y: usize = sc.cin();
        let c: char = sc.cin::<String>().chars().next().unwrap();
        if c == 'W' {
            x = (x + k) % k2;
            y = y % k2;
        } else {
            x %= k2;
            y %= k2;
        }
        bs[x][y] += 1;
        if y+k2 < k3 { bs[x][y+k2] += 1; }
        if x+k2 < k3 { bs[x+k2][y] += 1; }
        if y+k2 < k3 && x+k2 < k3 { bs[x+k2][y+k2] += 1; }
    }
    // for i in 0..k3 { trace!(bs[i]); }
    // put!("===");

    for i in 0..k3 {
        for j in 1..k3 {
            bs[i][j] += bs[i][j-1];
        }
    }
    for j in 0..k3 {
        for i in 1..k3 {
            bs[i][j] += bs[i-1][j];
        }
    }
    // for i in 0..k3 { trace!(bs[i]); }
    // put!("===");

    let mut mx = 0;
    let mut mn = n;
    for i in 0..k {
        for j in 0..k {
            let count = sum(i+0, j+0, i+k-1, j+k-1, &bs)
                      + sum(i+k, j+k, i+k2-1, j+k2-1, &bs);
            mx = max(mx, count);
            mn = min(mn, count);
        }
    }
    trace!(mx, mn);
    put!(max(mx, n-mn));
}

#[allow(dead_code)]
struct Scanner { stdin: io::Stdin, buffer: VecDeque<String>, }
#[allow(dead_code)]
impl Scanner {
    fn new() -> Scanner { Scanner { stdin: io::stdin(), buffer: VecDeque::new() } }
    fn reserve(&mut self) {
        while self.buffer.len() == 0 {
            let mut line = String::new();
            let _ = self.stdin.read_line(&mut line);
            for w in line.split_whitespace() {
                self.buffer.push_back(String::from(w));
            }
        }
    }
    fn cin<T: FromStr>(&mut self) -> T {
        self.reserve();
        match self.buffer.pop_front().unwrap().parse::<T>() {
            Ok(a) => a,
            Err(_) => panic!("parse err")
        }
    }
}