#include <bits/stdc++.h>
using namespace std;
const double epsilon = 1e-6;
double equal(double x, double y) {
  double delta = x - y;
  return fabs(delta) <= epsilon;
}
bool dle(double a, double b) { return a < b + epsilon; }
bool dgr(double a, double b) { return dle(b, a); }
struct point {
  double x, y;
  point() { x = y = 0; }
  point(double nx, double ny) : x(nx), y(ny) {}
  point(istream &in) { in >> x >> y; }
  double dist(point p) {
    double dx = x - p.x, dy = y - p.y;
    return sqrt(dx * dx + dy * dy);
  }
  bool operator==(point p) { return equal(x, p.x) && equal(y, p.y); }
  bool operator!=(point p) { return !operator==(p); }
  point operator+(point p) { return point(x + p.x, y + p.y); }
  point operator-() { return point(-x, -y); }
  point operator-(point p) { return point(x - p.x, y - p.y); }
  point operator*(double k) { return point(k * x, k * y); }
  double operator*(point p) { return x * p.x + y * p.y; }
  double operator^(point p) { return x * p.y - y * p.x; }
};
struct line {
  double A, B, C;
  line(point a, point b) {
    A = b.y - a.y;
    B = a.x - b.x;
    C = a.y * (b.x - a.x) - a.x * (b.y - a.y);
  }
  int side(point p) { return (A * p.x + B * p.y + C > 0) ? 1 : -1; }
  bool cross(line l, point &res) {
    double delta = A * l.B - B * l.A;
    if (equal(delta, 0)) return false;
    double deltax = -C * l.B + B * l.C;
    double deltay = -A * l.C + C * l.A;
    res = point(deltax / delta, deltay / delta);
    return true;
  }
};
struct segment {
  point a, b;
  segment(point na, point nb) : a(na), b(nb) {}
  bool cross(segment cd, point &res) {
    line abl(a, b), cdl(cd.a, cd.b);
    if (abl.side(cd.a) * abl.side(cd.b) != -1) return false;
    if (cdl.side(a) * cdl.side(b) != -1) return false;
    return abl.cross(cdl, res);
  }
  bool operator==(segment s) { return a == s.a && b == s.b; }
};
int n;
point data[110][3];
double answer;
bool compare(point a, point b) {
  return a.x + epsilon < b.x || (equal(a.x, b.x) && a.y < b.y);
}
bool inner(point p, point *tr) {
  double a = (tr[1] - tr[0]) ^ (tr[0] - p);
  double b = (tr[2] - tr[1]) ^ (tr[1] - p);
  double c = (tr[0] - tr[2]) ^ (tr[2] - p);
  if (dle(a, 0) && dle(b, 0) && dle(c, 0)) return true;
  if (dgr(a, 0) && dgr(b, 0) && dgr(c, 0)) return true;
  return false;
}
void solve(int a, int b) {
  segment seg(data[a][b], data[a][(b + 1) % 3]);
  vector<point> pts;
  pts.push_back(seg.a);
  pts.push_back(seg.b);
  for (int i = 0; i < n; i++) {
    if (i == a) continue;
    for (int j = 0; j < 3; j++) {
      segment cur(data[i][j], data[i][(j + 1) % 3]);
      if (cur == seg) continue;
      point c;
      if (seg.cross(cur, c)) pts.push_back(c);
    }
  }
  sort(pts.begin(), pts.end(), compare);
  for (int i = 0; i < (int)pts.size() - 1; i++) {
    point cur = pts[i], next = pts[i + 1], middle = (cur + next) * 0.5;
    int count = 0;
    for (int j = 0; j < n; j++) {
      if (j == a) continue;
      if (inner(middle, data[j])) count++;
    }
    if (!count) answer += cur.dist(next);
  }
}
int main() {
  cin >> n;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < 3; j++) {
      data[i][j] = point(cin);
    }
  }
  answer = 0.00;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < 3; j++) {
      solve(i, j);
    }
  }
  cout.precision(15);
  cout << fixed << answer;
  return 0;
}
