// Original C++ solution (slower):
#include <bits/stdc++.h>

#define int long long

#define uint unsigned int

#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, a, b) for (int i = (a); i < (b); ++i)

#define FORR(i, a, b) for (int i = (a); i >= (b); --i)

#define ALL(a) (a).begin(), (a).end()

#define ALLR(a) (a).rbegin(), (a).rend()

#define SZ(a) ((int)(a).size())

#define PB(a) push_back(a)

#define EMP emplace

#define EMPB(...) emplace_back(__VA_ARGS__)

#define MP(a, b) make_pair(a, b)

#define MT(...) make_tuple(__VA_ARGS__)

#define Bit(n) (1LL << (n))

using namespace std;

using pii = pair<int, int>;

template <class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

template <class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }

const int MOD = 1000000007;

const int INF = 1LL << 30;

const double EPS = 1e-10;



int N, C;

vector<pii> v[30];



vector<pii> f(vector<pii>& v) {

  vector<pii> res;

  sort(ALL(v));

  res.EMPB(v[0]);

  FOR(i, 1, SZ(v)) {

    if (v[i].first == res.back().second) {

      res.back().second = v[i].second;

    } else {

      res.EMPB(v[i]);

    }

  }

  return res;

}



signed main() {

  cin.tie(0);

  ios_base::sync_with_stdio(false);

  cout << fixed << setprecision(10);

  

  cin >> N >> C;

  REP(i, N) {

    int s, t, c;

    cin >> s >> t >> c;

    c--;

    v[c].EMPB(s, t);

  }

  REP(i, C) if (!v[i].empty()) v[i] = f(v[i]);

  int cum[200010] = {};

  REP(i, C) REP(j, SZ(v[i])) {

    cum[v[i][j].first*2-1]++;

    cum[v[i][j].second*2]--;

  }

  int ans = 0;

  FOR(i, 1, 200010) {

    cum[i] += cum[i-1];

    chmax(ans, cum[i]);

  }

  cout << ans << endl;



  return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#define int long long

#define pii pair<int,int>

#define FOR(i,a,b) for(int i=(a);i<(b);++i)

#define REP(i,n) FOR(i,0,n)

#define ALL(c) (c).begin(),(c).end()

#define ZERO(a) memset(a,0,sizeof(a))

#define MINUS(a) memset(a,0xff,sizeof(a))

#define MINF(a) memset(a,0x3f,sizeof(a))

#define POW(n) (1LL<<(n))

#define IN(i,a,b) (a <= i && i <= b)

using namespace std;

template <typename T> inline bool CHMIN(T& a,T b) { if(a>b) { a=b; return 1; } return 0; }

template <typename T> inline bool CHMAX(T& a,T b) { if(a<b) { a=b; return 1; } return 0; }

template <typename T> inline void SORT(T& a) { sort(ALL(a)); }

template <typename T> inline void REV(T& a) { reverse(ALL(a)); }

template <typename T> inline void UNI(T& a) { sort(ALL(a)); a.erase(unique(ALL(a)),a.end()); }

const int MOD = 1000000007;

const int INF = 0x3f3f3f3f3f3f3f3f;

const double EPS = 1e-10;

/* ---------------------------------------------------------------------------------------------------- */



int N,C;

vector<pii> v[31];

int cum[200010];



signed main() {

  cin.tie(0);

  ios_base::sync_with_stdio(false);

  cout << fixed << setprecision(10);



  cin >> N >> C;

  REP(i,N) {

    int s,t,c;

    cin >> s >> t >> c;

    c--;

    v[c].emplace_back(s,t);

  }

  REP(i,C) {

    SORT(v[i]);

    int l = 0, r = 0;

    while (l < v[i].size()) {

      while (r+1 < v[i].size() && v[i][r].second == v[i][r+1].first) r++;

      cum[2*v[i][l].first-1]++;

      cum[2*v[i][r].second]--;

      l = ++r;

    }

  }

  int ans = 0;

  REP(i,200005) {

    cum[i+1] += cum[i];

    CHMAX(ans,cum[i+1]);

  }

  cout << ans << endl;



  return 0;

}

// Fastest known solution for this problem: