import java.io.*;
import java.util.*;

public class greatwall_mb_geomcheck {
    private static class Segment {
        private final int x1, y1, x2, y2;
        public Segment(int x1, int y1, int x2, int y2) {
            if (x1 > x2 || x1 == x2 && y1 > y2) {
                this.x1 = x2;
                this.y1 = y2;
                this.x2 = x1;
                this.y2 = y1;
            } else {
                this.x1 = x1;
                this.y1 = y1;
                this.x2 = x2;
                this.y2 = y2;
            }
        }
        public int hashCode() {
            int rv = 117;
            rv = 31 * rv + x1;
            rv = 31 * rv + y1;
            rv = 31 * rv + x2;
            rv = 31 * rv + y2;
            return rv;
        }
        public boolean equals(Object o) {
            if (o instanceof Segment) {
                Segment s = (Segment) o;
                return x1 == s.x1 && y1 == s.y1 && x2 == s.x2 && y2 == s.y2;
            } else {
                return false;
            }
        }
        public boolean intersects(Segment that) {
            if (Math.max(x1, x2) < Math.min(that.x1, that.x2)) return false;
            if (Math.max(y1, y2) < Math.min(that.y1, that.y2)) return false;
            if (Math.min(x1, x2) > Math.max(that.x1, that.x2)) return false;
            if (Math.min(y1, y2) > Math.max(that.y1, that.y2)) return false;
            int vmul00 = Integer.signum((that.x1 - x1) * (y2 - y1) - (that.y1 - y1) * (x2 - x1));
            int vmul01 = Integer.signum((that.x2 - x1) * (y2 - y1) - (that.y2 - y1) * (x2 - x1));
            int vmul10 = Integer.signum((x1 - that.x1) * (that.y2 - that.y1) - (y1 - that.y1) * (that.x2 - that.x1));
            int vmul11 = Integer.signum((x2 - that.x1) * (that.y2 - that.y1) - (y2 - that.y1) * (that.x2 - that.x1));
            return vmul00 * vmul01 <= 0 && vmul10 * vmul11 <= 0;
        }
    }

    private static class Point {
        public final int x, y;
        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
        public int hashCode() {
            return 31 * x + 239 * y;
        }
        public boolean equals(Object o) {
            if (o instanceof Point) {
                Point p = (Point) o;
                return x == p.x && y == p.y;
            } else {
                return false;
            }
        }
    }

    private static void myAssert(String msg, boolean exp) {
        if (!exp) {
            throw new AssertionError(msg);
        }
    }

    private static int gcd(int a, int b) {
        a = Math.abs(a);
        b = Math.abs(b);
        while (b != 0) {
            int t = a % b;
            a = b;
            b = t;
        }
        return a;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new FileReader("greatwall.in"));
        int m = Integer.parseInt(in.readLine());
        myAssert("m is out of bounds", 1 <= m && m <= 1000);
        Map<Segment, Integer> set = new HashMap<Segment, Integer>();
        Set<Point> points = new HashSet<Point>();
        int[] x = new int[3];
        int[] y = new int[3];
        for (int line = 0; line < m; ++line) {
            StringTokenizer st = new StringTokenizer(in.readLine());
            myAssert("Line #" + (line + 2) + " is incorrectly formatted", st.countTokens() == 6);
            for (int i = 0; i < 3; ++i) {
                x[i] = Integer.parseInt(st.nextToken());
                y[i] = Integer.parseInt(st.nextToken());
                myAssert("x is out of bounds", -10000 <= x[i] && x[i] <= 10000);
                myAssert("y is out of bounds", -10000 <= y[i] && y[i] <= 10000);
                points.add(new Point(x[i], y[i]));
            }
            for (int i = 0; i < 3; ++i) {
                int j = (i + 1) % 3;
                Segment s = new Segment(x[i], y[i], x[j], y[j]);
                if (set.containsKey(s)) {
                    set.put(s, set.get(s) + 1);
                } else {
                    set.put(s, 1);
                }
            }
        }

        //This code is for input verification only.
        {
            List<Point> pts = new ArrayList<Point>(points);
            //Collinearity check
            for (int i = 0; i < pts.size(); ++i) {
                Set<Point> vectors = new HashSet<Point>();
                for (int j = i + 1; j < pts.size(); ++j) {
                    int dx = pts.get(i).x - pts.get(j).x;
                    int dy = pts.get(i).y - pts.get(j).y;
                    int gcd = gcd(dx, dy);
                    dx /= gcd;
                    dy /= gcd;
                    Point diff = new Point(dx, dy);
                    myAssert("Collinear points detected", !vectors.contains(diff));
                    vectors.add(diff);
                }
            }
            for (Iterator<Map.Entry<Segment, Integer>> it = set.entrySet().iterator(); it.hasNext(); ) {
                int count = it.next().getValue();
                myAssert("a segment is presented more than two times", count <= 2);
                if (count > 1) {
                    it.remove();
                }
            }
            //Computing vertex-edge graph.
            List<Segment> segments = new ArrayList<Segment>(set.keySet());
            Map<Point, List<Segment>> pointGraph = new HashMap<Point, List<Segment>>();
            for (Segment s : segments) {
                Point p1 = new Point(s.x1, s.y1);
                Point p2 = new Point(s.x2, s.y2);
                List<Segment> q1 = pointGraph.get(p1);
                if (q1 == null) {
                    pointGraph.put(p1, q1 = new ArrayList<Segment>());
                }
                q1.add(s);
                List<Segment> q2 = pointGraph.get(p2);
                if (q2 == null) {
                    pointGraph.put(p2, q2 = new ArrayList<Segment>());
                }
                q2.add(s);
            }
            for (List<Segment> i : pointGraph.values()) {
                myAssert("The resulting border graph is not a circle", i.size() == 2);
            }
            Map<Segment, List<Segment>> adjacent = new HashMap<Segment, List<Segment>>();
            for (Segment s : segments) {
                Set<Segment> adj = new HashSet<Segment>();
                for (Segment t : pointGraph.get(new Point(s.x1, s.y1))) {
                    adj.add(t);
                }
                for (Segment t : pointGraph.get(new Point(s.x2, s.y2))) {
                    adj.add(t);
                }
                adj.remove(s);
                myAssert("adjacent size is wrong", adj.size() == 2);
                adjacent.put(s, new ArrayList<Segment>(adj));
            }
            //Checking that there is one loop.
            Segment first = segments.get(0);
            Segment curr = first;
            Set<Segment> used = new HashSet<Segment>();
            do {
                used.add(curr);
                Segment old = curr;
                for (Segment t : adjacent.get(curr)) {
                    if (!used.contains(t)) {
                        curr = t;
                        break;
                    }
                }
                if (curr == old) {
                    break;
                }
            } while (true);
            myAssert("There is more than one loop", used.size() == segments.size());
            //Geometry checking.
            for (int i = 0; i < segments.size(); ++i) {
                for (int j = i + 1; j < segments.size(); ++j) {
                    Segment one = segments.get(i);
                    Segment two = segments.get(j);
                    if (!adjacent.get(one).contains(two)) {
                        myAssert("Self-intersection or self-touch", !one.intersects(two));
                    }
                }
            }
        }

        double answer = 0;
        for (Map.Entry<Segment, Integer> se : set.entrySet()) {
            if (se.getValue() == 1) {
                Segment s = se.getKey();
                int dx = s.x1 - s.x2;
                int dy = s.y1 - s.y2;
                answer += Math.sqrt(dx * dx + dy * dy);
            }
        }
        PrintWriter out = new PrintWriter("greatwall.out");
        out.println(answer);
        out.close();
    }
}
