#include <bits/stdc++.h>
using namespace std;
const double EPS = 10e-11;
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 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;
  }
  inline friend VagueDouble operator-(const double d, const VagueDouble &VD) {
    return VagueDouble(d) - VD;
  }
  inline friend VagueDouble operator*(const double d, const VagueDouble &VD) {
    return VagueDouble(d) * VD;
  }
  inline friend VagueDouble 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 double to_double() { return 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 VagueDouble abs(VagueDouble VD) {
  return (VD.vd < 0) ? (-VD.vd) : VD.vd;
}
inline VagueDouble sqr(VagueDouble VD) { return VD.vd * VD.vd; }
inline VagueDouble sqr(double d) { return d * d; }
inline VagueDouble sqrt(VagueDouble VD) { return VagueDouble(sqrt(VD.vd)); }
inline bool isnan(VagueDouble VD) { return isnan(VD.vd); }
class P {
 private:
 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;
  }
  P operator-() const { return P(-x, -y); }
  P operator+(const P p) const { return P(x + p.x, y + p.y); }
  P operator-(const P p) const { return P(x - p.x, y - p.y); }
  P operator*(const double d) const { return P(x * d, y * d); }
  P operator/(const double d) const { return P(x / d, y / d); }
  bool operator<(const P &p) const {
    return (x == p.x) ? (y < p.y) : (x < p.x);
  }
  bool operator>(const P &p) const {
    return (x == p.x) ? (y > p.y) : (x > p.x);
  }
  bool operator==(const P &p) const { return (x == p.x) && (y == p.y); }
  void operator+=(const P &p) { *this = *this + p; }
  void operator-=(const P &p) { *this = *this - p; }
  void operator*=(const double &p) { *this = *this * p; }
  void operator/=(const double &p) { *this = *this / p; }
  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 dist(P p0, P p1) {
  return sqrt(sqr(p0.x - p1.x) + sqr(p0.y - p1.y));
}
inline VagueDouble area(P p0, P p1, P p2) {
  return abs((p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y)) /
         0.5;
}
inline bool isnan(P p) { return isnan(p.x); }
VagueDouble distPL(P l0, P l1, P p) {
  if (l0 == l1) return dist(l0, p);
  VagueDouble dx = l0.x - l1.x;
  VagueDouble dy = l0.y - l1.y;
  return abs(dy * (l0.x - p.x) - dx * (l0.y - p.y)) / sqrt(dx * dx + dy * dy);
}
bool onLine(P l0, P l1, P p) {
  if (l0 == l1) return l0 == 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 findCross(P a0, P a1, P b0, P b1) {
  P a = a0 - a1, b = b0 - b1, res;
  VagueDouble den = (a.x * b.y - a.y * b.x);
  if (den == 0) return P();
  res.x =
      (a.x * b.x * (a0.y - b0.y) + a.x * b.y * b0.x - a.y * b.x * a0.x) / den;
  if (res.x < min(a0.x, a1.x) || max(a0.x, a1.x) < res.x) return P();
  if (res.x < min(b0.x, b1.x) || max(b0.x, b1.x) < res.x) return P();
  res.y =
      -(a.y * b.y * (a0.x - b0.x) + a.y * b.x * b0.y - a.x * b.y * a0.y) / den;
  if (res.y < min(a0.y, a1.y) || max(a0.y, a1.y) < res.y) return P();
  if (res.y < min(b0.y, b1.y) || max(b0.y, b1.y) < res.y) return P();
  return res;
}
class Polygon {
 private:
 public:
  vector<P> points;
  Polygon() {}
  Polygon(vector<P> vec) { points = vec; }
  Polygon(int num) { points.resize(num); }
  int size() { return ((int)(points).size()); }
  P &operator[](int pos) { return points[pos]; }
  bool onPoly(P p) {
    int n = ((int)(points).size());
    for (int i = 0; i < ((int)(n)); ++i)
      if (onLine(points[i], points[(i + 1) % n], p)) return true;
    return false;
  }
  bool inPoly(P p) {
    int n = ((int)(points).size());
    if (n == 0) return false;
    if (onPoly(p)) return true;
    P right_point = p;
    for (int i = 0; i < ((int)(n)); ++i)
      right_point.x = max(right_point.x, points[i].x);
    if (right_point == p) return false;
    int cnt = 0;
    for (int i = 0; i < ((int)(n)); ++i) {
      P cross = findCross(points[i], points[(i + 1) % n], p, right_point);
      if (!isnan(cross)) cnt++;
    }
    for (int i = 0; i < ((int)(((int)(points).size()))); ++i)
      if (onLine(p, right_point, points[i])) {
        VagueDouble dy0 = points[(i - 1 + n) % n].y - p.y;
        VagueDouble dy1 = points[(i + 1 + n) % n].y - p.y;
        if (dy0 * dy1 < 0) cnt++;
      }
    return cnt % 2 == 1;
  }
  friend std::ostream &operator<<(std::ostream &os, Polygon &poly) {
    for (int i = 0; i < ((int)(((int)(poly).size()))); ++i)
      os << poly[i] << " ";
    return os;
  }
  friend std::istream &operator>>(std::istream &is, Polygon &poly) {
    for (int i = 0; i < ((int)(((int)(poly).size()))); ++i) is >> poly[i];
    return is;
  }
};
int main() {
  int n;
  cin >> n;
  vector<Polygon> base(n, Polygon(3));
  for (int i = 0; i < ((int)(n)); ++i) cin >> base[i];
  set<P> seg[10005];
  for (int i = 0; i < ((int)(((int)(base).size()))); ++i)
    for (int j = 0; j < ((int)(((int)(base[i]).size()))); ++j)
      seg[i * 3 + j].insert(base[i][(j + 0) % 3]);
  for (int i = 0; i < ((int)(((int)(base).size()))); ++i)
    for (int j = 0; j < ((int)(((int)(base[i]).size()))); ++j)
      seg[i * 3 + j].insert(base[i][(j + 1) % 3]);
  for (int i = 0; i < ((int)(((int)(base).size()))); ++i)
    for (int j = 0; j < ((int)(((int)(base[i]).size()))); ++j)
      for (int k = 0; k < ((int)(((int)(base).size()))); ++k)
        for (int l = 0; l < ((int)(((int)(base[k]).size()))); ++l) {
          if (i == k) continue;
          P cross = findCross(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);
        }
  VagueDouble res = 0.0;
  vector<P> vec[10005];
  for (int i = 0; i < ((int)(((int)(base).size()))); ++i)
    for (int j = 0; j < ((int)(((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 (int i = 0; i < ((int)(((int)(base).size()))); ++i)
    for (int j = 0; j < ((int)(((int)(base[i]).size()))); ++j)
      for (int k = 0; k < ((int)(((int)(vec[i * 3 + j]).size()) - 1)); ++k) {
        P mid = (vec[i * 3 + j][k] + vec[i * 3 + j][k + 1]) / 2.0;
        bool ok = true;
        for (int l = 0; l < ((int)(((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());
}
