#include <cstdio>
#include <algorithm>
#include <set>
#include <unordered_map>

using namespace std;

//#define DBG
//#define CHECK

#define TMAX 1000000001  // czas większy niż wszystkie

int n, k;

struct Rezerw {
  int a, b, p;
  int maxt; // maksymalny czas na który można ją zaplanować;
  int t;    // czas przydzielony
};
Rezerw *R;
int *ord; // porządek rezerwacji (aby nie sortować całych struktur)

bool cmp_pb(int r1, int r2) {
  if (R[r1].p != R[r2].p)
    return R[r1].p < R[r2].p;
  else
    return R[r1].b > R[r2].b;
}

bool cmp_a(int r1, int r2) {return R[r1].a < R[r2].a;}

// ----------------------------------------------------------------------------------------------------

typedef pair<int, int> Para;
inline Para _Para(int a, int b) {return pair<int, int>(a, b);}

// miotła
set<Para> M_maxt;      // (maxt, numer rezerwacji)
unordered_map<int, int> M_p;     // (przyrząd, liczba wystąpień)
set<pair<Para, int> > P_maxt; // ((przyrząd, maxt), numer rezerwacji)

#ifdef DBG
void dump(int i, int t)
{
  printf("i=%d, t=%d\n", i, t);
  printf(  "  M_maxt: ");
  for(Para p : M_maxt) printf("%d.%d ", p.second, p.first);
  printf("\n  M_p   : ");
  for(Para p : M_p) printf("%d.%d ", p.first, p.second);
  printf("\n  P_maxt: ");
  for(pair<Para, int> p : P_maxt) printf("%d.%d(%d) ", p.first.first, p.first.second, p.second);
  printf("\n");
}
#endif

// Zaplanować na t najwcześniejszą (w sensie maxt) rezerwację dla każdego przyrządu na miotle.
void planuj(int t)
{
  vector<Para> todo; // (numer rezerwacji do zaplanowania, ile jest rezerwacji na ten przyrząd)

  for(unordered_map<int, int>::iterator mp_it = M_p.begin(); mp_it != M_p.end(); ++mp_it) {
    // najwcześniejsza w sensie maxt rezerwacja dla przyrządu (musi być)
    set<pair<Para, int> >::iterator pm_it = P_maxt.lower_bound(pair<Para, int>(Para(mp_it->first, -1), 0));
    todo.push_back(Para(pm_it->second, mp_it->second)); // numer rezerwacji, ile rezerwacji na dany przyrząd
    #ifdef DBG
    //printf("   todo: %d %d\n", pm_it->second, mp_it->second);
    #endif // DBG
  }
  for (Para nr_ilep : todo) {
    Rezerw &rez = R[nr_ilep.first];
    rez.t = t; // planuj
    #ifdef CHECK
    if (t < rez.a || t > rez.b) {
      printf("CHECK 2!!! t=%d, rez=%d, (%d, %d..%d), maxt=%d\n", t, nr_ilep.first, rez.p, rez.a, rez.b, rez.maxt);
      exit(0);
    }
    #endif
    #ifdef DBG
    printf("    t=%d, rez=%d, (%d, %d..%d), maxt=%d\n", t, nr_ilep.first, rez.p, rez.a, rez.b, rez.maxt);
    #endif

    M_maxt.erase(Para(rez.maxt, nr_ilep.first)); // usuń z miotły rezerwację (-maxt, nr rez)
    if (nr_ilep.second == 1)
      M_p.erase(rez.p); // nie ma już przyrządu na miotle
    else
      M_p[rez.p] = nr_ilep.second - 1;
    P_maxt.erase(pair<Para, int>(_Para(rez.p, rez.maxt), nr_ilep.first)); // usuń z miotły ((przyrząd, maxt), nr rez)
  }
}

