## 1. Abridged problem statement

You are given `N` circular 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.

For every pair of arcs, determine their intersection points. Output all distinct intersection points sorted by increasing `x`, then increasing `y`, rounded to three decimal places.

If infinitely many intersection points exist, output:

```text
Infinity
```

It is guaranteed that if the number of intersections is finite, any two distinct intersection points are at least `0.005` apart.

---

## 2. Detailed editorial

### Geometry interpretation

An arc is defined by three points `A`, `B`, `C`.

- `A` and `B` are endpoints.
- `C` lies somewhere on the desired arc between `A` and `B`.

If the three points are not collinear, they define a unique circle. The full circle is split by chord `AB` into two arcs. The point `C` tells us which of the two arcs is meant.

A point `P` on the same circle belongs to the arc iff `P` lies on the same side of line `AB` as `C`, or lies exactly on line `AB`.

If the three points are collinear, the code treats the arc as a straight segment from `A` to `B`.

---

### Main idea

There are at most `50` arcs, so checking every pair is enough:

```text
for every pair of arcs:
    find their intersection points
    detect whether they overlap infinitely
```

There are only three cases:

1. segment vs segment,
2. segment vs circular arc,
3. circular arc vs circular arc.

All intersection candidates are filtered to ensure they actually lie on both finite arcs.

---

### Case 1: segment vs segment

If two segments are not parallel, compute the intersection of their supporting lines. Then check whether the point lies on both segments.

If they are parallel:

- If they are on different lines, they do not intersect.
- If they lie on the same line, project onto one dimension and check overlap.
  - Positive-length overlap means infinitely many crossings.
  - Touching at one endpoint gives one crossing point.

---

### Case 2: segment vs circular arc

Intersect the segment’s supporting line with the circle.

A line can intersect a circle in:

- zero points,
- one tangent point,
- two points.

For every candidate point, check:

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

---

### Case 3: circular arc vs circular arc

If the two arcs lie on different circles, compute the circle-circle intersections. There are at most two. Keep only those points that lie on both arcs.

If the two arcs lie on the same circle, they may overlap along a whole arc. In that case, there are infinitely many intersections.

To detect this, convert every arc to an angular interval on the circle. Then compute overlap length between the two angular intervals.

- Positive angular overlap means infinitely many points.
- Zero-length overlap means they may only touch at endpoints.

---

### Deduplication

The same crossing point can be found multiple times, especially if several arcs meet at one point.

The statement guarantees distinct finite crossings are at least `0.005` apart, so the solution considers two computed points equal if their distance is less than `1e-3`.

Finally, points are sorted by `x`, then by `y`, and printed with three digits after the decimal point.

---

### Complexity

There are `O(N^2)` arc pairs.

Each pair is processed in constant time.

Therefore:

```text
Time complexity: O(N^2)
Memory complexity: O(N^2) for storing intersection points
```

With `N ≤ 50`, this is easily fast enough.

---

## 3. 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;
}
```

---

## 4. Python solution with detailed comments

```python
import sys
import math


# Floating-point tolerance.
EPS = 1e-9

# Pi and full circle angle.
PI = math.pi
FULL = 2.0 * PI


class Point:
    """2D point/vector with basic geometry operations."""

    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, value):
        # Multiplication by scalar.
        return Point(self.x * value, self.y * value)

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

    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):
        length = self.norm()
        return self / length

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

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


class Arc:
    """Processed representation of one input 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 ccw(a, b, c):
    """
    Orientation of triangle abc.
    Returns:
      1  if counterclockwise,
      -1 if clockwise,
      0  if collinear.
    """
    value = (b - a).cross(c - a)

    if -EPS <= value <= EPS:
        return 0

    return 1 if value > 0 else -1


def point_on_segment(a, b, p):
    """Check whether 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 point 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):
    """Return center of the circle through non-collinear points a, b, c."""
    mid_ab = (a + b) / 2.0
    mid_ac = (a + c) / 2.0

    perp_ab = (b - a).perp()
    perp_ac = (c - a).perp()

    return line_line_intersection(mid_ab, mid_ab + perp_ab,
                                  mid_ac, mid_ac + perp_ac)


def norm_2pi(angle):
    """Normalize angle into [0, 2*pi)."""
    angle = math.fmod(angle, FULL)

    if angle < 0:
        angle += FULL

    return angle


def make_arc(p0, p1, p2):
    """Convert three input points into an Arc."""
    arc = Arc()

    arc.a = p0
    arc.b = p1
    arc.c = p2

    # Degenerate circular arc: treat as segment.
    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


