/*input
3 2
1 7 2
7 8 1
8 12 1

9 4
56 60 4
33 37 2
89 90 3
32 43 1
67 68 3
49 51 3
31 32 3
70 71 1
11 12 3
*/

/*
When you walk through a storm
Hold your head up high
And don't be afraid of the dark
At the end of the storm
There's a golden sky
And the sweet silver song
of the lark
Walk on, through the wind
Walk on, through the rain
Though your dreams be tossed
and blown
Walk on, walk on
With hope in your heart
And you'll never walk alone
YNWA
*/

//hell_hacker
//IT TAKES EVERYTHING and IT IS NOT LUCK
//PICK ME LAST -- COME OUT OF N^WHERE

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define fo(i,n) for(i=0;i<n;++i)
#define forr(i,n) for(i=n-1;i>=0;--i)

#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define yolo "debug_statement"

typedef long long int ll;
typedef long double ld;
typedef pair<int,int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;

const ll inf = 1e9;
const ld eps = 1e-9;
const ld pi=acos(-1);
const ll mod=1000000007;

ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}



#if DEBUG && !ONLINE_JUDGE

    #define debug(args...)     (Debugger()) , args

    class Debugger
    {
        public:
        Debugger(const std::string& _separator = ", ") :
        first(true), separator(_separator){}

        template<typename ObjectType>
        Debugger& operator , (const ObjectType& v)
        {
            if(!first)
                std::cerr << separator;
            std::cerr << v;
            first = false;
            return *this;
        }
        ~Debugger() {  std::cerr << endl;}

        private:
        bool first;
        std::string separator;
    };

    template <typename T1, typename T2>
    inline std::ostream& operator << (std::ostream& os, const std::pair<T1, T2>& p)
    {
        return os << "(" << p.first << ", " << p.second << ")";
    }

    template <typename T1, unsigned long int N>
    inline std::ostream& operator << (std::ostream& os, const std::array<T1, N>& a){
        bool first = true;
        os << "[";
        for(unsigned int i = 0; i < N; i++)
        {
            if(!first)
                os << ", ";
            os << a[i];
            first = false;
        }
        return os << "]";   
    }

    template<typename T>
    inline std::ostream &operator << (std::ostream & os,const std::vector<T>& v)
    {
        bool first = true;
        os << "[";
        for(unsigned int i = 0; i < v.size(); i++)
        {
            if(!first)
                os << ", ";
            os << v[i];
            first = false;
        }
        return os << "]";
    }

    template<typename T>
    inline std::ostream &operator << (std::ostream & os,const std::set<T>& v)
    {
        bool first = true;
        os << "[";
        for (typename std::set<T>::const_iterator iii = v.begin(); iii != v.end(); ++iii)
        {
            if(!first)
                os << ", ";
            os << *iii;
            first = false;
        }
        return os << "]";
    }

    template<typename T1, typename T2>
    inline std::ostream &operator << (std::ostream & os,const std::map<T1, T2>& v)
    {
        bool first = true;
        os << "[";
        for (typename std::map<T1, T2>::const_iterator iii = v.begin(); iii != v.end(); ++iii)
        {
            if(!first)
                os << ", ";
            os << *iii ;
            first = false;
        }
        return os << "]";
    }

#else
    #define debug(args...)                  // Just strip off all debug tokens
#endif

int recorder[50][3];
int ptr;
int n, ccc;

struct helik{
	int s, t, c;
}tv[100005];

// bool check(int x){
// 	int i;
// 	for(i=0;i<n;++i){

// 	}
// }

bool cmp(struct helik &lhs, struct helik &rhs){
	if(lhs.s == rhs.s)
		if(lhs.t == rhs.t)
			return lhs.c < rhs.c;
		else 
			return lhs.t < rhs.c;
	else
		return lhs.s < rhs.s;
}

int main(){
    ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);
    int i, j;
    cin >> n >> ccc;
    for(i=0;i<n;++i){
    	cin >> tv[i].s >> tv[i].t >> tv[i].c;
    }

    sort(tv,tv+n,cmp);

    // fo(i,n){
    	// cout << tv[i].s << " " << tv[i].t << " " << t
    // }

    int rec = 0;
    // for(i=0;i<n;++i)
    // 	cout << tv[i].s << " " << tv[i].t << " " << tv[i].c << endl;
    recorder[ptr][0] = tv[0].s, recorder[ptr][1] = tv[0].t, recorder[ptr][2] = tv[0].c;
    for(i=1;i<n;++i){
    	for(j=0;j<=ptr;++j){
    		if(tv[i].s > recorder[j][1]){
    			recorder[j][0] = tv[i].s, recorder[j][1] = tv[i].t, recorder[j][2] = tv[i].c;
    			break;
    		}
    		else if(tv[i].s == recorder[j][1] && tv[i].c == recorder[j][2]){
    			recorder[j][0] = tv[i].s, recorder[j][1] = tv[i].t, recorder[j][2] = tv[i].c;
    			break;
    		}
    	}
    	if(j == (ptr+1)){
    		// cout << i << endl;
    		ptr++;
    		recorder[ptr][0] = tv[i].s, recorder[ptr][1] = tv[i].t, recorder[ptr][2] = tv[i].c;
    	}
    }
    cout << ptr + 1 << endl;

    // int lo = 1;
    // int hi = ccc;

    // int res = ccc;
    // while(lo <= hi){
    // 	int mid = (lo + hi) >> 1;
    // 	if(check(mid))
    // 		res = mid, hi = mid - 1;
    // 	else 
    // 		lo = mid + 1;
    // }

    // cout << res << endl;
    return 0;
}



Measured memory_bytes: 1408