#include <cstdio>
#include <iostream>
#include <cmath>
#include <complex>
#include <algorithm>
#include <utility>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

#define EPS 0.01

typedef complex<double> point;
typedef const point &refpoint;


int n;
vector<vector<point> > trgs, sqrs;
vector<int> to[100], rto[100];
vector<int> vs;
bool used[100];
int cmp[100];


double dot(refpoint a, refpoint b){
	return real(a) * real(b) + imag(a) * imag(b);
}

double cross(refpoint a, refpoint b){
	return real(a) * imag(b) - imag(a) * real(b);
}

double distance_l_p(refpoint a, refpoint b, refpoint c){
	return abs(cross(b - a, c - a)) / abs(b - a);
}

double distance_ls_p(refpoint a, refpoint b, refpoint c){
	if( dot(b - a, c - a) <= 0.0 ) return abs(c - a);
	if( dot(a - b, c - b) <= 0.0 ) return abs(c - b);
	return distance_l_p(a, b, c);
}

bool contains(const vector<point> &plg, refpoint pts){
	int cnt = 0;
	double y = imag(pts);

	for(int i = 0; i < plg.size(); ++i){
		int j = (i + 1 == plg.size() ? 0: i + 1);

		if( distance_ls_p(plg[i], plg[j], pts) <= EPS ){
			return true;
		}

		double dyi = imag(plg[i]) - y;
		double dyj = y - imag(plg[j]);
		double tx = (dyi * real(plg[j]) + dyj * real(plg[i])) / (dyi + dyj);

		if(imag(plg[i]) >= y && imag(plg[j]) < y){
			if( tx < real(pts) ) ++cnt;
		}
		else if(imag(plg[i]) < y && imag(plg[j]) >= y){
			if( tx < real(pts) ) --cnt;
		}
	}
	
	return (cnt % 2 != 0);
}

bool contact(const vector<point> &plg1, const vector<point> &plg2){
	for(int i = 0; i < plg1.size(); ++i){
		if( contains(plg2, plg1[i]) ) return true;
	}
	for(int i = 0; i < plg2.size(); ++i){
		if( contains(plg1, plg2[i]) ) return true;
	}
	return false;
}

vector<point> square(const vector<point> &trg, double d){
	vector<point> ret(4);

	double norms[3];
	for(int i = 0; i < 3; ++i){
		norms[i] = norm(trg[i] - trg[(i + 1) % 3]);
	}

	int idx = 2;
	for(int i = 1; i < 3; ++i){
		if(norms[0] == norms[i]){
			idx = 2 - i;
			break;
		}
	}

	int other0 = (idx + 1) % 3;
	int other1 = (idx + 2) % 3;
	
	ret[0] = trg[other0];
	ret[1] = trg[other1];
	
	point dif = polar(d, arg(ret[1] - ret[0]) + asin(1.0));

	if( cross(ret[1] - ret[0], trg[idx] - ret[0]) >= 0.0 ){
		ret[2] = ret[1] + dif;
		ret[3] = ret[0] + dif;
	}
	else{
		ret[2] = ret[1] - dif;
		ret[3] = ret[0] - dif;
	}

	return ret;
}

void dfs(int v){
	used[v] = true;
	for(int i = 0; i < to[v].size(); ++i){
		if( !used[ to[v][i] ] )	dfs( to[v][i] );
	}
	vs.push_back(v);
}

void rdfs(int v, int k){
	used[v] = true;
	cmp[v] = k;

	for(int i = 0; i < rto[v].size(); ++i){
		if( !used[ rto[v][i] ] ) rdfs( rto[v][i], k );
	}
}

int scc(){
	vs.clear();
	
	for(int v = 0; v < n; ++v){
		if( !used[v] ) dfs(v);
	}

	memset(used, 0, 100);
	int k = 0;
	for(int i = vs.size() - 1; i >= 0; --i){
		if( !used[ vs[i] ] ) rdfs(vs[i], k++);
	}
	return k;
}

int solve(){
	for(int i = 0; i < n; ++i){
		to[i].clear();
		rto[i].clear();
		used[i] = false;
		cmp[i] = 0;
	}

	for(int i = 0; i < n; ++i){
		for(int j = 0; j < n; ++j){
			if( i != j && contact(sqrs[i], trgs[j]) ){
				to[i].push_back(j);
				rto[j].push_back(i);
			}
		}
	}

	int k = scc();
	vector<int> rcount(k);

	for(int i = 0; i < n; ++i){
		for(int j = 0; j < to[i].size(); ++j){
			if( cmp[i] != cmp[ to[i][j] ] ){
				++rcount[ cmp[ to[i][j] ] ];
			}
		}
	}

	int ret = 0;
	for(int i = 0; i < k; ++i){
		if( rcount[i] == 0 ) ++ret;
	}

	return ret;
}


int main(){
	vector<point> trg(3);
	trgs.reserve(100);
	sqrs.reserve(100);

	int x, y;
	double d;
	for( ; scanf("%d%lf", &n, &d), n; ){
		trgs.clear();
		sqrs.clear();

		for(int i = 0; i < n; ++i){
			for(int j = 0; j < 3; ++j){
				scanf("%d%d", &x, &y);
				trg[j] = point(x, y);
			}

			trgs.push_back(trg);
			sqrs.push_back( square(trg, d) );
		}

		printf("%d\n", solve() );
	}
}

Measured memory_bytes: 1320