def on_circle_arc(arc, p):
    """
    Check whether point p belongs to circular arc.
    Assumes p is on the supporting circle.
    """
    side_c = (arc.b - arc.a).cross(arc.c - arc.a)
    side_p = (arc.b - arc.a).cross(p - arc.a)

    # Points on chord line are endpoints/touching boundary points.
    if abs(side_p) < EPS:
        return True

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


def arc_interval(arc):
    """
    Represent an arc on its circle as a counterclockwise angular interval:
    (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 = norm_2pi(ang_b - ang_a)
    span_c = norm_2pi(ang_c - ang_a)

    # If c is encountered while going CCW from a to b,
    # then the intended arc is a -> b.
    if span_c <= span_b:
        return ang_a, span_b

    # Otherwise the intended arc is b -> a.
    return ang_b, FULL - span_b


def arc_overlap(x, y):
    """Return positive angular overlap length for same-circle arcs."""
    start_x, len_x = arc_interval(x)
    start_y, len_y = arc_interval(y)

    # Work in coordinate system where x starts at angle 0.
    shift = norm_2pi(start_y - start_x)

    overlap = 0.0

    def add(lo, hi):
        """Add overlap of interval [lo, hi] with [0, len_x]."""
        nonlocal overlap

        left = max(lo, 0.0)
        right = min(hi, len_x)

        if right > left:
            overlap += right - left

    # y interval does not wrap.
    if shift + len_y <= FULL:
        add(shift, shift + len_y)
    else:
        # y interval wraps around 2*pi.
        add(shift, FULL)
        add(0.0, shift + len_y - FULL)

    return overlap


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

    # Foot of perpendicular from center to line.
    foot = a + direction * ((center - a).dot(direction))

    dist = (center - foot).norm()

    if dist > r + EPS:
        return []

    h_sq = r * r - dist * dist

    # Clamp tiny negative caused by roundoff.
    if h_sq < 0:
        h_sq = 0.0

    h = math.sqrt(h_sq)

    if h < EPS:
        return [foot]

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


def intersect_circles(c1, r1, c2, r2):
    """Return intersection points of two circles."""
    d = c2 - c1
    dist = d.norm()

    # Separate, nested, or concentric.
    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)

    h_sq = r1 * r1 - a * a

    if h_sq < -EPS:
        return []

    if h_sq < 0:
        h_sq = 0.0

    h = math.sqrt(h_sq)

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

    if h < EPS:
        return [mid]

    return [mid + perp_dir * h, mid - perp_dir * h]


def intersect_arcs(x, y):
    """
    Intersect two processed arcs.
    Returns:
      infinite: bool
      points: list of finite crossing points
    """
    infinite = False
    points = []

    # Segment-segment case.
    if x.is_segment and y.is_segment:
        d1 = x.b - x.a
        d2 = y.b - y.a

        # Parallel.
        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()
            length = (x.b - x.a).dot(u)

            pos_a = (y.a - x.a).dot(u)
            pos_b = (y.b - x.a).dot(u)

            lo = max(0.0, min(pos_a, pos_b))
            hi = min(length, max(pos_a, pos_b))

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

            return infinite, points

        # Non-parallel: one line intersection.
        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

    # 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

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

        return False, points

    # Circular arc vs circular arc on the 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, []

        # If there is 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

    # Circular arcs on different circles.
    for p in intersect_circles(x.center, x.r, y.center, y.r):
        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))

    raw = []

    # Read triples of points.
    for _ in range(n):
        x1 = float(next(it))
        y1 = float(next(it))
        x2 = float(next(it))
        y2 = float(next(it))
        x3 = float(next(it))
        y3 = float(next(it))

        raw.append((Point(x1, y1), Point(x2, y2), Point(x3, y3)))

    # Build arcs.
    arcs = [make_arc(a, b, c) for a, b, c in raw]

    all_points = []
    has_infinite = False

    # Check all pairs.
    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 intersection 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()
```

---

## 5. Compressed editorial

Each arc is determined by endpoints `A`, `B` and intermediate point `C`. If the three points are collinear, treat it as segment `AB`. Otherwise compute the circumcircle. A point on the circle belongs to the arc iff it lies on the same side of chord `AB` as `C`, with endpoints included.

Check every pair of arcs.

- Segment/segment: use standard segment intersection. Collinear overlapping segments imply `Infinity`.
- Segment/arc: intersect the segment’s supporting line with the circle, then filter candidates by segment containment and arc containment.
- Arc/arc:
  - If circles are different, compute circle-circle intersections and filter by both arcs.
  - If circles coincide, convert both arcs to angular intervals. Positive overlap means `Infinity`; otherwise only common endpoints can be intersections.

Collect all finite intersection points, remove duplicates using distance `< 1e-3`, sort by `(x, y)`, and print with three decimal digits.

Complexity is `O(N^2)`, since each pair is processed in constant time.