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

```cpp
#include <bits/stdc++.h>
// Convenience header: includes almost all standard C++ headers.

using namespace std;

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

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

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

// Output operator for vectors: prints all elements separated by spaces
template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

using coord_t = double; // All geometry uses double.

struct Point {
    // Epsilon for floating point comparisons.
    static constexpr coord_t eps = 1e-9;
    // PI constant computed via acos(-1).
    static inline const coord_t PI = acos((coord_t)-1.0);

    coord_t x, y;

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

    // Vector addition/subtraction/scalar multiply/divide
    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); }

    // Dot product
    coord_t operator*(const Point& p) const { return x * p.x + y * p.y; }
    // Cross product (2D): scalar value
    coord_t operator^(const Point& p) const { return x * p.y - y * p.x; }

    // Comparisons (exact; used mostly for sorting angles/points; careful with doubles)
    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;
    }

    // Squared length and length
    coord_t norm2() const { return x * x + y * y; }
    coord_t norm() const { return sqrt(norm2()); }

    // Angle of vector in [-pi, pi]
    coord_t angle() const { return atan2(y, x); }

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

    // Perpendicular vector (rotate 90 degrees CCW)
    Point perp() const { return Point(-y, x); }

    // Unit vector (normalized)
    Point unit() const { return *this / norm(); }

    // Unit normal (perpendicular, normalized)
    Point normal() const { return perp().unit(); }

    // Project point p onto this vector (treating *this as direction)
    Point project(const Point& p) const {
        return *this * (*this * p) / norm2();
    }

    // Reflect point p over the line through origin in direction *this
    Point reflect(const Point& p) const {
        return *this * 2 * (*this * p) / norm2() - p;
    }

    // Stream output/input for Point
    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;
    }

    // ccw test: orientation of triangle (a,b,c)
    // returns 0 if collinear, 1 if CCW, -1 if CW
    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;
        }
    }

    // Check if p is on segment [a,b] (inclusive, with eps tolerance)
    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 is inside/on boundary of triangle abc using orientation signs
    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 infinite lines (a1->b1) and (a2->b2)
    // Assumes they are not parallel.
    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));
    }

    // Are vectors a and b collinear?
    friend bool collinear(const Point& a, const Point& b) {
        return abs(a ^ b) < eps;
    }

    // Circumcenter of triangle abc (center of circle through the 3 points)
    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
        );
    }

    // Signed area contribution of the circular arc from p1 to p2 on circle
    // with given center and radius, assuming we traverse from p1 to p2 in CCW
    // direction with the *short/long?* actually the one matching increasing angle
    // after possibly adding 2*pi.
    friend coord_t arc_area(
        const Point& center, coord_t r, const Point& p1, const Point& p2
    ) {
        // Convert endpoints to angles around the center.
        coord_t theta1 = (p1 - center).angle();
        coord_t theta2 = (p2 - center).angle();

        // Ensure theta2 >= theta1 by wrapping theta2 forward by 2*pi if needed.
        if(theta2 < theta1 - eps) {
            theta2 += 2 * PI;
        }

        coord_t d_theta = theta2 - theta1;

        // Closed-form integral derived from Green's theorem.
        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;
    }

    // Compute intersection points of circles (c1,r1) and (c2,r2).
    // Returns 0,1, or 2 points. Ignores coincident circles (dist < eps).
    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();

        // No intersection if too far, one strictly inside the other, or same center.
        if(dist > r1 + r2 + eps || dist < abs(r1 - r2) - eps || dist < eps) {
            return {};
        }

        // Standard circle-circle intersection formula:
        // a = distance from c1 along line c1->c2 to the midpoint of chord.
        coord_t a = (r1 * r1 - r2 * r2 + dist * dist) / (2 * dist);

        // h^2 = r1^2 - a^2, where h is half-chord length.
        coord_t h_sq = r1 * r1 - a * a;
        if(h_sq < -eps) {
            return {};
        }
        if(h_sq < 0) {
            h_sq = 0; // clamp tiny negatives due to precision
        }
        coord_t h = sqrt(h_sq);

        // mid point on the line between centers
        Point mid = c1 + d.unit() * a;
        // perpendicular direction for chord endpoints
        Point perp_dir = d.perp().unit();

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

        // Two intersection points
        return {mid + perp_dir * h, mid - perp_dir * h};
    }
};

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

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

void solve() {
    // For each circle i, we will collect "events" (angle, point) on its boundary:
    // - all intersection points with other circles
    // - plus two extra points on opposite sides (left/right) to ensure >= 2 events
    vector<vector<pair<coord_t, Point>>> events(n);

    for(int i = 0; i < n; i++) {
        // Two arbitrary points on the circle: rightmost and leftmost.
        Point right = centers[i] + Point(radii[i], 0);
        Point left  = centers[i] - Point(radii[i], 0);

        // Store by angle relative to center.
        events[i].emplace_back((right - centers[i]).angle(), right);
        events[i].emplace_back((left - centers[i]).angle(), left);

        // Add all circle-circle intersection points with every other circle.
        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 by angle so adjacent entries define consecutive arcs.
        sort(events[i].begin(), events[i].end());

        // Remove near-duplicate angles (can happen with tangent intersections
        // or numerical duplicates).
        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;   // area with odd coverage
    coord_t inverse = 0.0;  // area with even positive coverage

    // Process each circle's arcs
    for(int i = 0; i < n; i++) {
        int m = (int)events[i].size();
        if(m < 2) continue; // should not happen due to extra points, but safe

        for(int j = 0; j < m; j++) {
            // Current event point and next (wrap-around to close the circle)
            Point p1 = events[i][j].second;
            Point p2 = events[i][(j + 1) % m].second;

            // Angles for the endpoints
            coord_t ang1 = events[i][j].first;
            coord_t ang2 = events[i][(j + 1) % m].first;

            // Ensure ang2 >= ang1 by wrapping around once
            if(ang2 < ang1) {
                ang2 += 2 * Point::PI;
            }

            // Mid-angle to choose test points on each side of the arc
            coord_t mid_ang = (ang1 + ang2) / 2.0;
            Point mid_dir(cos(mid_ang), sin(mid_ang));

            // Point just inside circle i along the radial direction
            Point test_inside = centers[i] + mid_dir * (radii[i] - 1e-6);
            // Point just outside circle i
            Point test_outside = centers[i] + mid_dir * (radii[i] + 1e-6);

            // Counts how many circles strictly contain point p
            auto count_circles = [&](Point p) {
                int cnt = 0;
                for(int k = 0; k < n; k++) {
                    // Strictly inside with eps margin (avoid boundary ambiguity)
                    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);

            // Signed area contribution for CCW arc p1->p2 on circle i
            coord_t piece = arc_area(centers[i], radii[i], p1, p2);

            // Add contribution for the region on the "inside" side
            if(cnt_inside % 2 == 1) {
                burned += piece;        // odd -> burned
            } else if(cnt_inside > 0) {
                inverse += piece;       // even positive -> inverse
            }

            // Subtract contribution for the region on the "outside" side
            // (same geometric arc but opposite orientation for the adjacent face)
            if(cnt_outside % 2 == 1) {
                burned -= piece;
            } else if(cnt_outside > 0) {
                inverse -= piece;
            }
        }
    }

    // Print results with 5 digits after decimal (>= 3 required)
    cout << fixed << setprecision(5);
    cout << burned << " " << inverse << "\n";
}

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

    int T = 1;
    // Single test case in this problem (code left generic).
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        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.