#include <bits/stdc++.h>
  
using namespace std;
  
#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define pb push_back
#define all(r) (r).begin(),(r).end()
#define rall(r) (r).rbegin(),(r).rend()
#define fi first
#define se second
  
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
 
const double EPS = 0.01;
const double INF = 1e12;
const double PI = acos(-1);
typedef complex<double> P;
typedef complex<double> point;
namespace std {
	bool operator < (const P& a, const P& b) {
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}
double cross(const P& a, const P& b) {
	return imag(conj(a)*b);
}
double dot(const P& a, const P& b) {
	return real(conj(a)*b);
}

struct L : public vector<P> {
	L(const P &a, const P &b) {
		push_back(a); push_back(b);
	}
};

typedef vector<P> G;
typedef vector<P> polygon;

int ccw(P a, P b, P c) {
	b -= a; c -= a;
	if (cross(b, c) > 0)   return +1;       // counter clockwise
	if (cross(b, c) < 0)   return -1;       // clockwise
	if (dot(b, c) < 0)     return +2;       // c--a--b on line
	if (norm(b) < norm(c)) return -2;       // a--b--c on line
	return 0;
}
bool intersectSP(const L &s, const P &p) {
	return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS; // triangle inequality
}
bool intersectSS(const L &s, const L &t) {
	return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 &&
			ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;
}
#define curr(P, i) P[i]
#define next(P, i) P[(i+1)%P.size()]
enum { OUT, ON, IN };
// int contains(const polygon& P, const point& p) {
// 	bool in = false;
// 	for (int i = 0; i < P.size(); ++i) {
// 		point a = curr(P,i) - p, b = next(P,i) - p;
// 		if (imag(a) > imag(b)) swap(a, b);
// 		if (imag(a) <= 0 && 0 < imag(b))
// 			if (cross(a, b) < 0) in = !in;
// 		if (cross(a, b) == 0 && dot(a, b) <= 0) return ON;
// 	}
// 	return in ? IN : OUT;
// }
int contains(const G& pol, const P& p){
	if(pol.size() < 2) return OUT;
	if(intersectSP({pol[0], pol[1]}, p)) return ON;
	bool f = cross(pol[1]-pol[0], p - pol[0]) > 0;
	for(int i = 1; i < pol.size(); i++) {
		auto& now = pol[i];
		auto& nxt = pol[(i+1) % pol.size()];
		if(intersectSP({nxt, now}, p)) return ON;
		if(f^(cross(nxt-now, p-now)>0)) return OUT;
	}
	return IN;
}


//????????´???????£???????????????????(??????????????£???????????????)
enum{NO_HIT=0, HIT, A_IN_B, B_IN_A};
int HitPol_Pol(const polygon& a, const polygon& b){
	bool f = true, hit = false;
	rep(i, a.size()){
		if(contains(b, a[i]) == OUT) f = false;
		else hit = true;
	}
	if(f) return A_IN_B;
	f = true;
	rep(i, b.size()){
		if(contains(a, b[i]) == OUT) f = false;
		else hit = true;
	}
	if(f) return B_IN_A;
	if(hit) return HIT;
	rep(i, a.size()) rep(j, b.size()){
		L la(curr(a, i), next(a, i)), lb(curr(b, j), next(b, j));
		if(intersectSS(la, lb)) return HIT;
	}
	return NO_HIT;
}
//point???theta???????????¢
point spinP(const point& p, double theta){
	return p*complex<double>(cos(theta),sin(theta));
}
point spinPExtend(const point& p, double theta, double rate){
	return p*complex<double>(rate*cos(theta),rate*sin(theta));
}

struct SCC{//O(V+E)
    static const int MAX_V = 1010;
    int V;
    vector<int> G[MAX_V], rG[MAX_V];
    vector<int> vs;
    bool used[MAX_V];
    int cmp[MAX_V];
    vector<vector<int> > res;
 
 
    SCC(int v) : V(v){};
    void add_edge(int from, int to){
        G[from].push_back(to);
        rG[to].push_back(from);
    }
 
    void dfs(int v){
        used[v] = true;
        for(int i = 0; i < G[v].size(); i++){
            if(!used[G[v][i]]) dfs(G[v][i]);
        }
        vs.push_back(v);
    }
    void rdfs(int v, int k){
        used[v] = true;
        cmp[v] = k;
        for(int i = 0; i < rG[v].size(); i++){
            if(!used[rG[v][i]]) rdfs(rG[v][i], k);
        }
    }
 
    int scc(){
        memset(used, 0, sizeof(used));
        vs.clear();
        for(int v = 0; v < V; v++){
            if(!used[v]) dfs(v);
        }
        memset(used, 0, sizeof(used));
        int k = 0;
        for(int i = vs.size() - 1; i >= 0; i--){
            if(!used[vs[i]]) rdfs(vs[i], k++);
        }
 
        res.clear();
        res.resize(k);
        for(int i = 0; i < V; i++){
            res[cmp[i]].push_back(i);
        }
        return k;
    }
};

int main(){
	int n, d;
	while(cin >> n >> d && (n+d)){
		vector<polygon> tri(n);
		rep(i, n){
			double x, y;
			rep(j, 3){
				cin >> x >> y;
				tri[i].pb({x, y});
			}
		}
		vector<polygon> pol(n);
		rep(i, n){
			double dist[3];
			rep(j, 3){
				dist[j] = abs(curr(tri[i], j)-next(tri[i], j));
			}
			rep(j, 3) {
				if(abs(dist[j] - dist[(j+1)%3])<1e-8){
					pol[i].pb(tri[i][j]);
					pol[i].pb(tri[i][(j+2)%3]);
					pol[i].pb(spinPExtend(pol[i][0]-pol[i][1], (ccw(pol[i][1], pol[i][0], tri[i][(j+1)%3])> 0)?PI/2:-PI/2, d/abs(pol[i][1]-pol[i][0]))+pol[i][1]);
					pol[i].pb(pol[i][2]+pol[i][0]-pol[i][1]);
					break;
				}
			}
		}
		SCC scc(n);
		rep(i, n) rep(j, i){
			if(HitPol_Pol(pol[i], tri[j])!=NO_HIT) scc.add_edge(i, j);
			if(HitPol_Pol(tri[i], pol[j])!=NO_HIT) scc.add_edge(j, i);
		}
		scc.scc();
		vector<int> f(scc.res.size(), 1);
		rep(i, n) rep(j, i){
			if(scc.cmp[i] == scc.cmp[j]) continue;
			if(HitPol_Pol(pol[i], tri[j])!=NO_HIT) f[scc.cmp[j]] = 0;
			else if(HitPol_Pol(tri[i], pol[j])!=NO_HIT) f[scc.cmp[i]] = 0;
		}
		cout<<accumulate(all(f), 0)<<endl;
	}
}

Measured memory_bytes: 3564