#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;
}