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 C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class Contest
{
	const long MOD1 = 1000000007L; // 10^9+7

	public static void Main()
	{
 
 
		int  n, k;
		VT<int,int,string>[] xycl;
		MyIO.ReadMulti(out n, out k);
		MyIO.ReadLines(n, out xycl);
 
		int[][] xywl = new int[k+1][];
		int[][] xybl = new int[k+1][];
		for(int i=0;i<=k;i++){
 			xybl[i] = new int[k+1];
			xywl[i] = new int[k+1];
		}
 		foreach(var e in xycl){
			int mx = e.Item1%(2*k);
			int my = e.Item2%(2*k);

			if(((mx<k)&&(my<k))||((k<=mx)&&(k<=my))) {
				if(e.Item3=="B"){
					xybl[mx%k][my%k]++;
				}else{
					xywl[mx%k][my%k]++;
				}
			}else{
				if(e.Item3=="B"){
					xywl[mx%k][my%k]++;
				}else{
					xybl[mx%k][my%k]++;
				}
			}
		}
 
		int[][] sxywl = new int[k+1][];
		int[][] sxybl = new int[k+1][];
		for(int i=0;i<=k;i++){
 			sxybl[i] = new int[k+1];
			sxywl[i] = new int[k+1];
		}
		for(int i=0;i<=k;i++){
			sxybl[0][i] = 0;
			sxywl[0][i] = 0;
		}
		for(int i=1;i<=k;i++){
			sxybl[i][0] = 0;
			sxywl[i][0] = 0;
			for(int j=1;j<=k;j++){
				sxybl[i][j] = xybl[i-1][j-1]+sxybl[i][j-1]+sxybl[i-1][j]-sxybl[i-1][j-1];
				sxywl[i][j] = xywl[i-1][j-1]+sxywl[i][j-1]+sxywl[i-1][j]-sxywl[i-1][j-1];
			}
		}

		int ans = 0;
		for(int i=0;i<k;i++){
			for(int j=0;j<k;j++){
				int cnt1 = calc(sxybl, 0,0, i,j)+calc(sxybl, i+1,j+1, k-1,k-1)+calc(sxywl, 0,j+1, i,k-1)+calc(sxywl, i+1,0, k-1,j);
				int cnt2 = calc(sxywl, 0,0, i,j)+calc(sxywl, i+1,j+1, k-1,k-1)+calc(sxybl, 0,j+1, i,k-1)+calc(sxybl, i+1,0, k-1,j);

/*
				for(int x=0;x<k;x++){
					for(int y=0;y<k;y++){
						if(((i<=x)&&(j<=y))||((x<i)&&(y<j))){
							cnt1+=xybl[x][y];
							cnt2+=xywl[x][y];
						}else{
							cnt1+=xywl[x][y];
							cnt2+=xybl[x][y];
						}
					}
				}
*/
				if(ans<cnt1)ans = cnt1;
				if(ans<cnt2)ans = cnt2;
			}
		}
 
		MyIO.WriteMulti(ans);
 
 
 
 
		
	}

	private static int calc(int[][] sxyl, int x1, int y1, int x2, int y2){
		return sxyl[x2+1][y2+1]-sxyl[x1][y2+1]-sxyl[x2+1][y1]+sxyl[x1][y1];

	}


}








public struct VT<T, U>
{
	public T Item1; public U Item2;
    public VT(T a, U b) { Item1 = a; Item2 = b; }
}
public struct VT<T, U, V>
{
	public T Item1; public U Item2; public V Item3;
    public VT(T a, U b, V c) { Item1 = a; Item2 = b; Item3 = c; }
}
public struct VT<T, U, V, W>
{
	public T Item1; public U Item2; public V Item3; public W Item4;
    public VT(T a, U b, V c, W d) { Item1 = a; Item2 = b; Item3 = c; Item4 = d; }
}

