Problem: In Medieval times existed the tradition of burning witches at steaks together with their pets, black cats. By the end of the 15-th century the population of black cats ceased to exist. The difficulty of the situation led to creating the EIC - the Emergency Inquisitory Commission.

The resolution #666 says that a white cat is considered black when and only when the perimeter of its black spots exceeds the acceptable norm. But what does the acceptable norm equal to? Every inquisitor will choose it himself depending on the situation. And your task is to find the perimeter of black spots on the cat's fur.

The very same resolution says that the cat's fur is a white square with the length of 105. During the measurement of spots it is customary to put the lower left corner of the fur into the origin of axes (0;0) and the upper right one — to the point with coordinates (105;105). The cats' spots are nondegenerate triangles. The spots can intersect and overlap with each other, but it is guaranteed that each pair of the triangular spots' sides have no more than one common point.

We'll regard the perimeter in this problem as the total length of the boarders where a cat's fur changes color.

Input

The first input line contains a single integer n (0 ≤ n ≤ 100). It is the number of spots on the cat's fur. The i-th of the last n lines contains 6 integers: x1i, y1i, x2i, y2i, x3i, y3i. They are the coordinates of the i-th triangular spot (0 < xji, yji < 105).

Output

Print a single number, the answer to the problem, perimeter of the union of triangles. Your answer should differ from the correct one in no more than 10 - 6.

Examples

Input

1
1 1 2 1 1 2


Output

3.4142135624


Input

3
3 3 10 3 3 10
1 1 9 4 5 6
2 2 11 7 6 11


Output

37.7044021497

Solution (in JAVA):

