## 1) Abridged problem statement

You are given **N (1 ≤ N ≤ 100)** circles on the plane. The plane initially consists of normal grain everywhere.

Each circle represents one UFO landing over that disk:
- landing on **grain** → becomes **burned**
- landing on **burned** → becomes **inverse grain**
- landing on **inverse grain** → becomes **burned**

So each landing **toggles** the state in its disk:
- state depends on how many disks cover the point:
  - covered by **odd** number of circles → **burned**
  - covered by **even positive** number → **inverse grain**
  - covered by **0** circles → normal grain (not asked)

Output:
1) total area of burned region (odd coverage)
2) total area of inverse grain region (even, ≥ 2 coverage)

Accuracy: at least 3 digits after decimal.

---

## 2) Detailed editorial (how the provided solution works)

### Key observation: coverage parity
For any point \(p\), let \(c(p)\) be the number of circles whose **interior** contains \(p\).
- If \(c(p)=0\): unchanged grain.
- If \(c(p)>0\) and \(c(p)\) is odd: burned.
- If \(c(p)>0\) and \(c(p)\) is even: inverse grain.

So the task is to compute the area of regions where the coverage count has a given parity (odd/even>0).

### Why circle intersections matter
The coverage count only changes when crossing a circle boundary. Therefore, the plane is partitioned into faces whose boundaries are circular arcs between intersection points.

If we can sum the area of each face and know its parity, we're done—but explicitly building faces of the arrangement is complex.

### Using Green's theorem to get area from boundary arcs
A standard trick: compute area by integrating along the boundary.

Green's theorem gives the signed area of a closed curve:
\[
A = \frac{1}{2}\oint (x\,dy - y\,dx)
\]

For a **circle arc** on a circle with center \((c_x,c_y)\) and radius \(r\), going from angle \(\theta_1\) to \(\theta_2\), the solution uses a closed-form of that integral:

\[
\text{arc\_area} =
\frac{1}{2}\left(
r c_x(\sin\theta_2 - \sin\theta_1)
- r c_y(\cos\theta_2 - \cos\theta_1)
+ r^2(\theta_2-\theta_1)
\right)
\]

This is a **signed contribution**: reversing direction negates it.

### Turning arcs into contributions to "odd area" and "even area"
Each circle boundary arc separates two adjacent faces:
- one side is "inside that circle"
- the other side is "outside that circle"

If we know the coverage parity on each side, we can decide whether this arc contributes (with sign) to burned or inverse totals.

Instead of constructing faces, the code processes every circle independently:

1. **For each circle i**, collect "events" on its boundary:
   - all intersection points between circle i and every other circle
   - plus **two extra points** (leftmost and rightmost) to ensure at least two events even if there are no intersections (this makes the circle boundary still get processed as arcs).

2. Sort events by polar angle around circle center.
   Adjacent events define an arc segment on that circle.

3. For each arc between consecutive events:
   - pick a **test point just inside** the circle along the mid-angle:
     \[
     p_\text{in} = c_i + \hat{u} \cdot (r_i - \varepsilon)
     \]
   - pick a **test point just outside**:
     \[
     p_\text{out} = c_i + \hat{u} \cdot (r_i + \varepsilon)
     \]
   - count how many circles strictly contain each test point → \(cnt_\text{in}, cnt_\text{out}\)

4. Compute the signed area contribution `piece = arc_area(...)` for the arc (using the CCW direction between angles).

5. Add/subtract this `piece` into the correct totals:
   - The boundary of a region contributes with orientation; the same geometric arc is seen with opposite orientation from the two sides.
   - The code effectively does:
     - if inside side is odd → add `piece` to burned
     - if inside side is even positive → add `piece` to inverse
     - if outside side is odd → subtract `piece` from burned
     - if outside side is even positive → subtract `piece` from inverse
   - It also ignores the outside side when count is 0 (that corresponds to the infinite "normal grain" region which should not be included).