public class Printer : System.IO.StreamWriter
{
	public override IFormatProvider FormatProvider { get { return System.Globalization.CultureInfo.InvariantCulture; } }
	public Printer(System.IO.Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
	public Printer(System.IO.Stream stream, Encoding encoding) : base(stream, encoding) { }
}
public static class MyIO
{
	private static char[] splitter = new char[] {' '};
	private static bool eq<T, U>() => typeof(T).Equals(typeof(U));
	private static T ct<T, U>(U a) => (T)Convert.ChangeType(a, typeof(T));
	private static T cv<T>(string s) => eq<T, int>()    ? ct<T, int>(int.Parse(s))
	                                  : eq<T, long>()   ? ct<T, long>(long.Parse(s))
	                                  : eq<T, double>() ? ct<T, double>(double.Parse(s, System.Globalization.CultureInfo.InvariantCulture))
	                                  : eq<T, char>()   ? ct<T, char>(s[0])
	                                                    : ct<T, string>(s);				
	public static string[] ReadMulti<T>(out T a) {
		var ar = Console.ReadLine().Split(splitter, StringSplitOptions.RemoveEmptyEntries); 
		a = cv<T>(ar[0]);
		return ar;
	}
	public static string[] ReadMulti<T, U>(out T a, out U b) {
		var ar = ReadMulti<T>(out a); 
        b = cv<U>(ar[1]);
		return ar;
	}
	public static string[] ReadMulti<T, U, V>(out T a, out U b, out V c) {
		var ar = ReadMulti<T, U>(out a, out b); 
        c = cv<V>(ar[2]);
		return ar;
	}
	public static string[] ReadMulti<T, U, V, W>(out T a, out U b, out V c, out W d) {
		var ar = ReadMulti<T, U, V>(out a, out b, out c); 
        d = cv<W>(ar[3]);
		return ar;
	}
	public static string[] ReadMulti<T, U, V, W, X>(out T a, out U b, out V c, out W d, out X e) {
		var ar = ReadMulti<T, U, V, W>(out a, out b, out c, out d); 
        e = cv<X>(ar[4]);
		return ar;
	}
	public static string[] ReadMulti<T, U, V, W, X, Y>(out T a, out U b, out V c, out W d, out X e, out Y f) {
		var ar = ReadMulti<T, U, V, W, X>(out a, out b, out c, out d, out e); 
        f = cv<Y>(ar[5]);
		return ar;
	}
	public static string[] ReadArray<T>(out T[] a) {		
		var ar = Console.ReadLine().Split(splitter, StringSplitOptions.RemoveEmptyEntries);
		a = ar.Select(cv<T>).ToArray();
		return ar;
	}		
	public static string[][] ReadLines<T>(int n, out T[] a) {
		a = new T[n];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) arr[i] = ReadMulti(out a[i]);
		return arr;
	}
	public static string[][] ReadLines<T, U>(int n, out VT<T, U>[] a) {
		a = new VT<T, U>[n];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) {
			T o; U p;
			arr[i] = ReadMulti(out o, out p);
			a[i] = new VT<T, U>(o, p);
		}
		return arr;
	}
	public static string[][] ReadLines<T, U, V>(int n, out VT<T, U, V>[] a) {
		a = new VT<T, U, V>[n];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) {
			T o; U p; V q;
			arr[i] = ReadMulti(out o, out p, out q);
			a[i] = new VT<T, U, V>(o, p, q);
		}
		return arr;
	}
	public static string[][] ReadLines<T, U, V, W>(int n, out VT<T, U, V, W>[] a) {
		a = new VT<T, U, V, W>[n];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) {
			T o; U p; V q; W r;
			arr[i] = ReadMulti(out o, out p, out q, out r);
			a[i] = new VT<T, U, V, W>(o, p, q, r);
		}
		return arr;
	}
	public static string[][] ReadMatrix<T>(int n, out T[][] a) {
		a = new T[n][];
		string[][] arr = new string[n][];
		for(int i=0; i<n; i++) arr[i] = ReadArray(out a[i]);
		return arr;
	}

	private static void wwp(Action act){
		var sw = new Printer(Console.OpenStandardOutput()){AutoFlush = false};
		Console.SetOut(sw);
		act();
		Console.Out.Flush();
		sw.AutoFlush = true;
		Console.SetOut(sw);
	}
	private static string wfm(Type t){
		return t.Equals(typeof(double)) ? "{0:F10}" : "{0}";
	}
	public static void WriteMulti(params object[] a) {
		wwp(()=>{
			for(int i=0;i<a.Length;i++) {
				string fs = wfm(a[i].GetType()) + ((i<a.Length-1) ? " " : Environment.NewLine);
				Console.Write(fs, a[i]);
			}
		});
	}
	public static void WriteArray<T>(T[] a) {
		wwp(()=>{
			string fs = wfm(typeof(T));
			string fs1 = fs + " ";
			string fs2 = fs + Environment.NewLine;
			for(int i=0;i<a.Length;i++) Console.Write( ((i<a.Length-1) ? fs1 : fs2), a[i]);
		});
	}
	public static void WriteLines<T>(T[] a) {
		wwp(()=>{
			string fs = wfm(typeof(T)) + Environment.NewLine;
			foreach(T x in a) Console.Write(fs, x);
		});
	}



}