#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;

struct coor {
	double x, y;
};
struct tri {
	coor p[3];
	coor rec[4];
};

int n, d;
vector<tri> v;
vector<vector<int> > edge;

const double EPS = 1e-9;
const double ERR = 1e-2;

template<class T>
T sqr(T x) {
	return x * x;
}

double dist(coor a, coor b) {
	return sqrt(sqr(a.x-b.x) + sqr(a.y-b.y));
}

double dist_lp(coor c, coor a, coor b) {
	coor v0, v1;
	v0.x = b.x - a.x; v0.y = b.y - a.y;
	v1.x = c.x - a.x; v1.y = c.y - a.y;

	if(sqr(dist(a,b)) + sqr(dist(a,c)) - sqr(dist(c,b)) > 0
			&& sqr(dist(a,b)) + sqr(dist(b,c)) - sqr(dist(c,a)) > 0) {
		double cross;
		cross = fabs(v0.x * v1.y - v0.y * v1.x);
		return cross / dist(a,b);
	}

	return min(dist(a,c), dist(b,c));
}

bool in_poly(coor p, coor poly[], int sz) {
	double sign = +0.0;
	for(int i = 0; i < sz; i++) {
		coor v0, v1;
		v0.x = poly[i].x - p.x; v0.y = poly[i].y - p.y;
		v1.x = poly[(i+1)%sz].x - p.x; v1.y = poly[(i+1)%sz].y - p.y;;

		if(i != 0 && sign * (v0.x * v1.y - v0.y * v1.x) < EPS*EPS) {
			break;
		}
		
		sign = (v0.x * v1.y - v0.y * v1.x);

		if(i == sz-1) {
			return true;
		}
	}

	for(int i = 0; i < sz; i++) {
		if(dist_lp(p,poly[i], poly[(i+1)%sz]) <= ERR + EPS) {
			return true;
		}
	}

	return false;
}

bool seg_cross(coor a, coor b, coor c, coor d) {
	coor v0, v1, v2;
	
	v0.x = a.x - c.x; v0.y = a.y - c.y;
	v1.x = b.x - c.x; v1.y = b.y - c.y;
	v2.x = d.x - c.x; v2.y = d.y - c.y;

	double s, t;
	s = (v0.x * v2.y - v0.y * v2.x) / (v0.x * v1.y - v0.y * v1.x);
	t = - (v1.x * v2.y - v1.y * v2.x) / (v0.x * v1.y - v0.y * v1.x);

	if(s + t > 1-EPS && s > -EPS && t > -EPS) {
		return true;
	}
	return false;
}

bool exist_edge(tri from, tri to) {
	for(int i = 0; i < 3; i++) {
		if(in_poly(to.p[i], from.rec, 4)) {
			return true;
		}
	}
	for(int i = 0; i < 4; i++) {
		if(in_poly(from.rec[i], to.p, 3)) {
			return true;
		}
	}

	for(int i = 0; i < 3; i++) {
		for(int j = 0; j < 4; j++) {
			if(seg_cross(to.p[i], to.p[(i+1)%3], from.rec[j], from.rec[(j+1)%4])) {
				return true;
			}
		}
	}
	return false;
}

bool visited[128];
bool touch[128];
bool path[128];

void check(int i, int s) {
	if(i != s && touch[i])
		touch[i] = false;
	if(path[i])
		return;
	visited[i] = true;
	path[i] = true;
	for(int j = 0; j < (int)edge[i].size(); j++) {
		check(edge[i][j], s);
	}
}

int main() {
	while(cin >> n >> d, n || d) {
		v.clear();
		edge.clear();
		edge.resize(n);
		for(int i = 0; i < n; i++) {
			visited[i] = touch[i] = path[i] = false;
		}
		for(int i = 0; i < n; i++) {
			tri in;
			for(int j = 0; j < 3; j++) {
				coor c;
				cin >> c.x >> c.y;
				in.p[j] = c;
			}

			for(int j = 0; j < 3; j++) {
				if(fabs(dist(in.p[(0+j)%3],in.p[(1+j)%3]) - dist(in.p[(1+j)%3], in.p[(2+j)%3])) < EPS) {
					swap(in.p[(1+j)%3], in.p[1]);
				}
			}

			coor add;
			add.x =	(in.p[1].x - in.p[0].x) + (in.p[1].x - in.p[2].x);
			add.y = (in.p[1].y - in.p[0].y) + (in.p[1].y - in.p[2].y);

			double addlen;
			addlen = sqrt(sqr(add.x) + sqr(add.y));
			add.x = add.x * d / addlen;
			add.y = add.y * d / addlen;

			in.rec[0].x = in.p[0].x; in.rec[0].y = in.p[0].y;
			in.rec[1].x = in.p[2].x; in.rec[1].y = in.p[2].y;
			in.rec[2].x = in.p[2].x + add.x; in.rec[2].y = in.p[2].y + add.y;
			in.rec[3].x = in.p[0].x + add.x; in.rec[3].y = in.p[0].y + add.y;

			v.push_back(in);
		}

		for(int i = 0; i < (int)v.size(); i++) {
			for(int j = 0; j < (int)v.size(); j++) {
				if(i != j) {
					if(exist_edge(v[i], v[j])) {
						edge[i].push_back(j);
					}
				}
			}
		}

		for(int i = 0; i < n; i++) {
			if(!visited[i]) {
				touch[i] = true;
				check(i, i);
			}
			for(int j = 0; j < 128; j++) {
				path[j] = false;
			}
		}

		int res = 0;
		for(int i = 0; i < n; i++) {
			if(touch[i])
				res++;
		}
		cout <<  res << endl;
	}
}

Measured memory_bytes: 1292