#include <bits/stdc++.h>
using namespace std;
struct point {
  double x, y;
};
struct tri {
  point p[3];
};
tri tris[110];
const double E = 1e-9;
point segl[1000][2];
int cnt;
int posi[10000];
inline int dblcmp(double x) {
  if (x > -E && x < E) return 0;
  return x > 0 ? 1 : -1;
}
double CP(point &p1, point &p2, point &p3) {
  return (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);
}
bool bline(point &p1, point &p2, point &p3) {
  return dblcmp(p3.x - min(p1.x, p2.x)) >= 0 &&
         dblcmp(p3.x - max(p1.x, p2.x)) <= 0 &&
         dblcmp(p3.y - min(p1.y, p2.y)) >= 0 &&
         dblcmp(p3.y - max(p1.y, p2.y)) <= 0;
}
bool cross(point &p1, point &p2, point &p3, point &p4, point &p) {
  double d1 = CP(p1, p2, p3), d2 = CP(p1, p2, p4), d3 = CP(p3, p4, p1),
         d4 = CP(p3, p4, p2);
  if (dblcmp(d1 * d2) < 0 && dblcmp(d3 * d4) < 0) {
    p.x = (d1 * p4.x - d2 * p3.x) / (d1 - d2);
    p.y = (d1 * p4.y - d2 * p3.y) / (d1 - d2);
    return true;
  }
  if (dblcmp(d1) == 0 && bline(p1, p2, p3)) {
    p = p3;
    return true;
  }
  if (dblcmp(d2) == 0 && bline(p1, p2, p4)) {
    p = p4;
    return true;
  }
  if (dblcmp(d3) == 0 && bline(p3, p4, p1)) {
    p = p1;
    return true;
  }
  if (dblcmp(d4) == 0 && bline(p3, p4, p2)) {
    p = p2;
    return true;
  }
  return false;
}
bool cmp(const point &cmp1, const point &cmp2) {
  if (dblcmp(cmp1.x - cmp2.x) == 0) return cmp1.y < cmp2.y;
  return cmp1.x < cmp2.x;
}
bool intri(point &p, tri &tr) {
  point p1, p2;
  int cc1 = 0, cc2 = 0;
  for (int i = 0; i < 3; i++) {
    p1 = tr.p[i];
    p2 = tr.p[(i + 1) % 3];
    if (dblcmp(CP(p1, p2, p)) > 0) {
      cc1++;
    }
    if (dblcmp(CP(p1, p2, p)) < 0) {
      cc2++;
    }
  }
  if (!cc1 || !cc2) return true;
  return false;
}
double gdis(point &p1, point &p2) {
  return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
bool cmp2(const int cmp1, const int cmp2) {
  return cmp(segl[cmp1][0], segl[cmp2][0]);
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < 3; j++) {
      scanf("%lf%lf", &tris[i].p[j].x, &tris[i].p[j].y);
    }
  }
  point p1, p2, p3, p4, p01, p02;
  double ans = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < 3; j++) {
      p1 = tris[i].p[j];
      p2 = tris[i].p[(j + 1) % 3];
      cnt = 0;
      bool ok = true;
      for (int a = 0; a < n; a++) {
        if (a != i) {
          if (intri(p1, tris[a]) && intri(p2, tris[a])) {
            ok = false;
            break;
          }
          for (int k = 0; k < 3; k++) {
            p3 = tris[a].p[k];
            p4 = tris[a].p[(k + 1) % 3];
            bool ok1 = false, ok2 = false;
            if (cross(p3, p4, p1, p2, p01)) {
              ok1 = true;
            }
            p3 = tris[a].p[(k + 1) % 3];
            p4 = tris[a].p[(k + 2) % 3];
            if (cross(p3, p4, p1, p2, p02)) {
              ok2 = true;
            }
            if (ok1 && ok2) {
              if (cmp(p01, p02)) {
                segl[cnt][0] = p01;
                segl[cnt][1] = p02;
              } else {
                segl[cnt][0] = p02;
                segl[cnt][1] = p01;
              }
              cnt++;
            } else if (ok1) {
              if (intri(p1, tris[a])) {
                segl[cnt][0] = min(p1, p01, cmp);
                segl[cnt][1] = max(p01, p1, cmp);
                cnt++;
              }
              if (intri(p2, tris[a])) {
                segl[cnt][0] = min(p2, p01, cmp);
                segl[cnt][1] = max(p01, p2, cmp);
                cnt++;
              }
            } else if (ok2) {
              if (intri(p1, tris[a])) {
                segl[cnt][0] = min(p1, p02, cmp);
                segl[cnt][1] = max(p02, p1, cmp);
                cnt++;
              }
              if (intri(p2, tris[a])) {
                segl[cnt][0] = min(p2, p02, cmp);
                segl[cnt][1] = max(p02, p2, cmp);
                cnt++;
              }
            }
          }
        }
      }
      if (ok) {
        point lp = min(p1, p2, cmp);
        point rp = max(p1, p2, cmp);
        for (int a = 0; a < cnt; a++) {
          posi[a] = a;
        }
        sort(posi, posi + cnt, cmp2);
        if (cnt > 0) {
          ans += gdis(segl[posi[0]][0], lp);
          point right = segl[posi[0]][1];
          for (int a = 1; a < cnt; a++) {
            if (!cmp(right, segl[posi[a]][0])) {
              if (cmp(right, segl[posi[a]][1])) {
                right = segl[posi[a]][1];
              }
            } else {
              ans += gdis(segl[posi[a]][0], right);
              right = segl[posi[a]][1];
            }
          }
          ans += gdis(rp, right);
        } else {
          ans += gdis(lp, rp);
        }
      }
    }
  }
  printf("%.10lf\n", ans);
  return 0;
}
