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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)


#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>
#include<numeric>
#include<cstring>
#include<cstdio>
#include<functional>

#define REP(i, n) for(int i = 0;i < n;i++)
#define REPR(i, n) for(int i = n;i >= 0;i--)
#define FOR(i, m, n) for(int i = m;i < n;i++)
#define FORR(i, m, n) for(int i = m;i >= n;i--)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define REVERSE(v,n) reverse(v,v+n);
#define VREVERSE(v) reverse(v.begin(), v.end());
#define ll long long
#define pb(a) push_back(a)
#define INF 9999999999
#define m0(x) memset(x,0,sizeof(x))
#define fill(x,y) memset(x,y,sizeof(x))
#define print(x) cout<<x<<endl;
#define pe(x) cout<<x<<" ";
#define lb(v,n) lower_bound(v.begin(), v.end(), n);
#define int long long


using namespace std;


int dy[4] = { 0,0,1,-1 };
int dx[4] = { 1,-1,0,0 };
int dxx[9] = {0, 0,0,1,1,1,-1,-1,-1 };
int dyy[9] = {0, 1,-1,0,1,-1,0,1,-1 };




ll gcd(ll x, ll y) {
	ll m = max(x, y), n = min(x, y);
	if (m%n == 0)return n;
	else return gcd(m%n, n);
}
ll lcm(ll x, ll y) {
	return x / gcd(x, y)*y;
}

ll myPow(ll x, ll n, ll m) {
	if (n == 0)
		return 1;
	if (n % 2 == 0)
		return myPow(x * x % m, n / 2, m);
	else
		return x * myPow(x, n - 1, m) % m;
}

ll pow2(ll a, ll n) {//aのn乗を計算します。
	ll x = 1;
	while (n > 0) {//全てのbitが捨てられるまで。
		if (n & 1) {//1番右のbitが1のとき。
			x = x * a;
		}
		a = a * a;
		n >>= 1;//bit全体を右に1つシフトして一番右を捨てる。
	}
	return x;
}

long long nCr(int n, int r) {
	if (r > n / 2) r = n - r; // because C(n, r) == C(n, n - r)
	long long ans = 1;
	int i;

	for (i = 1; i <= r; i++) {
		ans *= n - r + i;
		ans /= i;
	}

	return ans;
}

const int MAX = 510000;
const int MOD = 1000000007;

long long fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
	fac[0] = fac[1] = 1;
	finv[0] = finv[1] = 1;
	inv[1] = 1;
	for (int i = 2; i < MAX; i++) {
		fac[i] = fac[i - 1] * i % MOD;
		inv[i] = MOD - inv[MOD%i] * (MOD / i) % MOD;
		finv[i] = finv[i - 1] * inv[i] % MOD;
	}
}

// 二項係数計算
long long COM(int n, int k) {
	if (n < k) return 0;
	if (n < 0 || k < 0) return 0;
	return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

bool arr[100000100];
vector<ll>sosuu;
void Eratosthenes() {
	ll N = 10000010;
	int c = 0;
	for (int i = 0; i < N; i++) {
		arr[i] = 1;
	}
	for (ll i = 2; i < sqrt(N); i++) {
		if (arr[i]) {
			for (ll j = 0; i * (j + 2) < N; j++) {
				arr[i *(j + 2)] = 0;
			}
		}
	}

	for (ll i = 2; i < N; i++) {
		if (arr[i]) {
			sosuu.pb(i);
			//cout << sosuu[c] << " ";
			c++;
		}
	}
	//cout << endl;
	//cout << c << endl;
}

ll stoL(string s) {
	ll n = s.length();
	ll ans = 0;
	for (int i = 0; i < n; i++) {
		ans += pow2(10, n - i - 1)*(ll)(s[i] - '0');
	}
	return ans;
}





int imos[5010][5010];
ll getres(int x, int y, int K) {
	ll res = 0;
	res += imos[x][y] - imos[x - K][y] - imos[x][y - K] + imos[x - K][y - K];
	x += K, y += K;
	res += imos[x][y] - imos[x - K][y] - imos[x][y - K] + imos[x - K][y - K];
	return res;
}
signed main() {
	int N, K; cin >> N >> K;
	REP(i, 4010) {
		REP(j, 4010)imos[i][j] = 0;
	}
	REP(i, N) {
		int x, y;
		char c;
		cin >> x >> y >> c;
		if (c == 'B') {
			int nx = x % (2 * K), ny = y % (2 * K);
			nx++; ny++;
			imos[nx][ny]++;
			imos[nx + 2 * K][ny]++;
			imos[nx][ny + 2 * K]++;
			imos[nx + 2 * K][ny + 2 * K]++;
		}
		else {
			int nx = (x + K) % (2 * K), ny = y % (2 * K);
			nx++; ny++;
			imos[nx][ny]++;
			imos[nx + 2 * K][ny]++;
			imos[nx][ny + 2 * K]++;
			imos[nx + 2 * K][ny + 2 * K]++;
		}
	}
	/*REP(i, 4 * K + 1) {
		REP(j, 4 * K + 1) {
			pe(imos[i][j]);
		}
		cout << endl;
	}
	cout << endl;*/
	FOR(i, 1, 4 * K + 1) {
		FOR(j, 1, 4 * K + 1) {
			imos[i][j] += imos[i - 1][j] + imos[i][j - 1] - imos[i - 1][j - 1];
		}
	}
	ll ans = 0;
	FOR(i, K, 2 * K) {
		FOR(j, K, 2 * K) {
			ll res = getres(i, j, K);
			ans = max(ans, res);
		}
	}
	/*
	REP(i, 4 * K + 1) {
		REP(j, 4 * K + 1) {
			pe(imos[i][j]);
		}
		cout << endl;
	}
	*/
	print(ans);
}