//============================================================================
// Name        : par.cpp
// Author      : Grzegorz Gajoch
// Description : Potyczki 2014 - parking
//============================================================================


#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <ctype.h>
#include <algorithm>
#include <string>
#include <string.h>
#include <cstring>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <list>

using namespace std;

#define FOR(i,a,b) for(int i = a; i <= b; ++i)
#define FORD(i,a,b) for(int i = a; i >= b; --i)
#define REP(x, n) for(int x=0; x < (n); ++x)
#define VAR(v,i) __typeof(i) v=(i)
#define FOREACH(i,c) for(VAR(i,(c).begin());i!=(c).end();++i)
#define SIZE(n) (int)n.size()
#define ALL(c) c.begin(),c.end()
#define PB(n) push_back(n)
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef vector<vector<int> > VVI;
typedef vector<bool> VB;
#define MP make_pair
#define ST first
#define ND second
const int INF = 1000000001;

//#define DBGGG

#ifdef DBGGG
#define debug
#define dbg printf
#else
#undef debug
#define dbg //printf
#endif


int N, H, M;

//~~~~~~~~~~~~~~~~~~~~~~~~interval tree~~~~~~~~~~~~~~~~~~~~~~~~~~


const int MAX = 131072;
int A[MAX];

inline void update(int k, int val)
{
	k += M;
	A[k] = val;
	while (k > 1)
	{
		k /= 2;
		A[k] = max(A[2 * k], A[2 * k + 1]);
	}
}

inline int maxi_query(int p, int q)
{
	int tmp1 = 0, tmp2 = 0;
	if (p == q) return A[p];
	if (q < p) return -INF;
	if ((p) % 2 != 0)
	{
		tmp1 = A[p];
		++p;
	}
	if ((q) % 2 == 0)
	{
		tmp2 = A[q];
		--q;
	}
	return max(maxi_query((p / 2), (q / 2)), max(tmp1, tmp2));
}
int maxi(int p, int q)
{
	p += M;
	q += M;
	return maxi_query(p, q);
}




//~~~~~~~~~~~~~~~~~~~~~~~~interval tree~~~~~~~~~~~~~~~~~~~~~~~~~~
struct Place
{
	int pos, height, number;
	Place * pair;
	void print()
	{
		printf("(%d %d | %d %d)\n", pos, height, number);
	}
};
struct SORT_BY_NUMBER
{
	bool operator()(Place a, Place b)
	{
		if (a.number == b.number)
			return (a.pos == b.pos);
		return (a.number < b.number);
	}
};

bool SORT_BY_POSITION(Place a, Place b)
{
	if (a.pos == b.pos)
		return (a.number < b.number);
	return (a.pos < b.pos);
}

set<Place, SORT_BY_NUMBER> Set_by_number;
stack<Place> Stack;
vector<Place> begin_pos, desired_pos;
vector<int> Max_Val_before;
void read()
{
	scanf("%d %d", &N, &H);
	M = 1;
	while (M < N)
	{
		M *= 2;
	}
	Max_Val_before.resize(N + 1, 0);
	FOR(i, 0, 2 * M) A[i] = 0;
	int x1, x2, y1, y2;
	Place tmp;
	REP(x, N)
	{
		scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
		tmp.height = abs(y1 - y2);
		tmp.pos = min(x1, x2);
		tmp.number = x + 1;
		begin_pos.push_back(tmp);
	}
	REP(x, N)
	{
		scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
		tmp.height = abs(y1 - y2);
		tmp.pos = min(x1, x2);
		tmp.number = x + 1;
		desired_pos.push_back(tmp);
	}
	REP(x, N)
	{
		desired_pos[x].pair = &begin_pos[x];
	}
	sort(ALL(desired_pos), SORT_BY_POSITION);

	FOR(i, 1, N)
	{
		desired_pos[i - 1].number = i;
		desired_pos[i - 1].pair->number = i;
	}

	sort(ALL(begin_pos), SORT_BY_POSITION);

#ifdef debug
	printf("BEGIN:\n");
	for (auto x : begin_pos)
	{
		x.print();
	}
	printf("END:\n");
	for (auto x : desired_pos)
	{
		x.print();
	}
#endif
}
int main(int argc, char **argv)
{
	int Z;
	scanf("%d", &Z);
	while (Z--)
	{
		read();
		for (auto x = begin_pos.rbegin(); x != begin_pos.rend(); ++x)
			Stack.push(*x);
#ifdef debug
		printf("ON STACK\n");
		while (!Stack.empty())
		{
			Stack.top().print();
			Stack.pop();
		}
		for (auto x = begin_pos.rbegin(); x != begin_pos.rend(); ++x)
			Stack.push(*x);
		printf("\n\n\n");
#endif
		int next_to_place = 1;
		bool flag = true;
		Place top;
		while (!Stack.empty() || !Set_by_number.empty())
		{
			if (!Stack.empty())
			{
				top = Stack.top();
				update(top.number, top.height);
				dbg("updating %d pos to %d\n", top.number, top.height);
#ifdef debug
				printf("Processing: ");
				top.print();
				printf("BY_NR:\n");
				for (auto x : Set_by_number)
					x.print();
				printf("INTERVAL:\n");
				FOR(i, M, M + N + 1)
				{
					printf("val[%d] = %d\n", i - M, A[i]);
				}
#endif
			}
			if (Set_by_number.size() > 0 && Set_by_number.begin()->number == next_to_place)
			{
				//przechodzimy do nastêpnej liczby
				dbg("Trying to place: %d number\n", next_to_place);
				++next_to_place;

				auto minNr = *Set_by_number.begin();
#ifdef debug
				printf("going after ");
				minNr.print();
#endif

				dbg("OK, Trying to move: maxH = %d, top.height = %d\n", Max_Val_before[minNr.number], minNr.height);
				if (Max_Val_before[minNr.number] + minNr.height > H)
				{
					flag = false;
				}
				Set_by_number.erase(Set_by_number.begin());
			}
			else
			{
				//nie pasuje - zabieramy

				Max_Val_before[top.number] = maxi(top.number + 1, N);
#ifdef debug
				printf("erasing from stack: max val = %d |     ", Max_Val_before[top.number]);
				top.print();
#endif
				Stack.pop();
				Set_by_number.insert(top);
			}
		}
		if (flag)
			printf("TAK\n");
		else
			printf("NIE\n");


		Set_by_number.clear();
		while (!Stack.empty())
			Stack.pop();
		begin_pos.clear();
		desired_pos.clear();
		Max_Val_before.clear();
	}
}
