#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <map>

typedef long long lLong;
typedef unsigned long uLong;
typedef unsigned long long ulLong;
typedef unsigned int uInt;
typedef unsigned char Byte;

using namespace std;

#define FOR(x, b, e) for(int x=b; x<=(e); ++x)
#define ALL(i) (i).begin(), (i).end()
#define CONTAINS(i,v) (find(ALL(i),v)!=(i).end())
typedef vector<bool> bit_vector;
typedef vector<int> int_vector;
typedef vector<uInt> VI;
typedef vector<ulLong> VLL;


#define MAX_N 100
#define MAX_K 10000000

class Zadanie
{
public:
	int Id; //w sumie raczej nieistotne - liczba porządkowa wczytana taska
	int PoczatekMin; //od której chwili czasowej task może być wrzucony do procesora	
	int Koniec; //koniec na globalnej osi czasu
	int Czas; //czas pozostały do wykonania zadania
	int PoczatekMax;

	Zadanie(int poczatek, int koniec, int czas)
	{
		PoczatekMin = poczatek;
		Czas = czas < 0 ? 0 : czas;
		Koniec = koniec;
		PoczatekMax = PobierzPoczatekMax();
	}
	inline int PobierzPoczatekMax() const
	{
		return Koniec - Czas;
	}
	inline bool CzyUkonczone()
	{
		return Czas <= 0;
	}
	inline bool CzyPrzeterminowane()
	{
		int poczMax = PobierzPoczatekMax();
		return (PoczatekMin > poczMax || poczMax >= Koniec) && !CzyUkonczone();
	}

	inline bool CzyIstotniejsze(const Zadanie* rhs) const
	{
		const Zadanie* lhs = this;
		if (lhs->PoczatekMin < rhs->PoczatekMin) return true;
		if (lhs->PoczatekMin == rhs->PoczatekMin)
		{
			int pr1 = lhs->PobierzPoczatekMax(); 
			int pr2 = rhs->PobierzPoczatekMax(); 
			if (pr1 < pr2) return true;
			if (pr1 == pr2) //jesli nadal rownowazne - to wygrywa ten o krótszym czasie wykonania
			{
				if (lhs->Czas < rhs->Czas) return true;
				if (lhs->Czas == rhs->Czas)
				{
					return lhs->Koniec < rhs->Koniec;
				}
			}
		}
		return false;
	}

	Zadanie* PrzesunPoczatek(int czas)
	{
		//sprawdzamy czy w czasie zawieszenia zadanie już nie jest zakończone - jak tak to ustawiamy status i 
		//olewamy przy kolejnych przydzialach		
		if (czas >= PoczatekMin)
		{
			Czas = Czas - (czas - PoczatekMin);
			PoczatekMin = czas;
			Czas <= 0
				? 0
				: Czas;
			PoczatekMax = PobierzPoczatekMax();
		}
		return this;
	}
	
};

struct MniejszeOdByPoczatek
{
	bool operator()(const Zadanie* lhs, const Zadanie* rhs) const
	{
		return lhs->CzyIstotniejsze(rhs);
	}
};

typedef vector<Zadanie*> VZad;

class Cpu
{
private:
	Zadanie *_aktualneZadanie;
public:
	Cpu()
	{
		_aktualneZadanie = NULL;
	}
	int PobierzPlanowanyKoniec()
	{
		if (NULL == _aktualneZadanie) return 0;
		//return _aktualneZadanie->Koniec;
		return _aktualneZadanie->PoczatekMin + _aktualneZadanie->Czas;
	}
	void AktualizujAktualnyCzas(int czas)
	{
		if (NULL == _aktualneZadanie) return;
		_aktualneZadanie->PrzesunPoczatek(czas);
		if (!_aktualneZadanie->CzyUkonczone()) return;
		_aktualneZadanie = NULL;
	}

	Zadanie *PobierzAktualneZadanie()
	{
		return _aktualneZadanie;
	}

	Zadanie* PrzydzielProcesor(Zadanie *zadanie)
	{
		if (NULL == _aktualneZadanie)
		{
			_aktualneZadanie = zadanie;
			return NULL;
		}
		if (NULL == zadanie) return NULL;
		//
		if (zadanie->PoczatekMin >= _aktualneZadanie->Koniec)
		{
			//zakładamy że mniejszych już nie będzie na tym cpu - więc ustawiamy
			_aktualneZadanie = zadanie;
			return NULL;
		}

		if (zadanie->CzyIstotniejsze(_aktualneZadanie))
		{
			Zadanie *tmp = _aktualneZadanie;
			_aktualneZadanie = zadanie;
			return tmp->CzyUkonczone() ? NULL : tmp;
		}
		return zadanie->CzyUkonczone() ? NULL : zadanie;
	}
};