This works because when summing over all arcs, contributions along internal boundaries cancel appropriately, and only the correct region boundaries remain in the totals—exactly like computing area via line integrals.

### Correctness sketch
- The arrangement splits the plane into faces with constant coverage count.
- For any face \(F\), its boundary is a set of circular arcs; traversing the boundary with consistent orientation, the sum of `arc_area` over its boundary equals its area (Green's theorem).
- The algorithm assigns each oriented arc contribution to the face on each side according to parity, using inside/outside test points.
- Summing over all arcs accumulates each face's area exactly once into either burned (odd) or inverse (even positive), while faces with 0 coverage are excluded.

### Complexity
- Intersections: for each circle \(i\), it checks all \(j\): \(O(N^2)\) circle-pair computations.
- Number of events per circle: \(O(N)\), so arcs per circle \(O(N)\), total arcs \(O(N^2)\).
- For each arc it counts covering circles by scanning all circles: \(O(N)\).
- Total: \(O(N^3)\), with \(N \le 100\) (about 1e6 checks), acceptable.

---

## 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};
    }
};

int n;
vector<Point> centers;
vector<coord_t> radii;

void read() {
    cin >> n;
    centers.resize(n);
    radii.resize(n);
    for(int i = 0; i < n; i++) {
        cin >> centers[i] >> radii[i];
    }
}

