<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

227. The art to the broad masses!
time limit per test: 0.25 sec.
memory limit per test: 4096 KB
input: standard
output: standard



Little known abstract artist Madzinsky-Kalevich painted one more masterpiece. He painted N arcs of circles on the rectangular sheet of paper. Radiuses of all arcs do not exceed 10^3. To increase popularity of the masterpiece he decided to include the quantity of arc crosses in the title of the picture. Your task is to help the artist.

Input
The first line of the input contains integer N (1 <= N <= 50). The following N lines contain the descriptions of arcs. Each description is the sequence of three points. The first two are the end points of arc and the third is a intermediate point. All coordinates are integer numbers with the absolute values not greater than 1000.

Output
Write the amount of different cross points of arcs M to the first line of the output. The following M lines should contain coordinates of crosses in ascending order of x-coordinates. If tie, output coordinates in order of increasing y-coordinates. The computed coordinates should be exact to three digits after the decimal point. If there is infinity number of crosses, print 'Infinity' (quotes added for clarity) on the single line. It is guaranteed that in the case of finite number of crosses the distance between any two different crosses will be not less than 0.005.

Sample test(s)

Input
3
7 4 7 -4 3 0
2 2 6 2 4 0
0 4 0 -4 4 0

Output
4
3.009 0.263
3.500 -1.936
3.500 1.936
4.000 0.000
Author:	Ilya V. Elterman
Resource:	
Date:

<|response|>
## 1. Abridged problem statement

You are given `N` arcs, `1 ≤ N ≤ 50`.

Each arc is described by three integer points:

- first point: one endpoint,
- second point: the other endpoint,
- third point: an intermediate point lying on the intended arc.

Find all different intersection points of the arcs.

Print them sorted by increasing `x`, then increasing `y`, with exactly three digits after the decimal point.

If infinitely many intersection points exist, print:

```text
Infinity
```

If the number of intersections is finite, any two different intersection points are guaranteed to be at least `0.005` apart.

---

## 2. Key observations needed to solve the problem

### Observation 1: Three non-collinear points define one circle

For an arc described by points `A`, `B`, `C`:

- `A` and `B` are endpoints,
- `C` is an intermediate point on the arc.

If `A`, `B`, `C` are not collinear, they define a unique circle.

The chord `AB` splits the circle into two arcs. The intermediate point `C` tells which side is used.

A point `P` on the same circle belongs to the arc iff:

- `P` is on the same side of line `AB` as `C`, or
- `P` lies on line `AB`, meaning it is one of the endpoints.

### Observation 2: Collinear input becomes a segment

If `A`, `B`, `C` are collinear, the arc degenerates into the segment `AB`.

So we need to handle both:

- circular arcs,
- straight segments.

### Observation 3: Pairwise checking is enough

`N ≤ 50`, so there are at most:

```text
50 * 49 / 2 = 1225
```

pairs of arcs.

Each pair can be processed in constant time.

### Observation 4: Infinite intersections happen only by overlap

There are infinitely many intersections if two arcs overlap along a positive-length part.

This can happen in two cases:

1. Two collinear segments overlap in a segment.
2. Two circular arcs lie on the same circle and their angular intervals overlap with positive length.

Otherwise, two arcs have at most two intersection points.

### Observation 5: Duplicate intersection points must be removed

The same point can be produced by multiple pairs of arcs.

The statement guarantees different finite intersection points are at least `0.005` apart, so using a small tolerance like `1e-3` is safe for deduplication.

---

## 3. Full solution approach based on the observations

For each input arc:

1. Let its points be `A`, `B`, `C`.
2. If they are collinear, store it as a segment.
3. Otherwise:
   - compute the circumcenter of triangle `ABC`,
   - compute the radius,
   - store it as a circular arc.

Then check every pair of processed arcs.

There are three main pair types.

---

### Case 1: Segment vs segment

Let the segments be `AB` and `CD`.

If their supporting lines are not parallel:

- compute the line-line intersection,
- keep it only if it lies on both segments.

If they are parallel:

- if they are on different lines, they do not intersect,
- if they are on the same line:
  - project both segments onto one axis,
  - if the overlap has positive length, answer is `Infinity`,
  - if they touch at exactly one endpoint, add that point.