class PrzypadekTestowy
{
private:
	uInt _n, _m;
	FILE *_input;
	Cpu _procesory[MAX_N];
	
	VZad _kolejka;

	inline void Reset()
	{		
	}
	inline void WczytajPareUInt(uInt *value1, uInt *value2)
	{
		fscanf(_input, "%d %d\n", value1, value2);
	}
	inline void WczytajTrojkeInt(int *value1, int *value2, int *value3)
	{
		fscanf(_input, "%d %d %d\n", value1, value2, value3);
	}

public:
	PrzypadekTestowy() :_input(stdin)
	{
	}
	PrzypadekTestowy(FILE *input)
	{
		_input = input;
	}

	inline void Wykonaj()
	{
		Reset();
		WczytajPrzypadekTestowy();
		Rozwiaz();
	}
	inline int PobierzNapredzejDostepnyCpu()
	{
		int minKoniec = MAX_K;
		int result = -1;
		for (uInt i = 0; i < _m; i++)
		{
			int k = _procesory[i].PobierzPlanowanyKoniec();
			if (k == 0) return i;
			if (k < minKoniec)
			{
				minKoniec = k;
				result = i;
			}
		}
		return result;
	}

	inline void UstawCpuTimeLine(int timeLine)
	{		
		for (uInt i = 0; i < _m; i++)
		{
			_procesory[i].AktualizujAktualnyCzas(timeLine);
		}
	}

	inline void Rozwiaz()
	{
		Zadanie *tmp = NULL;
		Cpu *najpredzejDostepny = NULL;
		int minCzasPocz = MAX_K;

		while (!_kolejka.empty())
		{
			bool przydzielono = false;
			std::sort(_kolejka.begin(), _kolejka.end(), MniejszeOdByPoczatek());
			tmp = _kolejka[0];
			_kolejka.erase(_kolejka.begin());
			int prevId = tmp->Id;
			UstawCpuTimeLine(tmp->PoczatekMin);

			for (uInt i = 0; i < _m; i++) //od razu okladamy wszystkie procesory
			{
				tmp = _procesory[i].PrzydzielProcesor(tmp);				
				if (tmp == NULL) break; //przydzielono zadanie do wolnego procka - koncyzmy petle								
										//if (tmp && tmp->Id) break;
			}
			if (tmp && !tmp->CzyUkonczone())
			{
				if (tmp->Id == prevId) //wszystkie procesy w tej chwili czasowej niestety mają wyższy priorytet - więc wybieramy zadanie z najkrótszym czasem pozostałym do wykonania
				{
					int cpuIdx = PobierzNapredzejDostepnyCpu();
					int nowyStart = _procesory[cpuIdx].PobierzPlanowanyKoniec();
					nowyStart = min(nowyStart, tmp->PoczatekMax);
					if (tmp->PoczatekMin == nowyStart)
					{
						_kolejka.push_back(tmp);
						break;
					}
					else
					{
						tmp->PoczatekMin = nowyStart;
					}
				}
				_kolejka.push_back(tmp);
				if (tmp->CzyPrzeterminowane())
					break; //mamy pierwszy przeterminowany - wiec sie nie da uszeregowac				
			}
		}

		if (_kolejka.empty())
		{
			printf("TAK\n");
		}
		else
		{
			printf("NIE\n");
		}
	}

	inline void WczytajPrzypadekTestowy()
	{
		WczytajPareUInt(&_n, &_m);
		_kolejka.reserve(_n);
		int p, k, c; //poczatek,koniec,czas;
		for (uInt i = 0; i < _n; i++)
		{
			WczytajTrojkeInt(&p, &k, &c);
			Zadanie *zad = new Zadanie(p, k, c);
			zad->Id = i;
			_kolejka.push_back(zad);
		}
	}
};

int main(int argc, char **argv)
{
	FILE *in = stdin;
	if (argc>1)
	{
		in = fopen(argv[1], "rt");
		if (NULL == in)
		{
			in = stdin;
		}
	}

	PrzypadekTestowy *p = new PrzypadekTestowy(in);
	p->Wykonaj();
	fclose(in);
	delete(p);
	return 0;
}