void solve() {
    // We will start by building a planar graph of the circles, where the arcs
    // are the edges. We will have a vertex for every intersection point, and
    // also add two additional arbitrary points per circle (this is for
    // convenience). It's clear that there are O(N^2) vertices and edges, and
    // trivially there would be O(N^2) faces too (due to Euler, or V - E + F = 1
    // + C). We are interested in the area of each face, and if it's covered by
    // an even or odd number of circles.
    //
    //    1) For the area, we can use Green's theorem, or for an arc from θ₁ to
    //       θ₂ on a circle with center (cx, cy) and radius r, the signed area
    //       contribution is:
    //
    //           0.5 * (r * cx * (sin θ₂ - sin θ₁) -
    //                  r * cy * (cos θ₂ - cos θ₁) +
    //                  r^2 * (θ₂ - θ₁))
    //
    //       More details in:
    //           https://en.wikipedia.org/wiki/Green%27s_theorem
    //
    //    2) For the parity, we can choose some point inside of the face. A
    //       simple example would be to choose an arbitrary vertex in the face,
    //       get the two adjacent edges, sum the vectors (get director in the
    //       middle of them), and then move with "eps" in that direction. There
    //       are other approaches too. We can then iterate through all circles
    //       and see how many include this particular point.
    //
    // To build the graph, we will initially for every circle find all
    // intersection points, and two arbitrary points (say center-(R,0), and
    // center+(R,0)), then sort by angle and add edges between the adjacent
    // vertices. Then finding faces is also not hard - we create an embedding of
    // the planar graph (sort the neighbours by angle), and do a walk from each
    // point clockwise. All in all, the complexity is O(N^3).
    //
    // However, this solution is a bit complicated due to all the planar graph
    // logic. Instead, we can notice that we don't actually have to explicitly
    // build the faces - we can just go through the arcs and figure out how they
    // contribute to the two answers (burned and inverse grains). Particularly,
    // we are doing Green's theorem which already computes the area as signed
    // contribution from every, so instead for a given arc we can compute it's
    // contribution on both sides. For every arc we will choose an inner and an
    // outer point, and count the parity of the number of circles that cover the
    // inner point. This means that we will get CW contribution for that parity
    // and CCW for the opposite (or we can do the inverse, doesn't matter). We
    // should only be careful for the case when the count is equal, as we don't
    // want the contribution from the outer face. The complexity is still the
    // same, but we avoid a lot of the more complicated logic.

    vector<vector<pair<coord_t, Point>>> events(n);

    for(int i = 0; i < n; i++) {
        Point right = centers[i] + Point(radii[i], 0);
        Point left = centers[i] - Point(radii[i], 0);
        events[i].emplace_back((right - centers[i]).angle(), right);
        events[i].emplace_back((left - centers[i]).angle(), left);

        for(int j = 0; j < n; j++) {
            if(i == j) {
                continue;
            }
            vector<Point> pts =
                intersect_circles(centers[i], radii[i], centers[j], radii[j]);
            for(auto& p: pts) {
                coord_t ang = (p - centers[i]).angle();
                events[i].emplace_back(ang, p);
            }
        }

        sort(events[i].begin(), events[i].end());

        vector<pair<coord_t, Point>> unique_events;
        for(auto& e: events[i]) {
            if(unique_events.empty() ||
               abs(unique_events.back().first - e.first) > Point::eps) {
                unique_events.push_back(e);
            }
        }
        events[i] = unique_events;
    }

    coord_t burned = 0.0;
    coord_t inverse = 0.0;

    for(int i = 0; i < n; i++) {
        int m = events[i].size();
        if(m < 2) {
            continue;
        }

        for(int j = 0; j < m; j++) {
            Point p1 = events[i][j].second;
            Point p2 = events[i][(j + 1) % m].second;
            coord_t ang1 = events[i][j].first;
            coord_t ang2 = events[i][(j + 1) % m].first;
            if(ang2 < ang1) {
                ang2 += 2 * Point::PI;
            }

            coord_t mid_ang = (ang1 + ang2) / 2.0;
            Point mid_dir(cos(mid_ang), sin(mid_ang));
            Point test_inside = centers[i] + mid_dir * (radii[i] - 1e-6);
            Point test_outside = centers[i] + mid_dir * (radii[i] + 1e-6);

            auto count_circles = [&](Point p) {
                int cnt = 0;
                for(int k = 0; k < n; k++) {
                    if((p - centers[k]).norm() < radii[k] - Point::eps) {
                        cnt++;
                    }
                }
                return cnt;
            };

            int cnt_inside = count_circles(test_inside);
            int cnt_outside = count_circles(test_outside);

            coord_t piece = arc_area(centers[i], radii[i], p1, p2);

            if(cnt_inside % 2 == 1) {
                burned += piece;
            } else if(cnt_inside > 0) {
                inverse += piece;
            }

            if(cnt_outside % 2 == 1) {
                burned -= piece;
            } else if(cnt_outside > 0) {
                inverse -= piece;
            }
        }
    }

    cout << fixed << setprecision(5);
    cout << burned << " " << inverse << "\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();
        // cout << "Case #" << test << ": ";
        solve();
    }

    return 0;
}
```

---

## 4) Python solution (same approach, with detailed comments)

```python
import math
import sys

EPS = 1e-9
PI = math.acos(-1.0)

class Point:
    __slots__ = ("x", "y")
    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, c):     return Point(self.x * c, self.y * c)
    def __truediv__(self, c): return Point(self.x / c, self.y / c)

    # Dot and cross
    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.hypot(self.x, self.y)

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

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

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

def arc_area(center: Point, r: float, p1: Point, p2: Point) -> float:
    """
    Signed area contribution of the CCW arc from p1 to p2 on the circle
    (center, r), using the same closed-form integral as the C++ code.
    """
    t1 = (p1 - center).angle()
    t2 = (p2 - center).angle()
    if t2 < t1 - EPS:
        t2 += 2.0 * PI
    d = t2 - t1
    cx, cy = center.x, center.y
    area = r * cx * (math.sin(t2) - math.sin(t1)) \
         - r * cy * (math.cos(t2) - math.cos(t1)) \
         + r * r * d
    return 0.5 * area