int licz()
{
  /*
      Dla każdej rezerwacji ustalić najpóźniejszy możliwy czas:
          Posortować je wg przyrządu i czasu końca malejąco.
          Przejść kolejno i wrzucać do zbioru uporządkowanego wg czasu początku.
          maxt trzeba ustawiać najpierw dla tych o najpóźniejszym początku.
      Posortować wg czasu początku.
      Bierzemy kolejne idąc po czasach początku.
          Struktura danych (miotła, t - czas)
              Zawiera rezerwacje, które właśnie chcemy zaplanować. Może być to więcej niż jedna dla przyrządu.
              Musimy znać maximum z maxt dla wszystkich rezerwacji na miotle
                  M_maxt set<int, int> zawierający (-maxt, numer rez) - aby łatwiej przez begin() brać max
              Musimy znać przyrządy na miotle oraz liczbę rezerwacji na przyrząd
                  M_p    map<int, int> dla przyrządów (przyrząd, liczba wystąpień)
              Dla każdego przyrządu musimy znać taką o najwcześniejszym maxt i najpóźniejszym maxt
                  P_maxt set<<int, int>, int> zawierający ((przyrząd, maxt), numer rezerwacji)
                  najwcześniejsze maxt dla p: lower_bound(p, -1)
                  najpóźniejsze maxt dla p: upper_bound(p, TMAX) - 1
              Niezmiennik na miotle:
                Wszystkie na miotle można zaplanować na t
                Nie może być takiej rezerwacji dla której maxt > t (bo już za późno)
                Nie może być za dużo dla jednego przyrządu tzn. t + M_p[p] > max(maxt) dla p (bo nie zdążymy ich zaplanować)
          Jeśli kolejna rezerwacja ma a > t to:
            Jeśli się okaże, że a > min(maxt) z rezerwacji z miotły to:
                Trzeba zaplanować na t najwcześniejszą (w sensie maxt) rezerwację dla każdego przyrządu na miotle.
            ustawiamy t := a
          Po dołożeniu nowej rezerwacji na p trzeba sprawdzić czy za dużo się nie zgromadziło na ten przyrząd.
          Jeśli t + M_p[p] > max(maxt) z rezerwacji dla przyrządu na miotle to nie zdążymy ich zrobić później niż teraz:
              Trzeba zaplanować na t najwcześniejszą (w sensie maxt) rezerwację dla każdego przyrządu na miotle.
      Jeśli nie ma już więcej to trzeba zaplanować wszystkie z miotły na kolejne t, t+1, ... dopóki coś jest na miotle.
  */
  int i, t;
  int wyn = 0;

  sort(ord, ord + n, cmp_pb); // sortowanie wg przyrządu i czasu b malejąco

  i = 0;  // numer kolejny rezerwacji w porządku ord
  while (i < n) { // dla każdego przyrządu
    set<Para> PQ;  // rezerwacje o b >= t (-b, numer rez)  - aby łatwo wyciągać największe
    set<Para> PQ2; // rezerwacje o b >= maxt (-a, numer rez)  - aby łatwo wyciągać największe
    int maxt = TMAX;      // max czas jaki można jeszcze przydzielić
    int p = R[ord[i]].p;    // aktualny przyrząd
    while (i < n && R[ord[i]].p == p) {  // rezerwacje na dany przyrząd
      #ifdef CHECK
      if (n < 100 || i % (n / 100) == 0) printf("%d%%\n", 100 * i / n);
      #endif // CHECK
      t = R[ord[i]].b; // czas końcowy rezerwacji
      while (i < n && R[ord[i]].p == p && R[ord[i]].b == t) { // do PQ wszystkie rezerwacje na ten przyrząd z czasem końca b
        PQ.insert(Para(-R[ord[i]].b, ord[i]));
        #ifdef DBG
        printf("PQ.insert(%d, %d)\n", -R[ord[i]].b, ord[i]);
        #endif // DBG
        i++;
      }
      if (PQ2.size() == 0) {
        maxt = min(maxt, -PQ.begin()->first); // cofamy maxt jeśli rezerwacja o najpóźniejszym b ma b < maxt
        #ifdef DBG
        printf("t=%d, maxt=%d, PQ.max=%d\n", t, maxt, -PQ.begin()->first);
        #endif // DBG
        while (true) {
          set<Para>::iterator it = PQ.begin();
          if (-it->first < maxt)
            break;
          else {
            int nr = PQ.begin()->second;
            PQ2.insert(Para(-R[nr].a, nr));
            PQ.erase(it);
          }
        }
      }
      bool ostatnia = (i == n || R[ord[i]].p != p); // wszystkie dla przyrządu już mamy
      // można bezpiecznie przydzielić do czasu t (brak konfliktu z rezerwacjami których nie ma w PQ) lub wszystkie jak nie ma innych dla p
      while (PQ2.size() && (maxt >= t || ostatnia)) {
        set<Para>::iterator it = PQ2.begin();  // najpierw te o największym a
        Rezerw &rez = R[it->second];
        rez.maxt = maxt--;
        if (rez.a > rez.maxt) return -1;    // nie da się zaplanować bo kolejna chce się zaczynać później niż maxt dla poprzedniej
        #ifdef DBG
        printf("rez=%d, (%d, %d..%d), maxt=%d t=%d\n", it->second, p, rez.a, rez.b, rez.maxt, t);
        #endif // DBG
        #ifdef CHECK
        if (rez.maxt < rez.a || rez.maxt > rez.b) {
          printf("CHECK 1!!! t=%d, rez=%d, (%d, %d..%d), maxt=%d\n", t, it->second, rez.p, rez.a, rez.b, rez.maxt);
          exit(0);
        }
        #endif
        PQ2.erase(it);
        while (PQ.size()) {  // sprawdzić co można przerzucić z PQ po zmniejszeniu maxt
          set<Para>::iterator it = PQ.begin();
          if (-it->first < maxt)
            break;
          else {
            int nr = PQ.begin()->second;
            PQ2.insert(Para(-R[nr].a, nr));
            PQ.erase(it);
          }
        }
      }
    }
  }

  #if defined DBG || defined CHECK
  printf("faza 2\n");
  #endif
  sort(ord, ord + n, cmp_a); // sortowanie wg czasu a rosnąco

  t = 0; // ostatni zaplanowany czas
  for (i = 0; i < n; ++i) {
    #ifdef CHECK
    if (n < 100 || i % (n / 100) == 0) printf("%d%%\n", 100 * i / n);
    #endif // CHECK
    int nr = ord[i]; // numer rezerwacji
    Rezerw &rez = R[nr];
    #ifdef DBG
    printf("rez=%d, (%d, %d..%d), maxt=%d\n", nr, rez.p, rez.a, rez.b, rez.maxt);
    dump(i, t);
    #endif // DBG
    if (rez.a > t) { // nie nastąpi dla t = 0 (pierwszy obrót)
      while (M_maxt.size() > 0 && rez.a > M_maxt.begin()->first) {
        #ifdef DBG
        printf("  planuj A (%d > %d)\n", rez.a, M_maxt.begin()->first);
        #endif // DBG
        planuj(t);
        wyn++;
      }
      t = rez.a;
    }
    // TODO: a może tu przyspieszy jak dodamy od razu wszystkie rezerwacje dla danego a?

    // dokładamy rezerwację do miotły
    M_maxt.insert(_Para(rez.maxt, nr));

    int ile_dla_p; // ile na miotle jest rezerwacji dla przyrządu
    unordered_map<int, int>::iterator mp_it = M_p.find(rez.p);
    if (mp_it == M_p.end())
      ile_dla_p = M_p[rez.p] = 1;
    else
      ile_dla_p = M_p[rez.p] = mp_it->second + 1;

    // dokładamy informację o maxt dla przyrządu
    P_maxt.insert(pair<Para, int>(_Para(rez.p, rez.maxt), nr));
    set<pair<Para, int> >::iterator pm_it = P_maxt.upper_bound(pair<Para, int>(_Para(rez.p, TMAX), 0));
    pm_it--; // cofnięcie na ostatni

    #ifdef DBG
    dump(i, t);
    #endif // DBG

    if (t + ile_dla_p > pm_it->first.second) {
      // czas + liczba rezerwacji dla dołożonego przyrządu > maxt dla rezerwacji na ten przyrząd
      #ifdef DBG
      printf("  planuj B (%d + %d > %d)\n", t, ile_dla_p, pm_it->first.second);
      #endif // DBG
      planuj(t++);
      wyn++;
    }
      // TODO: czy na pewno wystarczy raz? chyba tak bo dla każdego przyrządu się zaplanuje
  }
  while (M_maxt.size()) {
    #ifdef DBG
    printf("  planuj C\n");
    #endif // DBG
    planuj(t++);
    wyn++;
  }

  return wyn;
}

// ----------------------------------------------------------------------------------------------------

int czytaj()
{
  int i;
  scanf("%d%d", &n, &k);
  R = new Rezerw[n];
  ord = new int[n];
  for (i = 0; i < n; ++i) {
    ord[i] = i;
    scanf("%d%d%d", &R[i].a, &R[i].b, &R[i].p);
  }
}

// ----------------------------------------------------------------------------------------------------

int main()
{
  czytaj();
  #ifdef CHECK
  printf("wczytane\n");
  #endif // CHECK
  int wyn = licz();
  if (wyn == -1)
    printf("NIE\n");
  else {
    printf("%d\n", wyn);
    #ifndef CHECK
    for (int i = 0; i < n; ++i) printf("%d\n", R[i].t);
    #endif // CHECK
  }
  return 0;
}
