#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:10000000")
const long double LDINF = 9128739847123.00;
const long double eps = 1e-9;
const int INF = 1 << 30;
const long double pi = fabsl(atan2(0.0, -1.0));
using namespace std;
class Point {
 public:
  long double x, y;
  void Rotate(long double ang) {
    long double _x = x * cos(ang) - y * sin(ang);
    long double _y = y * cos(ang) + sin(ang) * x;
    x = _x;
    y = _y;
  }
};
inline bool operator<(const Point &p1, const Point &p2) {
  return p1.x < p2.x - eps || fabsl(p1.x - p2.x) < eps && p1.y < p2.y - eps;
}
Point operator*(const Point &p1, long double t) {
  Point p;
  p.x = p1.x * t;
  p.y = p1.y * t;
  return p;
}
Point operator+(const Point &p1, const Point &p2) {
  Point p;
  p.x = p1.x + p2.x;
  p.y = p1.y + p2.y;
  return p;
}
int n;
Point p[1000][4];
vector<long double> xs;
void Load() {
  cin >> n;
  int i;
  for (i = 0; i < n; i++) {
    for (int j = 0; j < 3; j++) {
      cin >> p[i][j].x >> p[i][j].y;
      p[i][j].Rotate(123);
    }
  }
}
bool OnSegment(const Point &p1, const Point &p2, const Point &p3) {
  return (p3.x > min(p1.x, p2.x) - eps && p3.x < max(p1.x, p2.x) + eps &&
          p3.y > min(p1.y, p2.y) - eps && p3.y < max(p1.y, p2.y) + eps);
}
int Intersect(const Point &p1, const Point &p2, const Point &p3,
              const Point &p4, Point &P) {
  long double A1 = p1.y - p2.y;
  long double B1 = p2.x - p1.x;
  long double C1 = -(A1 * p1.x + B1 * p1.y);
  long double A2 = p3.y - p4.y;
  long double B2 = p4.x - p3.x;
  long double C2 = -(A2 * p3.x + B2 * p3.y);
  if (fabs(A1 * B2 - A2 * B1) < eps) return 0;
  P.x = (-C1 * B2 + B1 * C2) / (A1 * B2 - A2 * B1);
  P.y = (-C2 * A1 + A2 * C1) / (A1 * B2 - A2 * B1);
  if (OnSegment(p1, p2, P) && OnSegment(p3, p4, P)) return 1;
  return 0;
}
class Segment {
 public:
  Point p, v;
  int type;
  Segment() {}
  Segment(Point p1, Point p2) {
    p = p1;
    v.x = p2.x - p1.x;
    v.y = p2.y - p1.y;
  }
};
ostream &operator<<(ostream &oss, const Segment &s) {
  oss << "point " << s.p.x << " " << s.p.y << " vect  " << s.v.x << " " << s.v.y
      << " type " << s.type;
  return oss;
}
long double X;
vector<Segment> all;
inline bool operator<(const Segment &s1, const Segment &s2) {
  return s1.p + s1.v * ((X - s1.p.x) / s1.v.x) <
             s2.p + s2.v * ((X - s2.p.x) / s2.v.x) ||
         fabsl((s1.p + s1.v * ((X - s1.p.x) / s1.v.x)).y -
               (s2.p + s2.v * ((X - s2.p.x) / s2.v.x)).y) < eps &&
             s1.type < s2.type;
}
inline bool Intersect(Segment &s1, long double x1, long double x2) {
  long double a = min(s1.p.x, s1.p.x + s1.v.x);
  long double b = max(s1.p.x, s1.p.x + s1.v.x);
  return x1 > a - eps && x2 < b + eps;
}
inline long double getLen(Segment &s, long double x1, long double x2) {
  long double t1 = min((x1 - s.p.x) / s.v.x, (x2 - s.p.x) / s.v.x);
  long double t2 = max((x2 - s.p.x) / s.v.x, (x1 - s.p.x) / s.v.x);
  return (t2 - t1) * sqrt(s.v.x * s.v.x + s.v.y * s.v.y);
}
void Solve() {
  int i, j;
  Point P;
  for (i = 0; i < n; i++) {
    for (j = 0; j < 3; j++) xs.push_back(p[i][j].x);
    for (j = i + 1; j < n; j++) {
      for (int l = 0; l < 3; l++) {
        for (int o = 0; o < 3; o++) {
          if (Intersect(p[i][l], p[i][(l + 1) % 3], p[j][o], p[j][(o + 1) % 3],
                        P)) {
            xs.push_back(P.x);
          }
        }
      }
    }
  }
  sort(xs.begin(), xs.end());
  xs.erase(unique(xs.begin(), xs.end()), xs.end());
  Segment s[3], up, dwn;
  long double res = 0;
  for (i = 0; i + 1 < xs.size(); i++) {
    all.resize(0);
    X = (xs[i + 1] + xs[i]) / 2.0;
    for (j = 0; j < n; j++) {
      s[0] = Segment(p[j][0], p[j][1]);
      s[1] = Segment(p[j][1], p[j][2]);
      s[2] = Segment(p[j][2], p[j][0]);
      int l;
      for (l = 0; l < 3; l++) {
        if (Intersect(s[l], xs[i], xs[i + 1])) break;
      }
      if (l == 3) continue;
      up = s[l];
      dwn = s[l];
      up.type = dwn.type = 0;
      for (int l = 0; l < 3; l++) {
        s[l].type = 0;
        if (Intersect(s[l], xs[i], xs[i + 1])) {
          if (up < s[l]) up = s[l];
          if (s[l] < dwn) dwn = s[l];
        }
      }
      up.type = 1;
      dwn.type = 0;
      all.push_back(up);
      all.push_back(dwn);
    }
    sort(all.begin(), all.end());
    int bal = 0;
    for (j = 0; j < all.size(); j++) {
      if (all[j].type == 0) {
        bal++;
        if (bal == 1) {
          res += getLen(all[j], xs[i], xs[i + 1]);
        }
      } else if (all[j].type == 1) {
        bal--;
        if (bal == 0) {
          res += getLen(all[j], xs[i], xs[i + 1]);
        }
      }
    }
  }
  cout << setprecision(12) << fixed << res;
}
int main() {
  Load();
  Solve();
  return 0;
}
