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)

const MAX: usize = 4001;
fn main() {
    let (n, k): (usize, usize) = readln();
    let mut b = vec![vec![0i32; MAX]; MAX];
    let mut w = vec![vec![0i32; MAX]; MAX];
    for _ in 0..n {
        let (x, y, c): (usize, usize, String) = readln();
        let (bx, by) = (x % (2 * k), y % (2 * k));
        let (ex, ey) = (bx + k, by + k);
        if &c == "B" {
            b[by][bx] += 1;
            b[by][ex] -= 1;
            b[ey][bx] -= 1;
            b[ey][ex] += 1;
        } else {
            w[by][bx] += 1;
            w[by][ex] -= 1;
            w[ey][bx] -= 1;
            w[ey][ex] += 1;
        }
    }
    for y in 0..MAX {
        for x in 1..MAX {
            b[y][x] += b[y][x - 1];
            w[y][x] += w[y][x - 1];
        }
    }
    for y in 1..MAX {
        for x in 0..MAX {
            b[y][x] += b[y - 1][x];
            w[y][x] += w[y - 1][x];
        }
    }
    let mut ans = 0;
    for y in 0..2 * k {
        for x in 0..2 * k {
            let (bx, by) = (x, y);
            let (cx, cy) = ((x + k) % (2 * k), (y + k) % (2 * k));
            let mut s = 0;
            for b1 in &[0, 2 * k] {
                for b2 in &[0, 2 * k] {
                    s += w[by + b1][bx + b2];
                    s += w[cy + b1][cx + b2];
                    s += b[by + b1][cx + b2];
                    s += b[cy + b1][bx + b2];
                }
            }
            ans = max(ans, s);
        }
    }
    println!("{}", ans);
}

// --- template ---
#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused_imports)]
use std::collections::HashSet;

pub trait FromLn {
    fn fromln(s: &str) -> Self;
}
pub fn readln<T: FromLn>() -> T {
    let mut buf = String::new();
    let _ = ::std::io::stdin().read_line(&mut buf).unwrap();
    T::fromln(buf.trim())
}
pub fn readlns<T: FromLn>(n: usize) -> Vec<T> {
    let mut vs = vec![];
    for _ in 0..n {
        vs.push(readln());
    }
    vs
}
macro_rules! fromln_primitives {
    ($($t:ty),*) => { $(
        impl FromLn for $t {
            fn fromln(s: &str) -> $t {
                s.parse().unwrap()
            }
        }
    )* }
}
fromln_primitives!(
    String,
    bool,
    f32,
    f64,
    isize,
    i8,
    i16,
    i32,
    i64,
    usize,
    u8,
    u16,
    u32,
    u64
);
impl<T> FromLn for Vec<T>
where
    T: FromLn,
{
    fn fromln(s: &str) -> Vec<T> {
        s.split_whitespace().map(T::fromln).collect()
    }
}
impl FromLn for Vec<char> {
    fn fromln(s: &str) -> Vec<char> {
        s.chars().collect()
    }
}
macro_rules! fromln_tuple {
    ($($t:ident),*) => {
        impl<$($t),*> FromLn for ($($t),*) where $($t: FromLn),* {
            fn fromln(s: &str) -> ($($t),*) {
                let mut it = s.split_whitespace();
                let t = ($($t::fromln(it.next().unwrap())),*);
                assert_eq!(it.next(), None);
                t
            }
        }
    }
}
fromln_tuple!(A, B);
fromln_tuple!(A, B, C);
fromln_tuple!(A, B, C, D);
fromln_tuple!(A, B, C, D, E);
fromln_tuple!(A, B, C, D, E, F);