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.Linq;
    using System.Collections.Generic;
    using System.Text.RegularExpressions;
    using System.Text;
    using System.Net;

     
    public class Program
    {

        public void Proc() {
            int[] inpt = Reader.ReadLine().Split(' ').Select(a=>int.Parse(a)).ToArray();
            int kibouCount = inpt[0];
            this.CheckSize = inpt[1];
            int[,] mapSource = new int[CheckSize*2, CheckSize*2];
            for(int i=0; i<kibouCount; i++) {
                string[] tmp = Reader.ReadLine().Split(' ');
                long x = long.Parse(tmp[0]);
                long y = long.Parse(tmp[1]);
                if(tmp[2][0]=='W') {
                    x+=CheckSize;
                }
                int xIdx = (int)x%(CheckSize*2);
                int yIdx = (int)y%(CheckSize*2);
                mapSource[xIdx, yIdx]++;
            }
            this.Map = new int[CheckSize*2,CheckSize*2];
            for(int i=0; i<this.Map.GetLength(0); i++) {
                for(int j=0; j<this.Map.GetLength(0); j++) {
                    int cnt = mapSource[i,j];
                    if(i>0) {
                        cnt+=this.Map[i-1, j];
                    }
                    if(j>0) {
                        cnt+=this.Map[i, j-1];
                    }
                    if(i>0&&j>0){
                        cnt-=this.Map[i-1, j-1];
                    }
                    this.Map[i,j]=cnt;
                }
            }
            int ans = 0;
            for(int i=0; i<this.Map.GetLength(0); i++) {
                for(int j=0; j<this.Map.GetLength(0);j++) {
                    ans = Math.Max(ans, GetAns(i,j, true));
                }
            }
            Console.WriteLine(ans);
        }

        private int GetAns(int x, int y, bool flag) {
            int xBottom = Math.Min(x+CheckSize-1, this.Map.GetLength(0)-1);
            int yBottom = Math.Min(y+CheckSize-1, this.Map.GetLength(0)-1);
            int ans = GetCount(x, y, xBottom, yBottom);
            if(x+CheckSize>this.Map.GetLength(0)) {
                ans+=GetCount(0, y, (x+CheckSize-this.Map.GetLength(0)-1), yBottom);
            }
            if(y+CheckSize>this.Map.GetLength(0)) {
                ans+=GetCount(x, 0, xBottom, (y+CheckSize-this.Map.GetLength(0)-1));
            }
            if(x+CheckSize>this.Map.GetLength(0)&&y+CheckSize>this.Map.GetLength(0)) {
                ans+=GetCount(0, 0, (x+CheckSize-this.Map.GetLength(0)-1), (y+CheckSize-this.Map.GetLength(0)-1));
            }
            int x2 = (x+CheckSize)%(CheckSize*2);
            int y2 = (y+CheckSize)%(CheckSize*2);
            if(flag) {
                ans+=GetAns(x2, y2, false);
            }
            return ans;
        }

        private int GetCount(int x1, int y1, int x2, int y2) {
            int ans = this.Map[x2, y2];
            if(x1>0) {
                ans-=this.Map[x1-1, y2];
            }
            if(y1>0) {
                ans-=this.Map[x2, y1-1];
            }
            if(x1>0&&y1>0) {
                ans+=this.Map[x1-1, y1-1];
            }
            return ans;
        }

        private int[,] Map;

        private int CheckSize;




        public class Reader {
            public static bool IsDebug = false;
            private static System.IO.StringReader SReader;
            private static string InitText = @"




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






";
            public static string ReadLine() {
                if(IsDebug) {
                    if(SReader == null) {
                        SReader = new System.IO.StringReader(InitText.Trim());
                    }
                    return SReader.ReadLine();
                } else {
                    return Console.ReadLine();
                }
            }
        }
        public static void Main(string[] args)
        {
            #if DEBUG
            Reader.IsDebug = true;
            #endif
            Program prg = new Program();
            prg.Proc();
        }
    }