#include <bits/stdc++.h>
using namespace std;
const double EPS = 10e-11;
const double PI = acos(-1);
class VagueDouble {
 public:
  double vd;
  VagueDouble() { vd = nan(""); }
  VagueDouble(const double d) { vd = d; }
  inline VagueDouble operator-() const { return VagueDouble(-vd); }
  inline VagueDouble operator+(const VagueDouble VD) const {
    return VagueDouble(vd + VD.vd);
  }
  inline VagueDouble operator-(const VagueDouble VD) const {
    return VagueDouble(vd - VD.vd);
  }
  inline VagueDouble operator*(const VagueDouble VD) const {
    return VagueDouble(vd * VD.vd);
  }
  inline VagueDouble operator/(const VagueDouble VD) const {
    return VagueDouble(vd / VD.vd);
  }
  inline VagueDouble operator+(const double d) const {
    return VagueDouble(vd + d);
  }
  inline VagueDouble operator-(const double d) const {
    return VagueDouble(vd - d);
  }
  inline VagueDouble operator*(const double d) const {
    return VagueDouble(vd * d);
  }
  inline VagueDouble operator/(const double d) const {
    return VagueDouble(vd / d);
  }
  inline bool operator<(const VagueDouble VD) const {
    return vd + EPS < VD.vd || vd + EPS * abs(vd) < VD.vd;
  }
  inline bool operator>(const VagueDouble VD) const {
    return vd - EPS > VD.vd || vd - EPS * abs(vd) > VD.vd;
  }
  inline bool operator==(const VagueDouble VD) const {
    return !(*this < VD.vd) && !(*this > VD.vd);
  }
  inline bool operator!=(const VagueDouble VD) const {
    return (*this < VD.vd) || (*this > VD.vd);
  }
  inline bool operator<=(const VagueDouble VD) const {
    return !(*this > VD.vd);
  }
  inline bool operator>=(const VagueDouble VD) const {
    return !(*this < VD.vd);
  }
  inline bool operator<(const double d) const { return *this < VagueDouble(d); }
  inline bool operator>(const double d) const { return *this > VagueDouble(d); }
  inline bool operator==(const double d) const {
    return *this == VagueDouble(d);
  }
  inline bool operator!=(const double d) const {
    return *this != VagueDouble(d);
  }
  inline bool operator<=(const double d) const {
    return *this <= VagueDouble(d);
  }
  inline bool operator>=(const double d) const {
    return *this >= VagueDouble(d);
  }
  inline void operator+=(const VagueDouble VD) { *this = *this + VD; }
  inline void operator-=(const VagueDouble VD) { *this = *this - VD; }
  inline void operator*=(const VagueDouble VD) { *this = *this * VD; }
  inline void operator/=(const VagueDouble VD) { *this = *this / VD; }
  inline friend VagueDouble operator+(const double d, const VagueDouble &VD) {
    return VagueDouble(d + VD.vd);
  }
  inline friend VagueDouble operator-(const double d, const VagueDouble &VD) {
    return VagueDouble(d - VD.vd);
  }
  inline friend VagueDouble operator*(const double d, const VagueDouble &VD) {
    return VagueDouble(d * VD.vd);
  }
  inline friend VagueDouble operator/(const double d, const VagueDouble &VD) {
    return VagueDouble(d / VD.vd);
  }
  inline friend bool operator<(const double d, const VagueDouble &VD) {
    return VagueDouble(d) < VD;
  }
  inline friend bool operator>(const double d, const VagueDouble &VD) {
    return VagueDouble(d) > VD;
  }
  inline friend bool operator==(const double d, const VagueDouble &VD) {
    return VagueDouble(d) == VD;
  }
  inline friend bool operator<=(const double d, const VagueDouble &VD) {
    return VagueDouble(d) <= VD;
  }
  inline friend bool operator>=(const double d, const VagueDouble &VD) {
    return VagueDouble(d) >= VD;
  }
  inline friend std::ostream &operator<<(std::ostream &os,
                                         const VagueDouble VD) {
    os << VD.vd;
    return os;
  }
  inline friend std::istream &operator>>(std::istream &is, VagueDouble &VD) {
    double d;
    is >> d;
    VD = VagueDouble(d);
    return is;
  }
  inline friend VagueDouble abs(VagueDouble VD) {
    return (VD.vd < 0) ? (-VD.vd) : VD.vd;
  }
  inline friend VagueDouble sqr(VagueDouble VD) { return VD.vd * VD.vd; }
  inline friend VagueDouble sqr(double d) { return d * d; }
  inline friend VagueDouble sqrt(VagueDouble VD) {
    return VagueDouble(sqrt(VD.vd));
  }
  inline friend bool isnan(VagueDouble VD) { return isnan(VD.vd); }
  inline double to_double() { return vd; }
};
class P {
 public:
  VagueDouble x, y;
  P() {
    x = nan("");
    y = nan("");
  }
  P(double _x, double _y) {
    x = _x;
    y = _y;
  }
  P(VagueDouble _x, VagueDouble _y) {
    x = _x;
    y = _y;
  }
  inline P operator-() const { return P(-x, -y); }
  inline P operator+(const P p) const { return P(x + p.x, y + p.y); }
  inline P operator-(const P p) const { return P(x - p.x, y - p.y); }
  inline P operator*(const double d) const { return P(x * d, y * d); }
  inline P operator/(const double d) const { return P(x / d, y / d); }
  inline bool operator<(const P &p) const {
    return (x < p.x || (x == p.x && y < p.y));
  }
  inline bool operator>(const P &p) const {
    return (x > p.x || (x == p.x && y > p.y));
  }
  inline bool operator==(const P &p) const { return (x == p.x) && (y == p.y); }
  inline bool operator!=(const P &p) const { return (x != p.x) || (y != p.y); }
  inline void operator+=(const P &p) { *this = *this + p; }
  inline void operator-=(const P &p) { *this = *this - p; }
  inline void operator*=(const double &p) { *this = *this * p; }
  inline void operator/=(const double &p) { *this = *this / p; }
  inline VagueDouble operator*(const P p) const { return x * p.x + y * p.y; }
  inline VagueDouble operator^(const P p) const { return x * p.y - y * p.x; }
  friend std::ostream &operator<<(std::ostream &os, const P &p) {
    os << p.x.vd << "," << p.y.vd;
    return os;
  }
  friend std::istream &operator>>(std::istream &is, P &p) {
    double _x, _y;
    is >> _x >> _y;
    p = P(_x, _y);
    return is;
  }
  inline VagueDouble length() { return sqrt(x * x + y * y); }
  inline friend VagueDouble area(P p0, P p1, P p2) {
    return abs((p1 - p0) ^ (p2 - p0)) * 0.5;
  }
  inline friend bool isnan(P p) { return isnan(p.x); }
};
inline VagueDouble dist(P p0, P p1) {
  VagueDouble dx = abs(p0.x - p1.x);
  VagueDouble dy = abs(p0.y - p1.y);
  return sqrt(dx * dx + dy * dy);
}
VagueDouble distPL(P l0, P l1, P p) {
  if (l0 == -l1) return dist(l0, p);
  return abs((p - l0) ^ (l1 - l0)) / (l1 - l0).length();
}
VagueDouble angle(P from0, P to0, P from1, P to1) {
  P v0 = to0 - from0, v1 = to1 - from1;
  VagueDouble res = atan2(v1.y.vd, v1.x.vd) - atan2(v0.y.vd, v0.x.vd);
  for (; true; res += PI * 2.0)
    if (0 <= res) return res;
}
bool onLine(P l0, P l1, P p) {
  if (p.x < min(l0.x, l1.x) || max(l0.x, l1.x) < p.x) return false;
  if (p.y < min(l0.y, l1.y) || max(l0.y, l1.y) < p.y) return false;
  return distPL(l0, l1, p) == 0;
}
P LinePosAtX(P l0, P l1, VagueDouble x) {
  VagueDouble dx = l0.x - l1.x;
  VagueDouble dy = l0.y - l1.y;
  if (dx == 0) return P();
  VagueDouble d = 1.0 / dx;
  return P(x, x * dy * d + (l0.y - l0.x * dy * d));
}
P LinePosAtY(P l0, P l1, VagueDouble y) {
  VagueDouble dx = l0.x - l1.x;
  VagueDouble dy = l0.y - l1.y;
  if (dy == 0) return P();
  VagueDouble d = 1.0 / dy;
  return P(y * dx * d + (l0.x - l0.y * dx * d), y);
}
P findLineCross(P a0, P a1, P b0, P b1) {
  VagueDouble dx0 = a1.x - a0.x;
  VagueDouble dy0 = a1.y - a0.y;
  VagueDouble dx1 = b1.x - b0.x;
  VagueDouble dy1 = b1.y - b0.y;
  VagueDouble den = dx1 * dy0 - dy1 * dx0;
  if (den == 0) return P();
  VagueDouble da = ((a0.x - b0.x) * dy0 - (a0.y - b0.y) * dx0) / den;
  return P(b0.x + dx1 * da, b0.y + dy1 * da);
}
P findSegCross(P a0, P a1, P b0, P b1) {
  VagueDouble dx0 = a1.x - a0.x;
  VagueDouble dy0 = a1.y - a0.y;
  VagueDouble dx1 = b1.x - b0.x;
  VagueDouble dy1 = b1.y - b0.y;
  VagueDouble den = dx1 * dy0 - dy1 * dx0;
  if (den == 0) return P();
  VagueDouble da = ((a0.x - b0.x) * dy0 - (a0.y - b0.y) * dx0) / den;
  if (da < 0 || 1 < da) return P();
  P res = P(b0.x + dx1 * da, b0.y + dy1 * da);
  if (res.x < min(a0.x, a1.x) || max(a0.x, a1.x) < res.x) return P();
  if (res.y < min(a0.y, a1.y) || max(a0.y, a1.y) < res.y) return P();
  return res;
}
class Polygon {
 public:
  vector<P> points;
  Polygon() {}
  Polygon(vector<P> vec) { points = vec; }
  Polygon(long long int num) { points.resize(num); }
  friend std::ostream &operator<<(std::ostream &os, Polygon &poly) {
    for (long long int i = 0;
         i < ((long long int)(((long long int)(poly).size()))); ++i)
      os << poly[i] << " ";
    return os;
  }
  friend std::istream &operator>>(std::istream &is, Polygon &poly) {
    for (long long int i = 0;
         i < ((long long int)(((long long int)(poly).size()))); ++i)
      is >> poly[i];
    return is;
  }
  long long int size() { return ((long long int)(points).size()); }
  P &operator[](long long int pos) { return points[pos]; }
  bool onPoly(P p) {
    long long int n = ((long long int)(points).size());
    if (n == 0) return false;
    if (onLine(points[n - 1], points[0], p)) return true;
    for (long long int i = 0; i < ((long long int)(n - 1)); ++i)
      if (onLine(points[i], points[i + 1], p)) return true;
    return false;
  }
  bool inPoly(P p) {
    long long int n = ((long long int)(points).size()), cnt = 0;
    if (n == 0) return false;
    P right_point = p;
    for (long long int i = 0; i < ((long long int)(n)); ++i)
      right_point.x = max(right_point.x, points[i].x);
    if (right_point == p) return false;
    for (long long int i = 0, next = 1; i < n; i++, next++) {
      if (next == n) next = 0;
      if (0 < (points[i].y - p.y) * (points[next].y - p.y)) continue;
      P cross = findSegCross(points[i], points[next], p, right_point);
      if (isnan(cross)) continue;
      cnt++;
      if (cross == p) return true;
      if (points[i].y == p.y && onLine(p, right_point, points[i])) {
        long long int prev = (i == 0) ? (n - 1) : (i - 1);
        VagueDouble dy0 = points[prev].y - p.y;
        VagueDouble dy1 = points[next].y - p.y;
        if (dy0 * dy1 < 0) cnt++;
      }
    }
    return (cnt & 1);
  }
  bool outPoly(P p) { return !inPoly(p); }
  void convexReform() {
    long long int k = 0;
    if (((long long int)(points).size()) <= 1) return;
    sort(points.begin(), points.end());
    vector<P> ans(2 * ((long long int)(points).size()));
    for (long long int i = 0; i < ((long long int)(points).size());
         ans[k++] = points[i++]) {
      while (2 <= k &&
             0 <= ((ans[k - 1] - ans[k - 2]) ^ (points[i] - ans[k - 2])))
        k--;
    }
    for (long long int i = ((long long int)(points).size()) - 2, t = k + 1;
         0 <= i; ans[k++] = points[i--]) {
      while (t <= k &&
             0 <= ((ans[k - 1] - ans[k - 2]) ^ (points[i] - ans[k - 2])))
        k--;
    }
    ans.resize(k - 1);
    points = ans;
  }
  VagueDouble convexArea() {
    VagueDouble res = 0;
    for (long long int i = 0;
         i < ((long long int)(((long long int)(points).size()) - 1)); ++i)
      res += area(points[0], points[i], points[i + 1]);
    return res;
  }
};
class Circle {
 public:
  P center;
  VagueDouble radius;
  Circle(P _center, VagueDouble _r) {
    center = _center;
    radius = _r;
  };
  Circle(P p0, P p1, P p2) {
    if (p0 == p1) {
      center = (p0 + p2) * 0.5;
      radius = dist(p0, p2) * 0.5;
      return;
    }
    if (p0 == p2) {
      center = (p0 + p1) * 0.5;
      radius = dist(p0, p2) * 0.5;
      return;
    }
    if (p1 == p2) {
      center = (p0 + p2) * 0.5;
      radius = dist(p0, p2) * 0.5;
      return;
    }
    P mid0 = (p0 + p1) * 0.5;
    P mid1 = (p0 + p2) * 0.5;
    P _mid0 = mid0 + P((p1 - p0).y, (p0 - p1).x);
    P _mid1 = mid1 + P((p2 - p0).y, (p0 - p2).x);
    center = findLineCross(mid0, _mid0, mid1, _mid1);
    radius = dist(center, p0);
  }
};
int main() {
  long long int n;
  cin >> n;
  vector<Polygon> base(n, Polygon(3));
  for (long long int i = 0; i < ((long long int)(n)); ++i) cin >> base[i];
  set<P> seg[10005];
  for (long long int i = 0;
       i < ((long long int)(((long long int)(base).size()))); ++i)
    for (long long int j = 0;
         j < ((long long int)(((long long int)(base[i]).size()))); ++j)
      seg[i * 3 + j].insert(base[i][(j + 0) % 3]);
  for (long long int i = 0;
       i < ((long long int)(((long long int)(base).size()))); ++i)
    for (long long int j = 0;
         j < ((long long int)(((long long int)(base[i]).size()))); ++j)
      seg[i * 3 + j].insert(base[i][(j + 1) % 3]);
  for (long long int i = 0;
       i < ((long long int)(((long long int)(base).size()))); ++i)
    for (long long int j = 0;
         j < ((long long int)(((long long int)(base[i]).size()))); ++j)
      for (long long int k = 0; k < ((long long int)(i)); ++k)
        for (long long int l = 0;
             l < ((long long int)(((long long int)(base[k]).size()))); ++l) {
          if (i == k) continue;
          P cross = findSegCross(base[i][j], base[i][(j + 1) % 3], base[k][l],
                                 base[k][(l + 1) % 3]);
          if (isnan(cross)) continue;
          seg[i * 3 + j].insert(cross);
          seg[k * 3 + l].insert(cross);
        }
  VagueDouble res = 0.0;
  vector<P> vec[10005];
  for (long long int i = 0;
       i < ((long long int)(((long long int)(base).size()))); ++i)
    for (long long int j = 0;
         j < ((long long int)(((long long int)(base[i]).size()))); ++j)
      for (__typeof((seg[i * 3 + j]).begin()) it = (seg[i * 3 + j]).begin();
           it != (seg[i * 3 + j]).end(); it++)
        vec[i * 3 + j].push_back(*it);
  for (long long int i = 0;
       i < ((long long int)(((long long int)(base).size()))); ++i)
    for (long long int j = 0;
         j < ((long long int)(((long long int)(base[i]).size()))); ++j)
      for (long long int k = 0;
           k < ((long long int)(((long long int)(vec[i * 3 + j]).size()) - 1));
           ++k) {
        P mid = (vec[i * 3 + j][k] + vec[i * 3 + j][k + 1]) * 0.5;
        bool ok = true;
        for (long long int l = 0;
             l < ((long long int)(((long long int)(base).size()))); ++l)
          if (i != l && base[l].inPoly(mid)) {
            ok = false;
            break;
          }
        if (ok) res += dist(vec[i * 3 + j][k], vec[i * 3 + j][k + 1]);
      }
  printf("%0.20lf\n", res.to_double());
}
