// Piotr Golda
#define _CRT_SECURE_NO_WARNINGS  
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
#define LLD long long int

#define MAX_NUM 50000

class Car;

template< class _Object >
class PartitionTree;

int T, N, W;
int POS[ MAX_NUM ];
Car* Parking;
PartitionTree< int >* Height;  

/**************************
DRZEWO PRZEDZIALOWE
pytanie-przedzial-max
modyfikacja-element-dodawanie
***************************/
template< class _Object >
class PartitionTree
{
	unsigned int m_size;
	_Object* m_T;
	_Object m_neutral;

	const _Object& (*m_questionFunction)( const _Object&, const _Object&);
	void (*m_modificationFunction)( _Object&, _Object&);


	static const _Object& maximum_query(const _Object&, const _Object&);
	static void add( _Object&, _Object&);

public:

	PartitionTree(unsigned int);
	PartitionTree(unsigned int, _Object );
	~PartitionTree();

	void modify(unsigned int, _Object );
	_Object query(unsigned int, unsigned int);

	//friend ostream& operator<< <>( ostream&, PartitionTree<_Object> );

	const _Object& getObject( unsigned int );
	unsigned int getSize();
};


class Car
{
public:
	unsigned m_num;
	unsigned m_position;
	unsigned m_height;

	Car( unsigned p_num, unsigned p_pos, unsigned p_height )
		:m_num(p_num), m_position(p_pos), m_height(p_height){}
	Car()
		:m_num(0), m_position(0), m_height(0){}

	bool operator<( const Car& p_rhs ) const
	{
		if( m_position < p_rhs.m_position )
			return true;
		return false;
	}

};


//bool cmp(const Car& p_lhs, const Car& p_rhs )
//{
//
//}

void scan()
{
	scanf("%d %d", &N, &W);
	Parking = new Car[N];
	int a,b,c,d;
	for(int i = 0; i < N; ++i)
	{
			scanf( "%d %d %d %d", &a, &b, &c, &d);
			if( c < a )
				swap(a,c);
			Parking[i] = Car(i, a, abs(d - b) );
	}
	sort(Parking, Parking+N);
}

void initialize()
{
	
	for(int i = 0; i < N; ++i)
	{
		//cout<< Parking[i].m_num<<' ';
		POS[ Parking[i].m_num ] = i;
		Height->modify(i, Parking[i].m_height );
	}
	//cout<<endl;
}

bool scanCheckDestination()
{
	int a,b,c,d;
	for(int i = 0; i < N; ++i)
	{
		scanf( "%d %d %d %d", &a, &b, &c, &d);
		if( c < a )
			swap(a,c);
		Parking[i] = Car(i, a, abs(d - b) );
	}

	sort(Parking, Parking+N);

	int pos;
	int maxPrev;
	for(int i = 0; i < N; ++i)
	{
		pos = POS[ Parking[i].m_num ];
		if( pos != 0 )
			maxPrev = Height->query(0, pos-1 );
		else
			maxPrev = 0;
		if( maxPrev + Parking[i].m_height > W )
			return false;
		Height->modify(pos, -((int)Parking[i].m_height) );
	}

	return true;
}


int main()
{
	scanf("%d", &T);
	for(int t = 0; t < T; ++t)
	{
		scan();
		Height = new PartitionTree<int>( N );
		initialize();
		if( scanCheckDestination() )
			printf("TAK\n");
		else
			printf("NIE\n");
		delete Height;
	}
	return 0;
}


/**************************
DRZEWO PRZEDZIALOWE
***************************/
template< class _Object >
inline PartitionTree<_Object>::PartitionTree( unsigned int p_size )
	:m_neutral( _Object() )
{
	if(p_size == 0)
		throw;
	m_size = 1;
	while( m_size < p_size )
	{
		m_size = m_size << 1;
	}
	m_size = m_size << 1;

	m_T = new _Object[m_size+1];
	

	for(unsigned int i = 0; i <= m_size; ++i)
		m_T[i] = m_neutral;
	m_questionFunction = (&PartitionTree<_Object>::maximum_query);
	m_modificationFunction = (&PartitionTree<_Object>::add);

	m_size = m_size >> 1;
}

template< class _Object >
inline PartitionTree<_Object>::PartitionTree( unsigned int p_size, _Object p_neutralObject )
	:m_neutral( p_neutralObject )
{
	if(p_size == 0)
		throw;
	m_size = 1;
	while( m_size < p_size )
	{
		m_size = m_size << 1;
	}
	m_size = m_size << 1;

	m_T = new _Object[m_size+1];
	

	for(unsigned int i = 0; i <= m_size; ++i)
		m_T[i] = m_neutral;
	m_questionFunction = (&PartitionTree<_Object>::maximum_query);
	m_modificationFunction = (&PartitionTree<_Object>::add);

	m_size = m_size >> 1;
}

template< class _Object >
inline PartitionTree<_Object>::~PartitionTree()
{
	delete[] m_T;
}


template< class _Object >
inline unsigned int PartitionTree<_Object>::getSize()
{
	return m_size;
}

template< class _Object >
inline const _Object& PartitionTree<_Object>::getObject( unsigned int p_index )
{
	return m_T[ p_index + m_size ];
}

template< class _Object >
inline const _Object& PartitionTree<_Object>::maximum_query( const _Object& p_lhs, const _Object& p_rhs)
{
	return max(p_lhs, p_rhs);
}

template< class _Object >
inline void PartitionTree<_Object>::add( _Object& p_desValue, _Object& p_srcValue )
{
	p_desValue = p_desValue + p_srcValue;
}

template< class _Object >
inline void PartitionTree<_Object>::modify(unsigned int p_index, _Object p_parameter )
{
	p_index += m_size;
	m_modificationFunction( m_T[ p_index ], p_parameter );
	while ( p_index != 1 ) 
	{
		p_index = p_index >> 1;
		m_T[p_index] = m_questionFunction( m_T[ p_index << 1 ] , m_T[ (p_index << 1) + 1] );
    }
}

template< class _Object >
inline _Object PartitionTree<_Object>::query(unsigned int p_a, unsigned int p_b)
{
	unsigned int va = m_size + p_a, vb = m_size + p_b;
   /* Skrajne przedziały do rozkładu. */
	_Object wyn = m_questionFunction( m_T[va], m_T[vb]);
   /* Spacer aż do momentu spotkania. */
   while ( (va >> 1) != (vb >> 1) ) {
     if (va % 2 == 0) wyn =  m_questionFunction( wyn, m_T[va + 1] ); /* prawa bombka na lewej ścieżce */
     if (vb % 2 == 1) wyn =  m_questionFunction( wyn, m_T[vb - 1] ); /* lewa bombka na prawej ścieżce */
     va = va >> 1; vb = vb >> 1;
   }
   return wyn;
}

//template< class _Object >
//ostream& operator<<( ostream& p_out, PartitionTree<_Object> p_Tree )
//{
//	unsigned int pot = 2;
//	for(int i = 1; i < p_Tree.m_size << 1; ++i)
//	{
//		p_out << p_Tree.m_T[i] <<' ';
//		if( i+1 == pot )
//		{
//			pot = pot << 1;
//			p_out<<'\n';
//		}
//	}
//	return p_out;
//}