← Home
#include <algorithm>
#include <cmath>
#include <iostream>
#include <numeric>
#include <set>
#include <vector>
 
#define EPS 1e-8
 
struct Point {
	double x, y;
 
	Point() {}
	Point(double x, double y) : x(x), y(y) {}
 
	double abs() const                     { return std::hypot(x, y); }
	Point  scale(double o) const           { return *this * (o / abs()); }
	Point  rotl() const                    { return {-y, x}; }
	Point  rotr() const                    { return {y, -x}; }
 
	Point operator*(double o) const        { return {x * o, y * o}; }
	Point operator+(const Point& o) const  { return {x + o.x, y + o.y}; }
	Point operator-(const Point& o) const  { return {x - o.x, y - o.y}; }
	bool  operator<(const Point& o) const  { return x < o.x - EPS || (x < o.x + EPS && y < o.y - EPS); }
};
 
void solve(Point a, Point b, double da, double db, std::vector<Point>& ret) {
	double sum = (b - a).abs();
	double dif = (da * da - db * db) / sum;
	double ra = (sum + dif) / 2;
	double rb = (sum - dif) / 2;
	double h = da * da - ra * ra;
 
	if (h < -EPS)
		return;
	else
		h = std::sqrt(std::max(0.0, h));
 
	Point v = (b - a).scale(h);
 
	ret.push_back(a + (b - a).scale(ra) + v.rotl());
	ret.push_back(a + (b - a).scale(ra) + v.rotr());
	ret.push_back(a + (b - a).scale(rb) + v.rotl());
	ret.push_back(a + (b - a).scale(rb) + v.rotr());
}
 
int main() {
	double e[4];
	double t[4][3];
	std::vector<Point> v;
 
	for (int i = 0; i < 4; ++i) {
		Point p[3];
		for (int j = 0; j < 3; ++j)
			std::cin >> p[j].x >> p[j].y;
 
		t[i][0] = (p[1] - p[0]).abs();
		t[i][1] = (p[2] - p[1]).abs();
		t[i][2] = (p[0] - p[2]).abs();
 
		std::sort(t[i], &t[i][3]);
	}
 
	int ans = 9;
	for (int i = 0; i < 81; ++i) {
		for (int j = 0, k = i; j < 4; ++j, k /= 3)
			e[j] = t[j][k % 3];
 
		if (*std::max_element(e, e + 4) * 2 - std::accumulate(e, e + 4, 0.0) < EPS) {
			ans = 8;
			break;
		}
	}
 
	for (int i = 0; i < 12; ++i) {
		for (int j = (i / 3 + 1) * 3; j < 12; ++j) {
			for (int k = (j / 3 + 1) * 3; k < 12; ++k) {
				Point a = {0, 0};
				Point b = {t[i / 3][i % 3], 0};
 
				v.clear();
				solve(a, b, t[j / 3][j % 3], t[k / 3][k % 3], v);
 
				if (v.empty())
					continue;
 
				Point c = v[0];
				std::vector<Point> va;
				std::vector<Point> vb;
				std::vector<Point> vc;
 
				solve(a, b, t[i / 3][(i + 1) % 3], t[i / 3][(i + 2) % 3], va);
				solve(a, c, t[j / 3][(j + 1) % 3], t[j / 3][(j + 2) % 3], vb);
				solve(b, c, t[k / 3][(k + 1) % 3], t[k / 3][(k + 2) % 3], vc);
 
				for (auto pa : va) {
					for (auto pb : vb) {
						for (auto pc : vc) {
							std::set<Point> st = {a, b, c, pa, pb, pc};
							ans = std::min(ans, (int)st.size() + 2);
							for (int l = 0; l < 12; ++l) {
								if (i / 3 + j / 3 + k / 3 + l / 3 != 6)
									continue;
 
								for (auto u : st) {
									for (auto v : st) {
										if (std::abs((u - v).abs() - t[l / 3][l % 3]) > EPS)
											continue;
 
										std::vector<Point> vd;
										solve(u, v, t[l / 3][(l + 1) % 3], t[l / 3][(l + 2) % 3], vd);
 
										for (auto pd : vd)
											ans = std::min(ans, (int)st.size() + 1 - (int)st.count(pd));
									}
								}
							}
						}
					}
				}
			}
		}
	}
 
	int tmp = 3;
	for (int i = 1; i < 4; ++i) {
		int acc = 2;
		for (int j = 0; j < i; ++j) {
			bool same = true;
			for (int k = 0; k < 3 && same; ++k)
				same &= std::abs(t[i][k] - t[j][k]) < EPS;
 
			if (same) {
				acc = 0;
				break;
			}
		}
 
		for (int j = 0; j < 3 * i && acc > 1; ++j) {
			for (int k = 0; k < 3; ++k) {
				if (std::abs(t[j / 3][j % 3] - t[i][k]) < EPS) {
					acc = 1;
					break;
				}
			}
		}
 
		tmp += acc;
	}
 
	ans = std::min(ans, tmp);
	std::cout << ans << '\n';
 
	return 0;
}