/*
* C++11 code template for contests.
* @author: Andrei Kalendarov
* @e-mail: andreykalendarov@gmail.com
*/

//#define ANDREIKKAA_ALLOCATOR
//#define ANDREIKKAA_INTERACTIVE
const int _ML = 220;
const char _inpf[] =
#if defined(ANDREIKKAA)
        "input.txt"
#else
""
#endif
;
const char _outf[] =
#if defined(ANDREIKKAA)
        ""
#else
""
#endif
;

#if !defined(ANDREIKKAA)
#pragma GCC optimize ("O3")
#endif
#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
#define rand rd
#define random_shuffle abcdefghijklmnopqrstuvwxyz
#if !defined(ANDREIKKAA_INTERACTIVE) && !defined(ANDREIKKAA)
#define endl '\n'
#endif
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
typedef long long ll;
typedef double ld;
const ld PI = 3.14159265358979323846;
mt19937 rd(228);

#if defined(ANDREIKKAA_ALLOCATOR)
char _mem[_ML * 1024 * 1024];
size_t _ptr = 0;
inline void* operator new (size_t _x) { _ptr += _x; return _mem + _ptr - _x; }
inline void operator delete (void*) { }
#endif

template<typename T, typename U> inline ostream &operator<< (ostream &_out, const pair<T, U> &_p) { _out << _p.first << ' ' << _p.second; return _out; }
template<typename T, typename U> inline istream &operator>> (istream &_in, pair<T, U> &_p) { _in >> _p.first >> _p.second; return _in; }
template<typename T> inline ostream &operator<< (ostream &_out, const vector<T> &_v) { if (_v.empty()) { return _out; } _out << _v.front(); for (auto _it = ++_v.begin(); _it != _v.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline istream &operator>> (istream &_in, vector<T> &_v) { for (auto &_i : _v) { _in >> _i; } return _in; }
template<typename T> inline ostream &operator<< (ostream &_out, const set<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline ostream &operator<< (ostream &_out, const multiset<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline ostream &operator<< (ostream &_out, const unordered_set<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline ostream &operator<< (ostream &_out, const unordered_multiset<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T, typename U> inline ostream &operator<< (ostream &_out, const map<T, U> &_m) { if (_m.empty()) { return _out; } _out << '(' << _m.begin()->first << ": " << _m.begin()->second << ')'; for (auto _it = ++_m.begin(); _it != _m.end(); ++_it) { _out << ", (" << _it->first << ": " << _it->second << ')'; } return _out; }
template<typename T, typename U> inline ostream &operator<< (ostream &_out, const unordered_map<T, U> &_m) { if (_m.empty()) { return _out; } _out << '(' << _m.begin()->first << ": " << _m.begin()->second << ')'; for (auto _it = ++_m.begin(); _it != _m.end(); ++_it) { _out << ", (" << _it->first << ": " << _it->second << ')'; } return _out; }

/* ________ CODE ________ */

const int N = 1002;
int ps[2][N][N];

inline void mainFunction()
{
    int n, k;
    cin >> n >> k;

    vector<pair<pair<int, int>, bool>> v;
    for(int i = 0; i < n; ++i)
    {
        int x, y;
        char c;
        cin >> x >> y >> c;

        bool clr = (c == 'W');

        int cnt = (x / k) + (y / k);
        x %= k;
        y %= k;

        if(cnt & 1)
        {
            clr ^= 1;
        }

        ++ps[clr][x][y];
    }

    for(int l = 0; l < 2; ++l)
    {
        for(int i = 0; i <= k + 1; ++i)
        {
            for(int j = 0; j <= k + 1; ++j)
            {
                if(i)
                {
                    ps[l][i][j] += ps[l][i - 1][j];
                }
                if(j)
                {
                    ps[l][i][j] += ps[l][i][j - 1];
                }
                if(i && j)
                {
                    ps[l][i][j] -= ps[l][i - 1][j - 1];
                }
            }
        }
    }

    int ans = 0;

    for(int l = 0; l < 2; ++l)
    {
        for (int i = 0; i < k; ++i)
        {
            for (int j = 0; j < k; ++j)
            {
                int cur = 0;

                if (i && j)
                {
                    cur += ps[l][i - 1][j - 1];
                }

                if(i)
                {
                    cur += ps[1 - l][i - 1][k];
                    if(j)
                    {
                        cur -= ps[1 - l][i - 1][j - 1];
                    }
                }

                if(j)
                {
                    cur += ps[1 - l][k][j - 1];
                    if(i)
                    {
                        cur -= ps[1 - l][i - 1][j - 1];
                    }
                }

                cur += ps[l][k][k];
                if(i)
                {
                    cur -= ps[l][i - 1][k];
                }
                if(j)
                {
                    cur -= ps[l][k][j - 1];
                }
                if(i && j)
                {
                    cur += ps[l][i - 1][j - 1];
                }

                ans = max(ans, cur);
            }
        }
    }

    cout << ans << endl;
}

/* ________ CODE ________ */

int main()
{
#if defined(ANDREIKKAA)
    time_t _start = clock();
#endif
    if (_inpf[0] != '\0') assert(freopen(_inpf, "r", stdin) != nullptr);
    if (_outf[0] != '\0') assert(freopen(_outf, "w", stdout) != nullptr);
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << setprecision(228);
    //cout << fixed;
    mainFunction();
#if defined(ANDREIKKAA)
    cout << "Time: " << (clock() - _start) / (ld)CLOCKS_PER_SEC << endl;
#endif
}


Measured memory_bytes: 8064