---

### Case 2: Segment vs circular arc

Intersect the segment's supporting line with the circle.

A line and a circle may have:

- no intersection,
- one tangent point,
- two intersection points.

For each candidate point, keep it only if:

1. it lies on the segment,
2. it lies on the circular arc.

---

### Case 3: Circular arc vs circular arc

If their supporting circles are different:

- compute circle-circle intersections,
- keep only points belonging to both arcs.

If their supporting circles are the same:

- convert each arc to an angular interval on the circle,
- if their angular intervals overlap with positive length, print `Infinity`,
- otherwise they can only share endpoints, so test all endpoints.

---

### Final steps

After processing all pairs:

1. If any infinite overlap was found, print `Infinity`.
2. Otherwise:
   - remove duplicate points,
   - sort points by `x`, then by `y`,
   - print the number of points and their coordinates.

Complexity:

```text
Time:   O(N^2)
Memory: O(N^2)
```

---

## 4. C++ Solution

```cpp
#include <bits/stdc++.h>
// #include <coding_library/geometry/point.hpp>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

using coord_t = double;

struct Point {
    static constexpr coord_t eps = 1e-9;
    static inline const coord_t PI = acos((coord_t)-1.0);

    coord_t x, y;
    Point(coord_t x = 0, coord_t y = 0) : x(x), y(y) {}

    Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }
    Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }
    Point operator*(coord_t c) const { return Point(x * c, y * c); }
    Point operator/(coord_t c) const { return Point(x / c, y / c); }

    coord_t operator*(const Point& p) const { return x * p.x + y * p.y; }
    coord_t operator^(const Point& p) const { return x * p.y - y * p.x; }

    bool operator==(const Point& p) const { return x == p.x && y == p.y; }
    bool operator!=(const Point& p) const { return x != p.x || y != p.y; }
    bool operator<(const Point& p) const {
        return x != p.x ? x < p.x : y < p.y;
    }
    bool operator>(const Point& p) const {
        return x != p.x ? x > p.x : y > p.y;
    }
    bool operator<=(const Point& p) const {
        return x != p.x ? x < p.x : y <= p.y;
    }
    bool operator>=(const Point& p) const {
        return x != p.x ? x > p.x : y >= p.y;
    }

    coord_t norm2() const { return x * x + y * y; }
    coord_t norm() const { return sqrt(norm2()); }
    coord_t angle() const { return atan2(y, x); }

    Point rotate(coord_t a) const {
        return Point(x * cos(a) - y * sin(a), x * sin(a) + y * cos(a));
    }

    Point perp() const { return Point(-y, x); }
    Point unit() const { return *this / norm(); }
    Point normal() const { return perp().unit(); }
    Point project(const Point& p) const {
        return *this * (*this * p) / norm2();
    }
    Point reflect(const Point& p) const {
        return *this * 2 * (*this * p) / norm2() - p;
    }

    friend ostream& operator<<(ostream& os, const Point& p) {
        return os << p.x << ' ' << p.y;
    }
    friend istream& operator>>(istream& is, Point& p) {
        return is >> p.x >> p.y;
    }

    friend int ccw(const Point& a, const Point& b, const Point& c) {
        coord_t v = (b - a) ^ (c - a);
        if(-eps <= v && v <= eps) {
            return 0;
        } else if(v > 0) {
            return 1;
        } else {
            return -1;
        }
    }

    friend bool point_on_segment(
        const Point& a, const Point& b, const Point& p
    ) {
        return ccw(a, b, p) == 0 && p.x >= min(a.x, b.x) - eps &&
               p.x <= max(a.x, b.x) + eps && p.y >= min(a.y, b.y) - eps &&
               p.y <= max(a.y, b.y) + eps;
    }

    friend bool point_in_triangle(
        const Point& a, const Point& b, const Point& c, const Point& p
    ) {
        int d1 = ccw(a, b, p);
        int d2 = ccw(b, c, p);
        int d3 = ccw(c, a, p);
        return (d1 >= 0 && d2 >= 0 && d3 >= 0) ||
               (d1 <= 0 && d2 <= 0 && d3 <= 0);
    }

    friend Point line_line_intersection(
        const Point& a1, const Point& b1, const Point& a2, const Point& b2
    ) {
        return a1 +
               (b1 - a1) * ((a2 - a1) ^ (b2 - a2)) / ((b1 - a1) ^ (b2 - a2));
    }

    friend bool collinear(const Point& a, const Point& b) {
        return abs(a ^ b) < eps;
    }

    friend Point circumcenter(const Point& a, const Point& b, const Point& c) {
        Point mid_ab = (a + b) / 2.0;
        Point mid_ac = (a + c) / 2.0;
        Point perp_ab = (b - a).perp();
        Point perp_ac = (c - a).perp();
        return line_line_intersection(
            mid_ab, mid_ab + perp_ab, mid_ac, mid_ac + perp_ac
        );
    }

    friend coord_t arc_area(
        const Point& center, coord_t r, const Point& p1, const Point& p2
    ) {
        coord_t theta1 = (p1 - center).angle();
        coord_t theta2 = (p2 - center).angle();
        if(theta2 < theta1 - eps) {
            theta2 += 2 * PI;
        }

        coord_t d_theta = theta2 - theta1;
        coord_t cx = center.x, cy = center.y;
        coord_t area = r * cx * (sin(theta2) - sin(theta1)) -
                       r * cy * (cos(theta2) - cos(theta1)) + r * r * d_theta;
        return area / 2.0;
    }

    friend vector<Point> intersect_circles(
        const Point& c1, coord_t r1, const Point& c2, coord_t r2
    ) {
        Point d = c2 - c1;
        coord_t dist = d.norm();

        if(dist > r1 + r2 + eps || dist < abs(r1 - r2) - eps || dist < eps) {
            return {};
        }

        coord_t a = (r1 * r1 - r2 * r2 + dist * dist) / (2 * dist);
        coord_t h_sq = r1 * r1 - a * a;
        if(h_sq < -eps) {
            return {};
        }
        if(h_sq < 0) {
            h_sq = 0;
        }
        coord_t h = sqrt(h_sq);

        Point mid = c1 + d.unit() * a;
        Point perp_dir = d.perp().unit();

        if(h < eps) {
            return {mid};
        }
        return {mid + perp_dir * h, mid - perp_dir * h};
    }

    friend optional<Point> intersect_ray_segment(
        const Point& ray_start, const Point& ray_through, const Point& seg_a,
        const Point& seg_b
    ) {
        Point ray_dir = ray_through - ray_start;
        if(ray_dir.norm2() < Point::eps) {
            return {};
        }
        Point seg_dir = seg_b - seg_a;
        coord_t denom = ray_dir ^ seg_dir;
        if(fabs(denom) < eps) {
            return {};
        }
        coord_t t = ((seg_a - ray_start) ^ seg_dir) / denom;
        if(t < eps) {
            return {};
        }
        coord_t s = ((seg_a - ray_start) ^ ray_dir) / denom;
        if(s < eps || s > 1 - eps) {
            return {};
        }
        return ray_start + ray_dir * t;
    }
};

struct Arc {
    bool is_segment;
    Point a, b, c, center;
    coord_t r;
};

struct Crossing {
    bool infinite;
    vector<Point> pts;
};

int n;
vector<array<Point, 3>> raw_arcs;

void read() {
    cin >> n;
    raw_arcs.assign(n, {});
    for(auto& t: raw_arcs) {
        cin >> t[0] >> t[1] >> t[2];
    }
}

coord_t norm_2pi(coord_t a) {
    coord_t full = 2 * Point::PI;
    a = fmod(a, full);
    if(a < 0) {
        a += full;
    }

    return a;
}

Arc make_arc(const Point& p0, const Point& p1, const Point& p2) {
    Arc arc;
    arc.a = p0;
    arc.b = p1;
    arc.c = p2;
    if(ccw(p0, p1, p2) == 0) {
        arc.is_segment = true;
    } else {
        arc.is_segment = false;
        arc.center = circumcenter(p0, p1, p2);
        arc.r = (p0 - arc.center).norm();
    }

    return arc;
}

bool on_circle_arc(const Arc& arc, const Point& p) {
    coord_t side_c = (arc.b - arc.a) ^ (arc.c - arc.a);
    coord_t side_p = (arc.b - arc.a) ^ (p - arc.a);
    if(fabs(side_p) < Point::eps) {
        return true;
    }

    return (side_c > 0) == (side_p > 0);
}

pair<coord_t, coord_t> arc_interval(const Arc& arc) {
    coord_t ang_a = (arc.a - arc.center).angle();
    coord_t ang_b = (arc.b - arc.center).angle();
    coord_t ang_c = (arc.c - arc.center).angle();
    coord_t span_b = norm_2pi(ang_b - ang_a);
    coord_t span_c = norm_2pi(ang_c - ang_a);
    if(span_c <= span_b) {
        return {ang_a, span_b};
    }

    return {ang_b, 2 * Point::PI - span_b};
}

coord_t arc_overlap(const Arc& x, const Arc& y) {
    auto interval_x = arc_interval(x);
    auto interval_y = arc_interval(y);
    coord_t start_x = interval_x.first, len_x = interval_x.second;
    coord_t start_y = interval_y.first, len_y = interval_y.second;
    coord_t full = 2 * Point::PI;
    coord_t shift = norm_2pi(start_y - start_x);
    coord_t overlap = 0;

    auto add = [&](coord_t lo, coord_t hi) {
        coord_t l = max(lo, (coord_t)0), r = min(hi, len_x);
        if(r > l) {
            overlap += r - l;
        }
    };

    if(shift + len_y <= full) {
        add(shift, shift + len_y);
    } else {
        add(shift, full);
        add(0, shift + len_y - full);
    }

    return overlap;
}

vector<Point> line_circle(
    const Point& a, const Point& b, const Point& center, coord_t r
) {
    Point dir = (b - a).unit();
    Point foot = a + dir * ((center - a) * dir);
    coord_t dist = (center - foot).norm();
    if(dist > r + Point::eps) {
        return {};
    }

    coord_t h_sq = r * r - dist * dist;
    if(h_sq < 0) {
        h_sq = 0;
    }
    coord_t h = sqrt(h_sq);
    if(h < Point::eps) {
        return {foot};
    }

    return {foot + dir * h, foot - dir * h};
}

Crossing intersect_arcs(const Arc& x, const Arc& y) {
    Crossing res;
    res.infinite = false;

    if(x.is_segment && y.is_segment) {
        Point d1 = x.b - x.a, d2 = y.b - y.a;
        if(fabs(d1 ^ d2) < Point::eps) {
            if(ccw(x.a, x.b, y.a) != 0) {
                return res;
            }

            Point u = d1.unit();
            coord_t len = (x.b - x.a) * u;
            coord_t pos_a = (y.a - x.a) * u;
            coord_t pos_b = (y.b - x.a) * u;
            coord_t lo = max((coord_t)0, min(pos_a, pos_b));
            coord_t hi = min(len, max(pos_a, pos_b));
            if(hi > lo + Point::eps) {
                res.infinite = true;
            } else if(hi > lo - Point::eps) {
                res.pts.push_back(x.a + u * ((lo + hi) / 2));
            }

            return res;
        }

        Point p = line_line_intersection(x.a, x.b, y.a, y.b);
        if(point_on_segment(x.a, x.b, p) && point_on_segment(y.a, y.b, p)) {
            res.pts.push_back(p);
        }

        return res;
    }

    if(x.is_segment != y.is_segment) {
        const Arc& seg = x.is_segment ? x : y;
        const Arc& cir = x.is_segment ? y : x;
        for(const Point& p: line_circle(seg.a, seg.b, cir.center, cir.r)) {
            if(point_on_segment(seg.a, seg.b, p) && on_circle_arc(cir, p)) {
                res.pts.push_back(p);
            }
        }

        return res;
    }

    if((x.center - y.center).norm() < 1e-6 && fabs(x.r - y.r) < 1e-6) {
        if(arc_overlap(x, y) > 1e-7) {
            res.infinite = true;
            return res;
        }

        for(const Point& p: {x.a, x.b, y.a, y.b}) {
            if(on_circle_arc(x, p) && on_circle_arc(y, p)) {
                res.pts.push_back(p);
            }
        }

        return res;
    }

    for(const Point& p: intersect_circles(x.center, x.r, y.center, y.r)) {
        if(on_circle_arc(x, p) && on_circle_arc(y, p)) {
            res.pts.push_back(p);
        }
    }

    return res;
}

void solve() {
    // Each arc is the circle through its three points, restricted to the side
    // of the chord (first two points) that contains the third, intermediate
    // point. So a point lying on the supporting circle belongs to the arc iff
    // it is on the same side of the chord as the intermediate point, with the
    // two endpoints included. If the three points are collinear the supporting
    // circle degenerates and the arc is just the segment between its endpoints,
    // which we treat as a separate case.
    //
    // We gather all crossing points by looking at every pair of arcs. For two
    // arcs on different circles we take the (at most two) circle-circle
    // intersection points and keep those that lie on both arcs. A segment and
    // an arc reduce to line-circle intersection filtered the same way, and two
    // segments reduce to segment-segment intersection.
    //
    // The number of crossings is infinite exactly when two arcs share a whole
    // sub-arc: two segments overlapping along a common sub-segment, or two
    // co-circular arcs whose angular ranges overlap on more than isolated
    // points. For co-circular arcs we build the CCW angular interval of each
    // (the one passing through the intermediate point) and measure their
    // overlap length on the circle; a positive overlap means infinitely many
    // crossings, otherwise the only crossings are shared endpoints.
    //
    // Finally we drop duplicate points (the same crossing is found by several
    // pairs, and distinct crossings are guaranteed to be at least 0.005 apart),
    // then sort by x and then y for output.

    vector<Arc> arcs;
    for(auto& t: raw_arcs) {
        arcs.push_back(make_arc(t[0], t[1], t[2]));
    }

    bool infinite = false;
    vector<Point> pts;
    for(int i = 0; i < n; i++) {
        for(int j = i + 1; j < n; j++) {
            Crossing res = intersect_arcs(arcs[i], arcs[j]);
            if(res.infinite) {
                infinite = true;
            }
            for(const Point& p: res.pts) {
                pts.push_back(p);
            }
        }
    }

    if(infinite) {
        cout << "Infinity\n";
        return;
    }

    vector<Point> uniq;
    for(const Point& p: pts) {
        bool dup = false;
        for(const Point& q: uniq) {
            if((p - q).norm() < 1e-3) {
                dup = true;
                break;
            }
        }
        if(!dup) {
            uniq.push_back(p);
        }
    }

    sort(uniq.begin(), uniq.end(), [](const Point& p, const Point& q) {
        if(fabs(p.x - q.x) > 1e-6) {
            return p.x < q.x;
        }

        return p.y < q.y;
    });

    cout << uniq.size() << '\n';
    cout << fixed << setprecision(3);
    for(const Point& p: uniq) {
        coord_t ox = fabs(p.x) < 5e-4 ? 0 : p.x;
        coord_t oy = fabs(p.y) < 5e-4 ? 0 : p.y;
        cout << ox << ' ' << oy << '\n';
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        solve();
    }

    return 0;
}
```

