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)

use std::io::*;
use std::str::FromStr;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn square_sum(sy: usize, sx: usize, k: usize, c: usize, sums: &Vec<Vec<Vec<usize>>>) -> usize {
    sums[c][sy + k][sx + k] +
    sums[c][sy][sx] -
    sums[c][sy][sx + k] -
    sums[c][sy + k][sx]
}

fn main() {
    let n: usize = read();
    let k: usize = read();
    let mut ps = vec![(0, 0, 0); n];
    for i in 0..n {
        let x: usize = read();
        let y: usize = read();
        let c: String = read();
        let x = x % (2 * k);
        let y = y % (2 * k);
        ps[i] = (x, y, if c == 'W'.to_string() { 0 } else { 1 });
    }
    let mut sums = vec![vec![vec![0 as usize; 3 * k + 1]; 4 * k + 1]; 2];
    for i in 0..n {
        let x = ps[i].0;
        let y = ps[i].1;
        let c = ps[i].2;
        for dy in [0, 2 * k].iter() {
            for dx in [0, 2 * k].iter() {
                let nx = x + dx;
                let ny = y + dy;
                if ny >= 4 * k || nx >= 3 * k { continue; }
                sums[c][ny + 1][nx + 1] += 1;
            }
        }
    }
    for c in 0..2 {
        for y in 0..4 * k {
            for x in 0..3 * k {
                sums[c][y + 1][x + 1] += sums[c][y + 1][x] + sums[c][y][x + 1] - sums[c][y][x];
            }
        }
    }
    let mut ans = 0;
    for offset_y in 0..2*k+1 {
        for offset_x in 0..k+1 {
            let mut sum = 0;
            sum += square_sum(offset_y, offset_x, k, 0, &sums);
            sum += square_sum(k + offset_y, offset_x, k, 1, &sums);
            sum += square_sum(offset_y, k + offset_x, k, 1, &sums);
            sum += square_sum(k + offset_y, k + offset_x, k, 0, &sums);
            ans = std::cmp::max(ans, sum);
        }
    }
    println!("{}", ans);
}