def intersect_circles(c1: Point, r1: float, c2: Point, r2: float):
    """
    Return intersection points (0/1/2) of circles (c1,r1) and (c2,r2).
    Mirrors the C++ logic (reject coincident centers dist < EPS).
    """
    d = c2 - c1
    dist = d.norm()

    # No intersections (separate, contained, or coincident centers)
    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.0:
        h2 = 0.0
    h = math.sqrt(h2)

    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 solve():
    data = sys.stdin.read().strip().split()
    if not data:
        return
    it = iter(data)
    n = int(next(it))
    centers = []
    radii = []
    for _ in range(n):
        x = float(next(it)); y = float(next(it)); r = float(next(it))
        centers.append(Point(x, y))
        radii.append(r)

    # Collect events (angle, Point) for each circle
    events = [[] for _ in range(n)]

    for i in range(n):
        c = centers[i]
        r = radii[i]

        # Two arbitrary points to guarantee at least 2 events
        right = c + Point(r, 0.0)
        left  = c - Point(r, 0.0)
        events[i].append(((right - c).angle(), right))
        events[i].append(((left  - c).angle(), left))

        # All intersection points with other circles
        for j in range(n):
            if i == j:
                continue
            for p in intersect_circles(c, r, centers[j], radii[j]):
                events[i].append(((p - c).angle(), p))

        # Sort by angle
        events[i].sort(key=lambda t: t[0])

        # Deduplicate by angle (within EPS)
        uniq = []
        for ang, p in events[i]:
            if not uniq or abs(uniq[-1][0] - ang) > EPS:
                uniq.append((ang, p))
        events[i] = uniq

    def count_circles(p: Point) -> int:
        """Count circles whose interior strictly contains p."""
        cnt = 0
        for k in range(n):
            if (p - centers[k]).norm() < radii[k] - EPS:
                cnt += 1
        return cnt

    burned = 0.0
    inverse = 0.0

    # Process each circle's consecutive arcs
    for i in range(n):
        m = len(events[i])
        if m < 2:
            continue

        c = centers[i]
        r = radii[i]

        for j in range(m):
            ang1, p1 = events[i][j]
            ang2, p2 = events[i][(j + 1) % m]

            # Make ang2 >= ang1 by wrapping around
            if ang2 < ang1:
                ang2 += 2.0 * PI

            # Mid-angle direction to pick test points
            mid_ang = 0.5 * (ang1 + ang2)
            mid_dir = Point(math.cos(mid_ang), math.sin(mid_ang))

            # Slightly inside/outside to avoid boundary ambiguity
            test_inside = c + mid_dir * (r - 1e-6)
            test_outside = c + mid_dir * (r + 1e-6)

            cnt_in = count_circles(test_inside)
            cnt_out = count_circles(test_outside)

            piece = arc_area(c, r, p1, p2)

            # Add piece to the classification of the inside side
            if cnt_in % 2 == 1:
                burned += piece
            elif cnt_in > 0:
                inverse += piece

            # Subtract piece to the classification of the outside side
            if cnt_out % 2 == 1:
                burned -= piece
            elif cnt_out > 0:
                inverse -= piece

    # Print with enough precision
    print(f"{burned:.5f} {inverse:.5f}")

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

---

## 5) Compressed editorial

- Each point is covered by \(c\) circles; after all landings:
  - \(c=0\): normal
  - \(c\) odd: burned
  - \(c\) even and \(>0\): inverse
- Boundaries are circle arcs between intersection points. Use Green's theorem to compute area from boundary integrals.
- For each circle, gather all intersection points on it + two arbitrary points, sort by polar angle, forming arcs between consecutive points.
- For each arc, compute signed contribution `piece` via the closed-form arc integral.
- Determine which regions lie on the two sides of the arc by testing a point slightly inside and slightly outside; count how many circles contain the test point to get parity.
- Add `piece` to burned/inverse according to inside parity; subtract `piece` according to outside parity (ignore count=0 to avoid including the infinite outside face).
- Total complexity \(O(N^3)\) (≤ 100), outputs burned and inverse areas.