---

## 5. Python implementation with detailed comments

```python
import sys
import math


EPS = 1e-9
PI = math.pi
FULL = 2.0 * PI


class Point:
    def __init__(self, x=0.0, y=0.0):
        self.x = float(x)
        self.y = float(y)

    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

    def __sub__(self, other):
        return Point(self.x - other.x, self.y - other.y)

    def __mul__(self, k):
        return Point(self.x * k, self.y * k)

    def __truediv__(self, k):
        return Point(self.x / k, self.y / k)

    def dot(self, other):
        return self.x * other.x + self.y * other.y

    def cross(self, other):
        return self.x * other.y - self.y * other.x

    def norm2(self):
        return self.x * self.x + self.y * self.y

    def norm(self):
        return math.sqrt(self.norm2())

    def unit(self):
        return self / self.norm()

    def perp(self):
        return Point(-self.y, self.x)

    def angle(self):
        return math.atan2(self.y, self.x)


class Arc:
    def __init__(self):
        self.is_segment = False

        self.a = None
        self.b = None
        self.c = None

        self.center = None
        self.r = 0.0


def sign(x):
    if x > EPS:
        return 1
    if x < -EPS:
        return -1
    return 0


def ccw(a, b, c):
    """
    Orientation of triangle ABC.
    """
    return sign((b - a).cross(c - a))


def point_on_segment(a, b, p):
    """
    Check whether point p lies on closed segment AB.
    """
    return (
        ccw(a, b, p) == 0
        and min(a.x, b.x) - EPS <= p.x <= max(a.x, b.x) + EPS
        and min(a.y, b.y) - EPS <= p.y <= max(a.y, b.y) + EPS
    )


def line_line_intersection(a1, b1, a2, b2):
    """
    Intersection of two non-parallel infinite lines.
    """
    d1 = b1 - a1
    d2 = b2 - a2

    t = (a2 - a1).cross(d2) / d1.cross(d2)

    return a1 + d1 * t


def circumcenter(a, b, c):
    """
    Circumcenter of non-collinear triangle ABC.
    """
    mid_ab = (a + b) / 2.0
    mid_ac = (a + c) / 2.0

    dir_ab = (b - a).perp()
    dir_ac = (c - a).perp()

    return line_line_intersection(
        mid_ab, mid_ab + dir_ab,
        mid_ac, mid_ac + dir_ac
    )


def normalize_angle(a):
    """
    Normalize angle to [0, 2*pi).
    """
    a = math.fmod(a, FULL)

    if a < 0:
        a += FULL

    return a


def make_arc(a, b, c):
    """
    Convert input triple into either a segment or a circular arc.
    """
    arc = Arc()

    arc.a = a
    arc.b = b
    arc.c = c

    if ccw(a, b, c) == 0:
        arc.is_segment = True
    else:
        arc.is_segment = False
        arc.center = circumcenter(a, b, c)
        arc.r = (a - arc.center).norm()

    return arc


def on_circle_arc(arc, p):
    """
    Check whether p belongs to circular arc.

    Assumes p lies on the same supporting circle.
    """
    side_c = (arc.b - arc.a).cross(arc.c - arc.a)
    side_p = (arc.b - arc.a).cross(p - arc.a)

    if abs(side_p) < EPS:
        return True

    return (side_c > 0) == (side_p > 0)


def arc_interval(arc):
    """
    Convert a circular arc to a counterclockwise angular interval.

    Returns:
        start_angle, length
    """
    ang_a = (arc.a - arc.center).angle()
    ang_b = (arc.b - arc.center).angle()
    ang_c = (arc.c - arc.center).angle()

    span_b = normalize_angle(ang_b - ang_a)
    span_c = normalize_angle(ang_c - ang_a)

    if span_c <= span_b:
        return ang_a, span_b

    return ang_b, FULL - span_b


def arc_overlap(x, y):
    """
    Compute angular overlap length of two arcs on the same circle.
    Positive overlap means infinitely many common points.
    """
    start_x, len_x = arc_interval(x)
    start_y, len_y = arc_interval(y)

    shift = normalize_angle(start_y - start_x)

    overlap = 0.0

    def add_overlap(l, r):
        nonlocal overlap

        left = max(l, 0.0)
        right = min(r, len_x)

        if right > left:
            overlap += right - left

    if shift + len_y <= FULL:
        add_overlap(shift, shift + len_y)
    else:
        add_overlap(shift, FULL)
        add_overlap(0.0, shift + len_y - FULL)

    return overlap


def line_circle_intersection(a, b, center, r):
    """
    Intersect infinite line AB with circle.
    """
    direction = (b - a).unit()

    foot = a + direction * (center - a).dot(direction)

    dist = (center - foot).norm()

    if dist > r + EPS:
        return []

    h2 = r * r - dist * dist

    if h2 < 0:
        h2 = 0.0

    h = math.sqrt(h2)

    if h < EPS:
        return [foot]

    return [
        foot + direction * h,
        foot - direction * h
    ]


def circle_circle_intersection(c1, r1, c2, r2):
    """
    Intersect two circles.
    """
    d = c2 - c1
    dist = d.norm()

    if (
        dist > r1 + r2 + EPS
        or dist < abs(r1 - r2) - EPS
        or dist < EPS
    ):
        return []

    a = (r1 * r1 - r2 * r2 + dist * dist) / (2.0 * dist)
    h2 = r1 * r1 - a * a

    if h2 < -EPS:
        return []

    if h2 < 0:
        h2 = 0.0

    base = c1 + d.unit() * a
    perp = d.perp().unit()

    h = math.sqrt(h2)

    if h < EPS:
        return [base]

    return [
        base + perp * h,
        base - perp * h
    ]


def intersect_arcs(x, y):
    """
    Intersect two arcs.

    Returns:
        infinite, points
    """
    infinite = False
    points = []

    # Case 1: segment vs segment.
    if x.is_segment and y.is_segment:
        d1 = x.b - x.a
        d2 = y.b - y.a

        # Parallel supporting lines.
        if abs(d1.cross(d2)) < EPS:
            # Different lines.
            if ccw(x.a, x.b, y.a) != 0:
                return False, []

            # Same line: project onto direction of first segment.
            u = d1.unit()

            len_x = (x.b - x.a).dot(u)

            p1 = (y.a - x.a).dot(u)
            p2 = (y.b - x.a).dot(u)

            lo = max(0.0, min(p1, p2))
            hi = min(len_x, max(p1, p2))

            if hi > lo + EPS:
                return True, []

            if hi > lo - EPS:
                points.append(x.a + u * ((lo + hi) / 2.0))

            return False, points

        # Non-parallel lines.
        p = line_line_intersection(x.a, x.b, y.a, y.b)

        if point_on_segment(x.a, x.b, p) and point_on_segment(y.a, y.b, p):
            points.append(p)

        return False, points

    # Case 2: segment vs circular arc.
    if x.is_segment != y.is_segment:
        seg = x if x.is_segment else y
        cir = y if x.is_segment else x

        candidates = line_circle_intersection(
            seg.a,
            seg.b,
            cir.center,
            cir.r
        )

        for p in candidates:
            if point_on_segment(seg.a, seg.b, p) and on_circle_arc(cir, p):
                points.append(p)

        return False, points

    # Case 3: circular arc vs circular arc.

    # Same supporting circle.
    if (x.center - y.center).norm() < 1e-6 and abs(x.r - y.r) < 1e-6:
        if arc_overlap(x, y) > 1e-7:
            return True, []

        # No positive overlap: only shared endpoints are possible.
        for p in [x.a, x.b, y.a, y.b]:
            if on_circle_arc(x, p) and on_circle_arc(y, p):
                points.append(p)

        return False, points

    # Different supporting circles.
    candidates = circle_circle_intersection(
        x.center,
        x.r,
        y.center,
        y.r
    )

    for p in candidates:
        if on_circle_arc(x, p) and on_circle_arc(y, p):
            points.append(p)

    return False, points


def solve():
    data = sys.stdin.read().strip().split()

    if not data:
        return

    it = iter(data)

    n = int(next(it))

    arcs = []

    for _ in range(n):
        a = Point(float(next(it)), float(next(it)))
        b = Point(float(next(it)), float(next(it)))
        c = Point(float(next(it)), float(next(it)))

        arcs.append(make_arc(a, b, c))

    all_points = []
    has_infinite = False

    # Process all pairs of arcs.
    for i in range(n):
        for j in range(i + 1, n):
            infinite, points = intersect_arcs(arcs[i], arcs[j])

            if infinite:
                has_infinite = True

            all_points.extend(points)

    if has_infinite:
        print("Infinity")
        return

    # Deduplicate points.
    unique = []

    for p in all_points:
        duplicate = False

        for q in unique:
            if (p - q).norm() < 1e-3:
                duplicate = True
                break

        if not duplicate:
            unique.append(p)

    # Sort by x, then y.
    unique.sort(key=lambda p: (p.x, p.y))

    print(len(unique))

    for p in unique:
        # Avoid printing -0.000.
        x = 0.0 if abs(p.x) < 5e-4 else p.x
        y = 0.0 if abs(p.y) < 5e-4 else p.y

        print(f"{x:.3f} {y:.3f}")


if __name__ == "__main__":
    solve()
```