## 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. Provided C++ solution with detailed comments

```cpp
#include <bits/stdc++.h> // Include almost all standard C++ library headers.

using namespace std; // Avoid writing std:: before standard library names.

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

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

// Input operator for vectors.
template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) { // Read each vector element.
        in >> x;
    }
    return in;
};

// Output operator for vectors.
template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) { // Print each vector element.
        out << x << ' ';
    }
    return out;
};

// Coordinates are stored as doubles.
using coord_t = double;

// 2D point/vector structure.
struct Point {
    // Epsilon for floating-point comparisons.
    static constexpr coord_t eps = 1e-9;

    // Value of pi.
    static inline const coord_t PI = acos((coord_t)-1.0);

    coord_t x, y; // Coordinates.

    // Constructor.
    Point(coord_t x = 0, coord_t y = 0) : x(x), y(y) {}

    // Vector addition.
    Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }

    // Vector subtraction.
    Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }

    // Multiplication by scalar.
    Point operator*(coord_t c) const { return Point(x * c, y * c); }

    // Division by scalar.
    Point operator/(coord_t c) const { return Point(x / c, y / c); }

    // Dot product.
    coord_t operator*(const Point& p) const { return x * p.x + y * p.y; }

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

    // Exact equality; mostly unused for geometric comparisons.
    bool operator==(const Point& p) const { return x == p.x && y == p.y; }

    // Exact inequality.
    bool operator!=(const Point& p) const { return x != p.x || y != p.y; }

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

    // Reverse lexicographic comparison.
    bool operator>(const Point& p) const {
        return x != p.x ? x > p.x : y > p.y;
    }

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

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

    // Squared vector length.
    coord_t norm2() const { return x * x + y * y; }

    // Vector length.
    coord_t norm() const { return sqrt(norm2()); }

    // Polar angle.
    coord_t angle() const { return atan2(y, x); }

    // Rotate vector by angle a.
    Point rotate(coord_t a) const {
        return Point(x * cos(a) - y * sin(a), x * sin(a) + y * cos(a));
    }

    // Perpendicular vector rotated 90 degrees counterclockwise.
    Point perp() const { return Point(-y, x); }

    // Unit vector in same direction.
    Point unit() const { return *this / norm(); }

    // Unit normal vector.
    Point normal() const { return perp().unit(); }

    // Projection of p onto this vector.
    Point project(const Point& p) const {
        return *this * (*this * p) / norm2();
    }

    // Reflection of p across the line in direction of this vector.
    Point reflect(const Point& p) const {
        return *this * 2 * (*this * p) / norm2() - p;
    }

    // Print point.
    friend ostream& operator<<(ostream& os, const Point& p) {
        return os << p.x << ' ' << p.y;
    }

    // Read point.
    friend istream& operator>>(istream& is, Point& p) {
        return is >> p.x >> p.y;
    }

    // Orientation test for triangle abc.
    friend int ccw(const Point& a, const Point& b, const Point& c) {
        // Signed area multiplied by 2.
        coord_t v = (b - a) ^ (c - a);

        // Nearly collinear.
        if(-eps <= v && v <= eps) {
            return 0;
        } else if(v > 0) {
            return 1; // Counterclockwise.
        } else {
            return -1; // Clockwise.
        }
    }

    // Check if p lies on segment ab.
    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;
    }

    // Check if p lies inside or on triangle abc.
    // This helper is not used in the final solution.
    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);
    }

    // Intersection point of two non-parallel lines a1b1 and a2b2.
    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));
    }

    // Check if two vectors are collinear.
    friend bool collinear(const Point& a, const Point& b) {
        return abs(a ^ b) < eps;
    }

    // Circumcenter of triangle abc.
    friend Point circumcenter(const Point& a, const Point& b, const Point& c) {
        // Midpoint of AB.
        Point mid_ab = (a + b) / 2.0;

        // Midpoint of AC.
        Point mid_ac = (a + c) / 2.0;

        // Direction perpendicular to AB.
        Point perp_ab = (b - a).perp();

        // Direction perpendicular to AC.
        Point perp_ac = (c - a).perp();

        // Circumcenter is intersection of two perpendicular bisectors.
        return line_line_intersection(
            mid_ab, mid_ab + perp_ab, mid_ac, mid_ac + perp_ac
        );
    }

    // Area contribution of a circular arc; unused here.
    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;
    }

    // Intersections of two circles.
    friend vector<Point> intersect_circles(
        const Point& c1, coord_t r1, const Point& c2, coord_t r2
    ) {
        Point d = c2 - c1;       // Vector from first center to second.
        coord_t dist = d.norm(); // Distance between centers.

        // No intersection if circles are separate, nested, or concentric.
        if(dist > r1 + r2 + eps || dist < abs(r1 - r2) - eps || dist < eps) {
            return {};
        }

        // Distance from c1 to the base point along line c1-c2.
        coord_t a = (r1 * r1 - r2 * r2 + dist * dist) / (2 * dist);

        // Squared distance from base point to intersection points.
        coord_t h_sq = r1 * r1 - a * a;

        if(h_sq < -eps) {
            return {};
        }

        // Avoid negative due to floating-point error.
        if(h_sq < 0) {
            h_sq = 0;
        }

        coord_t h = sqrt(h_sq);

        // Base point.
        Point mid = c1 + d.unit() * a;

        // Perpendicular direction.
        Point perp_dir = d.perp().unit();

        // Tangent circles: one intersection.
        if(h < eps) {
            return {mid};
        }

        // Two intersections.
        return {mid + perp_dir * h, mid - perp_dir * h};
    }

    // Ray-segment intersection helper; unused in final solution.
    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;
    }
};

// Internal representation of an input arc.
struct Arc {
    bool is_segment;      // True if input points are collinear.
    Point a, b, c;        // Endpoint a, endpoint b, intermediate c.
    Point center;         // Circle center if not a segment.
    coord_t r;            // Circle radius if not a segment.
};

// Result of intersecting two arcs.
struct Crossing {
    bool infinite;        // True if infinitely many intersections exist.
    vector<Point> pts;    // Finite intersection points.
};

int n; // Number of arcs.

// Raw input triples.
vector<array<Point, 3>> raw_arcs;

// Read input.
void read() {
    cin >> n;
    raw_arcs.assign(n, {});

    for(auto& t: raw_arcs) {
        cin >> t[0] >> t[1] >> t[2];
    }
}

// Normalize an angle to [0, 2*pi).
coord_t norm_2pi(coord_t a) {
    coord_t full = 2 * Point::PI;

    a = fmod(a, full);

    if(a < 0) {
        a += full;
    }

    return a;
}

// Convert three input points into Arc object.
Arc make_arc(const Point& p0, const Point& p1, const Point& p2) {
    Arc arc;

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

    // If collinear, treat as segment.
    if(ccw(p0, p1, p2) == 0) {
        arc.is_segment = true;
    } else {
        arc.is_segment = false;

        // Unique circle through the three points.
        arc.center = circumcenter(p0, p1, p2);

        // Radius.
        arc.r = (p0 - arc.center).norm();
    }

    return arc;
}

// Check whether point p belongs to circular arc.
// Assumes p is already on the same supporting circle.
bool on_circle_arc(const Arc& arc, const Point& p) {
    // Side of intermediate point c relative to chord ab.
    coord_t side_c = (arc.b - arc.a) ^ (arc.c - arc.a);

    // Side of candidate point p relative to chord ab.
    coord_t side_p = (arc.b - arc.a) ^ (p - arc.a);

    // Endpoints and chord-line points are accepted.
    if(fabs(side_p) < Point::eps) {
        return true;
    }

    // p must lie on same side as c.
    return (side_c > 0) == (side_p > 0);
}

// Return angular interval describing a circular arc.
// Result is {start_angle, length}, traversed counterclockwise.
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();

    // Counterclockwise span from a to b.
    coord_t span_b = norm_2pi(ang_b - ang_a);

    // Counterclockwise span from a to c.
    coord_t span_c = norm_2pi(ang_c - ang_a);

    // If c lies on CCW arc from a to b, use that interval.
    if(span_c <= span_b) {
        return {ang_a, span_b};
    }

    // Otherwise the intended arc is the other one, from b to a.
    return {ang_b, 2 * Point::PI - span_b};
}

// Compute angular overlap length of two arcs on the same circle.
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;

    // Shift y's start into coordinate system where x starts at 0.
    coord_t shift = norm_2pi(start_y - start_x);

    coord_t overlap = 0;

    // Add overlap of [lo, hi] with x interval [0, len_x].
    auto add = [&](coord_t lo, coord_t hi) {
        coord_t l = max(lo, (coord_t)0);
        coord_t r = min(hi, len_x);

        if(r > l) {
            overlap += r - l;
        }
    };

    // If y interval does not wrap around 2*pi.
    if(shift + len_y <= full) {
        add(shift, shift + len_y);
    } else {
        // Wrapped interval consists of two parts.
        add(shift, full);
        add(0, shift + len_y - full);
    }

    return overlap;
}

// Intersect infinite line ab with circle.
vector<Point> line_circle(
    const Point& a, const Point& b, const Point& center, coord_t r
) {
    // Unit direction of line.
    Point dir = (b - a).unit();

    // Orthogonal projection of center onto line.
    Point foot = a + dir * ((center - a) * dir);

    // Distance from center to line.
    coord_t dist = (center - foot).norm();

    // No intersection.
    if(dist > r + Point::eps) {
        return {};
    }

    // Half-distance from foot to intersections.
    coord_t h_sq = r * r - dist * dist;

    if(h_sq < 0) {
        h_sq = 0;
    }

    coord_t h = sqrt(h_sq);

    // Tangency.
    if(h < Point::eps) {
        return {foot};
    }

    // Two intersections.
    return {foot + dir * h, foot - dir * h};
}

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

    // Segment-segment case.
    if(x.is_segment && y.is_segment) {
        Point d1 = x.b - x.a;
        Point d2 = y.b - y.a;

        // Parallel supporting lines.
        if(fabs(d1 ^ d2) < Point::eps) {
            // Different parallel lines.
            if(ccw(x.a, x.b, y.a) != 0) {
                return res;
            }

            // Same line: project y endpoints onto x direction.
            Point u = d1.unit();

            // Length of x segment along u.
            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;

            // Overlap interval.
            coord_t lo = max((coord_t)0, min(pos_a, pos_b));
            coord_t hi = min(len, max(pos_a, pos_b));

            // Positive-length overlap gives infinitely many points.
            if(hi > lo + Point::eps) {
                res.infinite = true;
            }
            // Single touching point.
            else if(hi > lo - Point::eps) {
                res.pts.push_back(x.a + u * ((lo + hi) / 2));
            }

            return res;
        }

        // Non-parallel lines intersect at one point.
        Point p = line_line_intersection(x.a, x.b, y.a, y.b);

        // Keep only if it lies on both segments.
        if(point_on_segment(x.a, x.b, p) && point_on_segment(y.a, y.b, p)) {
            res.pts.push_back(p);
        }

        return res;
    }

    // Segment-circle-arc case.
    if(x.is_segment != y.is_segment) {
        const Arc& seg = x.is_segment ? x : y;
        const Arc& cir = x.is_segment ? y : x;

        // Intersect segment's supporting line with circle.
        for(const Point& p: line_circle(seg.a, seg.b, cir.center, cir.r)) {
            // Candidate must be on segment and on arc.
            if(point_on_segment(seg.a, seg.b, p) && on_circle_arc(cir, p)) {
                res.pts.push_back(p);
            }
        }

        return res;
    }

    // Circle-arc vs circle-arc with same supporting circle.
    if((x.center - y.center).norm() < 1e-6 && fabs(x.r - y.r) < 1e-6) {
        // Positive angular overlap means infinitely many intersections.
        if(arc_overlap(x, y) > 1e-7) {
            res.infinite = true;
            return res;
        }

        // Otherwise they can only share endpoints.
        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;
    }

    // Distinct circles: at most two intersection points.
    for(const Point& p: intersect_circles(x.center, x.r, y.center, y.r)) {
        // Keep only points lying on both arcs.
        if(on_circle_arc(x, p) && on_circle_arc(y, p)) {
            res.pts.push_back(p);
        }
    }

    return res;
}

// Main solving routine.
void solve() {
    vector<Arc> arcs;

    // Build processed arc objects.
    for(auto& t: raw_arcs) {
        arcs.push_back(make_arc(t[0], t[1], t[2]));
    }

    bool infinite = false; // Whether any pair overlaps infinitely.
    vector<Point> pts;     // All found finite intersections, with duplicates.

    // Check every pair of arcs.
    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 any pair has infinitely many intersections, output Infinity.
    if(infinite) {
        cout << "Infinity\n";
        return;
    }

    vector<Point> uniq;

    // Remove duplicate points.
    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 by x, then by y.
    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;
    });

    // Print number of finite crossing points.
    cout << uniq.size() << '\n';

    // Print coordinates to three decimals.
    cout << fixed << setprecision(3);

    for(const Point& p: uniq) {
        // Avoid printing negative zero.
        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() {
    // Fast input/output.
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;

    // There is only one test case.
    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.