#include <iostream>
#include <sstream>
#include <cmath>
#include <algorithm>
#include <utility>
#include <functional>
#include <iomanip>
#include <typeinfo>
#include <iterator>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <tuple>
#include <map>
#include <set>
#include <numeric>
using namespace std;

#define all(container) container.begin(), container.end()
#define sortall(container) (sort(container.begin(), container.end()))
#define yn(cond) ((cond) ? (cout << "Yes" << endl) : (cout << "No" << endl))
#define YN(cond) ((cond) ? (cout << "YES" << endl) : (cout << "NO" << endl))
#define LLONG_MAX numeric_limits<long long>::max()
#define INT_MAX numeric_limits<int>::max()

typedef long long       ll;
typedef vector<int>     vi;
typedef vector<ll>      vll;
typedef vector<double>  vd;
typedef vector<bool>    vb;
typedef vector<string>  vs;
typedef vector<char>    vc;
typedef pair<int, int>  pii;
typedef pair<ll, ll>    pll;
typedef vector<pii>     vpii;
typedef vector<pll>     vpll;
typedef vector<vll>		vvll;
typedef vector<vi>		vvi;
typedef vector<vb>		vvb;
typedef vector<vs>		vvs;
typedef vector<vc>		vvc;

typedef struct edge_ {
	ll to;
	ll cost;
} edge;

typedef struct point_ {
	ll x, y;
	point_(ll x = 0, ll y = 0) : x(x), y(y) {}
} point;

template <typename T>
class mat2D {
private:
	vector<vector<T>> data;
public:
	mat2D(int rows, int cols) : data(vector<vector<T>>(rows, vector<T>(cols))) {}
	T operator () (int row, int col) { return data[row][col]; }

	friend istream& operator >> (istream& is, mat2D<T>& m) { return is >> m.data; }
	friend ostream& operator << (ostream& os, const mat2D<T>& m) {
		for (const vector<T>& row : m.data) os << row << endl;
		return os;
	}
};

constexpr double	PI = 3.14159265358979323846;
constexpr ll		INF = 1 << 15;
constexpr ll		MOD = (ll)1e9 + 7;
constexpr double	EPS = 1e-7;
constexpr int		dy4[4] = { 0, 1, 0, -1 };
constexpr int		dx4[4] = { 1, 0, -1, 0 };
constexpr int		dy8[8] = { 0, 1, 1, 1, 0, -1, -1, -1 };
constexpr int		dx8[8] = { 1, 1, 0, -1, -1, -1, 0, 1 };

template<typename T>
istream& operator >> (istream& is, vector<T>& vec) {
	for (T& x : vec) is >> x;
	return is;
}

template<typename T>
ostream& operator << (ostream& os, const vector<T>& vec) {
	for (const T& x : vec) os << x << " ";
	return os;
}

template<typename S, typename T>
istream& operator >> (istream& is, pair<S, T>& p) {
	is >> p.first >> p.second;
	return is;
}

istream& operator >> (istream& is, point& p) {
	is >> p.x >> p.y;
	return is;
}

template<typename S, typename T>
ostream& operator << (ostream& os, const pair<S, T>& p) {
	os << "{" << p.first << " " << p.second << "}";
	return os;
}

ostream& operator << (ostream& os, const point& p) {
	os << "(" << p.x << " " << p.y << ")";
	return os;
}

/******************************************************************************/
/**********************         Don't make WA !!         **********************/
/******************************************************************************/

template <typename T>
class CumulativeSum {
private:
	int n;
	vector<vector<T>> data;

public:
	CumulativeSum(vector<vector<T>>& init) : n(init.size()) {
		data = vector<vector<T>>(n + 1, vector<T>(n + 1, 0));
		for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)
				data[i + 1][j + 1] += init[i][j] + data[i + 1][j] + data[i][j + 1] - data[i][j];
	}

	T get(int i, int j, int h, int w) {
		if (i + h >= n + 1 || j + w >= n + 1) {
			cerr << "Cumulatice Sum range error." << endl;
			exit(EXIT_FAILURE);
		}
		//if (h == 0 || w == 0) return 0;
		return data[i + h][j + w] - data[i][j + w] - data[i + h][j] + data[i][j];
	}
};


int main()
{
	int N, K;
	cin >> N >> K;
	vector<point> p(N);
	vc c(N);
	for (int i = 0; i < N; i++)
		cin >> p[i].x >> p[i].y >> c[i];

	vvi white(4 * K, vi(4 * K, 0));
	vvi black(4 * K, vi(4 * K, 0));
	for (int i = 0; i < N; i++) {
		p[i].x %= 2 * K;
		p[i].y %= 2 * K;
		if (c[i] == 'W') {
			white[p[i].y][p[i].x]++;
			white[p[i].y + 2 * K][p[i].x]++;
			white[p[i].y][p[i].x + 2 * K]++;
			white[p[i].y + 2 * K][p[i].x + 2 * K]++;
		}
		else if (c[i] == 'B') {
			black[p[i].y][p[i].x]++;
			black[p[i].y + 2 * K][p[i].x]++;
			black[p[i].y][p[i].x + 2 * K]++;
			black[p[i].y + 2 * K][p[i].x + 2 * K]++;
		}
	}

	CumulativeSum<int> Wsum(white), Bsum(black);

	int ans = 0;
	for (int y = 0; y < 2 * K; y++) {
		for (int x = 0; x < 2 * K; x++) {
			int black_meet = Bsum.get(y, x, K, K) + Bsum.get(y + K, x + K, K, K);
			int white_meet = Wsum.get(y, x + K, K, K) + Wsum.get(y + K, x, K, K);
			ans = max(ans, black_meet + white_meet);
		}
	}

	cout << ans << endl;

	return 0;
}

Measured memory_bytes: 252544