#include <stdio.h>
#include <iostream>
#include <cstdio>
#include <algorithm> 
#include <stdio.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <list>
#include <utility>
#include <set>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <bitset>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <random>

using namespace std;

static const double EPS = 1e-9;
template<class T> bool INRANGE(T x, T a, T b) { return a <= x&&x <= b; }
template<class T> void amin(T &a, T v) { if (a > v) a = v; }
template<class T> void amax(T &a, T v) { if (a < v) a = v; }
int ROUND(double x) { return (int)(x + 0.5); }
bool ISINT(double x) { return fabs(ROUND(x) - x) <= EPS; }
bool ISEQUAL(double x, double y) { return fabs(x - y) <= EPS*max(1.0, max(fabs(x), fabs(y))); }
double SQSUM(double x, double y) { return x*x + y*y; }
#define PI  (acos(-1))
#define ARRAY_NUM(a) (sizeof(a)/sizeof(a[0])) 
#define NG (-1)
#define BIG ((int)1e9+10)
#define BIGLL ((ll)4e18)
#define SZ(a) ((int)(a).size())
#define SQ(a) ((a)*(a))
typedef unsigned long long ull;
typedef long long ll;


#if 1

inline ll getSumArea(int y, int x, int h, int w, const vector < vector <ll> >& sum_board)
{
	return sum_board[y + h][x + w] - sum_board[y + h][x] - sum_board[y][x + w] + sum_board[y][x];
}


template <class T>
vector < vector <ll> > makeSumArea(const vector <T>& board)
{
	const int H = SZ(board);
	const int W = SZ(board[0]);

	vector < vector <ll> > ret(H + 1, vector <ll>(W + 1, 0));
	for (int y = 0; y < H; y++)
	{
		for (int x = 0; x < W; x++)
		{
			ret[y + 1][x + 1] = ret[y + 1][x] + board[y][x]; // 注：vector <string>のときは-'0'とかつくでしょう。
		}
	}

	for (int x = 0; x <= W; x++)
	{
		for (int y = 0; y < H; y++)
		{
			ret[y + 1][x] += ret[y][x];
		}
	}

	return ret;
}

int main()
{
	int N, K;

	scanf("%d %d", &N, &K);

	vector < vector < int > > match(K, vector <int>(K, 0));
	vector < vector < int > > unmatch(K, vector <int>(K, 0));


	for (int i = 0; i < N; ++i)
	{
		int x, y;
		char c;
		scanf("%d %d %c", &x, &y, &c);

		int grid = ((x / K) + (y / K));
		if (grid % 2 == 0 && c == 'W' || grid % 2 == 1 && c == 'B')
		{
			match[y%K][x%K]++;
		}
		else
		{
			unmatch[y%K][x%K]++;

		}
	}


	const vector <vector <ll> > sumMatch = makeSumArea(match);
	const vector <vector <ll> > sumUnmatch = makeSumArea(unmatch);

	const ll defPoint = getSumArea(0, 0, K, K, sumMatch);
	// BEGIN CUT HERE
//	cerr << " defPoint=" << defPoint << endl;
	// END CUT HERE


	ll best = defPoint;

	for (int y = 0; y <= K; ++y)
	{
		for (int x = 0; x <= K; ++x)
		{
			amax(best, defPoint - getSumArea(0, 0, y, x, sumMatch)
				                + getSumArea(0, 0, y, x, sumUnmatch)
							    - getSumArea(y, x, K - y, K - x, sumMatch)
			                    + getSumArea(y, x, K - y, K - x, sumUnmatch));

			amax(best, defPoint - getSumArea(y, 0, K-y, x, sumMatch)
				                + getSumArea(y, 0, K-y, x, sumUnmatch)
                                - getSumArea(0, x, y, K-x, sumMatch)
				                + getSumArea(0, x, y, K - x, sumUnmatch));
				                

		}
	}

	cout << best << endl;
}


#else


bool check(int dt, int dx, int dy)
{
	int dist = abs(dx) + abs(dy);

	return (dt >= dist && (dt - dist) % 2 == 0);
}

int main()
{
	int N;
	scanf("%d", &N);

	vector <int> t, x, y;
	t.push_back(0);
	x.push_back(0);
	y.push_back(0);

	for (int i = 0; i < N; ++i)
	{
		int a, b, c;
		scanf("%d %d %d", &a, &b, &c);

		t.push_back(a);
		x.push_back(b);
		y.push_back(c);
	}

	bool ok = true;
	for (int i = 0; i < N; ++i)
	{
		if (!check(t[i + 1] - t[i], x[i + 1] - x[i], y[i + 1] - y[i]))
		{
			ok = false;
			break;
		}
	}

	if (ok)
	{
		printf("Yes\n");
	}
	else
	{
		printf("No\n");
	}




	return 0;
}

#endif


Measured memory_bytes: 23808