Solution:
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.util.Comparator;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author AlexFetisov
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC_Inc solver = new TaskC_Inc();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC_Inc {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            Point[][] tri = new Point[n][3];
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < 3; ++j) {
                    tri[i][j] = new Point(in);
                }
            }
            double res = 0;
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < 3; ++j) {
                    Point A = tri[i][j];
                    Point B = tri[i][(j + 1) % 3];
                    res += solve(A, B, i, tri);
                }
            }
            out.println(res);
        }

        private double solve(Point A, Point B, int curId, Point[][] tri) {
            List<Point> points = new ArrayList<Point>();
            for (int i = 0; i < tri.length; ++i)
                if (i != curId) {
                    for (int j = 0; j < 3; ++j) {
                        Point C = tri[i][j];
                        Point D = tri[i][(j + 1) % 3];
                        Segment s1 = new Segment(A, B);
                        Segment s2 = new Segment(C, D);
                        Point p = s1.intersect(s2, false);
                        if (p != null) {
                            points.add(p);
                        }
                    }
                }
            points.add(A);
            points.add(B);
            Collections.sort(points, new Comparator<Point>() {

                public int compare(Point o1, Point o2) {
                    return o1.compareTo(o2);
                }
            });
            double res = 0;
            for (int i = 0, j = 1; j < points.size(); ++j, ++i) {
                Point M = points.get(i).add(points.get(j)).div(2.);
                boolean inside = false;
                for (int k = 0; k < tri.length; ++k)
                    if (curId != k) {
                        Point[] t = tri[k];
                        double S = GeometryUtils.triangleSquare(t[0], t[1], t[2]);
                        double S1 = GeometryUtils.triangleSquare(t[0], t[1], M);
                        double S2 = GeometryUtils.triangleSquare(t[0], M, t[2]);
                        double S3 = GeometryUtils.triangleSquare(M, t[1], t[2]);
//                if (DoubleUtils.compareTo(S1, 0) == 0) throw new AssertionError("!");
//                if (DoubleUtils.compareTo(S2, 0) == 0) throw new AssertionError("!");
//                if (DoubleUtils.compareTo(S3, 0) == 0) throw new AssertionError("!");

                        if (DoubleUtils.compareTo(S1, 0) != 0 && DoubleUtils.compareTo(S2, 0) != 0 && DoubleUtils.compareTo(S3, 0) != 0 &&
                            DoubleUtils.compareTo(S, S1 + S2 + S3) == 0) {
                            inside = true;
                            break;
                        }
                    }
                if (!inside) {
                    res += points.get(i).distanceTo(points.get(j));
                }
            }
            return res;
        }

    }

    static class Segment {
        public final Point a;
        public final Point b;
        private Line line = null;

        public Segment(Point a, Point b) {
            this.a = a;
            this.b = b;
        }

        public Point intersect(Segment other, boolean withEnds) {
            Line line = line();
            Line otherLine = other.a.line(other.b);
            if (line.parallel(otherLine)) {
                return null;
            }
            Point intersection = line.intersect(otherLine);
            if (contains(intersection, withEnds) && other.contains(intersection, withEnds)) {
                return intersection;
            } else {
                return null;
            }
        }

        public boolean contains(Point point, boolean withEnds) {
            if (a.equals(point) || b.equals(point)) {
                return withEnds;
            }
            if (a.equals(b)) {
                return false;
            }
            Line line = line();
            if (!line.contains(point)) {
                return false;
            }
            Line perpendicular = line.perpendicular(a);
            double aValue = perpendicular.value(a);
            double bValue = perpendicular.value(b);
            double pointValue = perpendicular.value(point);
            return aValue < pointValue && pointValue < bValue || bValue < pointValue && pointValue < aValue;
        }


        public String toString() {
            return a.toString() + ", " + b.toString();
        }

        public Line line() {
            if (line == null) {
                line = a.line(b);
            }
            return line;
        }

    }

    static class Point implements Comparable<Point> {
        public double x;
        public double y;

        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public Line line(Point other) {
            if (equals(other))
                return null;
            double a = other.y - y;
            double b = x - other.x;
            double c = -a * x - b * y;
            return new Line(a, b, c);
        }

        public Point() {
            this.x = 0;
            this.y = 0;
        }

        public Point(InputReader in) {
            this.x = in.nextDouble();
            this.y = in.nextDouble();
        }


        public String toString() {
            return "(" + x + ", " + y + " )";
        }


        public boolean equals(Object o) {
            Point p = (Point) o;
            return DoubleUtils.compareTo(x, p.x) == 0 && DoubleUtils.compareTo(y, p.y) == 0;
        }


        public int hashCode() {
            int result;
            long temp;
            temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
            result = (int) (temp ^ (temp >>> 32));
            temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
            result = 31 * result + (int) (temp ^ (temp >>> 32));
            return result;
        }

        public Point add(Point p) {
            return new Point(x + p.x, y + p.y);
        }

        public Point sub(Point p) {
            return new Point(x - p.x, y - p.y);
        }

        public Point div(double k) {
            return new Point(x / k, y / k);
        }

        public double dotProduct(Point p) {
            return x * p.x + y * p.y;
        }

        public double crossProduct(Point p) {
            return x * p.y - y * p.x;
        }

        public double length() {
            return DoubleUtils.sqrt(dotProduct(this));
        }

        public double distanceTo(Point p) {
            return sub(p).length();
        }


        public int compareTo(Point o) {
            int temp = DoubleUtils.compareTo(x, o.x);
            if (temp == 0) {
                return DoubleUtils.compareTo(y, o.y);
            }
            return temp;
        }

    }

    static class DoubleUtils {
        public static final double EPS = 1e-6;

        public static double sqr(double x) {
            return x * x;
        }

        public static int compareTo(double a, double b) {
            if (doubleEqual(a, b)) {
                return 0;
            }
            if (a < b) {
                return -1;
            }
            return 1;
        }

        private static boolean doubleEqual(double a, double b) {
            return Math.abs(a - b) < EPS;
        }

        public static double sqrt(double a) {
            if (compareTo(a, 0) < 0) {
                System.exit(1);
            }
            if (a < 0) return 0;
            return Math.sqrt(a);
        }

        public static double hypot(double a, double b) {
            return sqrt(sqr(a) + sqr(b));
        }

    }

    static class Line {
        public final double a;
        public final double b;
        public final double c;
        public Point p1;
        public Point p2;
        boolean hasPoints;

        public Line(Point p, double angle) {
            a = Math.sin(angle);
            b = -Math.cos(angle);
            c = -p.x * a - p.y * b;
            p1 = p2 = null;
            hasPoints = false;
        }

        public Line(double a, double b, double c) {
            double h = DoubleUtils.hypot(a, b);
            this.a = a / h;
            this.b = b / h;
            this.c = c / h;
            hasPoints = false;
        }

        public Line(Point p1, Point p2) {
            double a = p2.y - p1.y;
            double b = p1.x - p2.x;
            double c = -(p1.x * a + p1.y * b);
            double h = DoubleUtils.hypot(a, b);
            this.a = a / h;
            this.b = b / h;
            this.c = c / h;
            hasPoints = true;
        }

        public Point intersect(Line other) {
            if (parallel(other)) {
                return null;
            }
            double determinant = b * other.a - a * other.b;
            double x = (c * other.b - b * other.c) / determinant;
            double y = (a * other.c - c * other.a) / determinant;
            return new Point(x, y);
        }

        public boolean parallel(Line other) {
            return DoubleUtils.compareTo(Math.abs(a * other.b - b * other.a), 0) == 0;
        }

        public boolean contains(Point point) {
            return DoubleUtils.compareTo(Math.abs(value(point)), 0) == 0;
        }

        public Line perpendicular(Point point) {
            return new Line(-b, a, b * point.x - a * point.y);
        }

        public double value(Point point) {
            return a * point.x + b * point.y + c;
        }


        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Line line = (Line) o;

            if (!parallel(line)) return false;
            if (Math.abs(a * line.c - c * line.a) > DoubleUtils.EPS || Math.abs(b * line.c - c * line.b) > DoubleUtils.EPS)
                return false;

            return true;
        }

    }

    static class GeometryUtils {
        public static double triangleSquare(Point A, Point B, Point C) {
            return Math.abs(B.sub(A).crossProduct(C.sub(A))) / 2.;
        }

    }

    static class InputReader {
        private BufferedReader reader;
        private StringTokenizer stt;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
        }

        public String nextLine() {
            try {
                return reader.readLine();
            } catch (IOException e) {
                return null;
            }
        }

        public String nextString() {
            while (stt == null || !stt.hasMoreTokens()) {
                stt = new StringTokenizer(nextLine());
            }
            return stt.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(nextString());
        }

        public double nextDouble() {
            return Double.parseDouble(nextString());
        }

    }
}