#include <bits/stdc++.h>   using namespace std;   const double EPS = 1e-9;   const double INF = 1e6;   const double PI = atan2(0, -1);   const int maxn = 550;   inline int sgn(double x) {     if (fabs(x) < EPS) return 0;     return x < 0 ? -1 : 1;   }   inline int iseq(double x, double y) { return sgn(x - y) == 0; }   struct Point {     double x, y;     Point(double x = 0, double y = 0) : x(x), y(y) {}     double Angle() { return atan2(y, x); }   };   inline Point operator+(Point A, Point B) { return Point(A.x + B.x, A.y + B.y); }   inline Point operator-(Point A, Point B) { return Point(A.x - B.x, A.y - B.y); }   inline Point operator*(double x, Point A) { return Point(x * A.x, x * A.y); }   inline double operator*(Point A, Point B) { return A.x * B.x + A.y * B.y; }   inline double operator%(Point A, Point B) { return A.x * B.y - A.y * B.x; }   inline double Length2(Point A) { return A * A; }   inline double Length(Point A) { return sqrt(A * A); }   inline double Distance2(Point A, Point B) { return Length2(A - B); }   inline double Distance(Point A, Point B) { return Length(A - B); }   inline bool operator==(Point A, Point B) { return iseq(Distance(A, B), 0); }   inline bool operator<(Point A, Point B) {     return iseq(A.x, B.x) ? sgn(A.y - B.y) == -1 : sgn(A.x - B.x) == -1;   }   struct Line {     Point P, Q;     Line() {}     Line(Point A, Point B) {       P = A;       Q = B;     }     Point Direction() { return Q - P; }   };   inline int IsOnLine(Point P, Line l) { return sgn((l.P - P) % (l.Q - P)) == 0; }   inline int IsOnSegment(Point P, Line l) {     if (P == l.P || P == l.Q) return 1;     return sgn((l.P - P) % (l.Q - P)) == 0 && sgn((l.P - P) * (l.Q - P)) <= 0;   }   inline bool IsSegmentOverlap(Line A, Line B) {     if (iseq(A.Direction() % B.Direction(), 0))       return IsOnSegment(A.P, B) + IsOnSegment(A.Q, B) + IsOnSegment(B.P, A) +                  IsOnSegment(B.Q, A) >=              2;     else       return false;   }   inline bool IsSegmentIntersected(Line A, Line B) {     if (IsOnSegment(A.P, B) || IsOnSegment(A.Q, B)) return true;     if (IsOnSegment(B.P, A) || IsOnSegment(B.Q, A)) return true;     int sgn1 = sgn((A.P - B.P) % B.Direction()),         sgn2 = sgn((A.Q - B.P) % B.Direction());     int sgn3 = sgn((B.P - A.P) % A.Direction()),         sgn4 = sgn((B.Q - A.P) % A.Direction());     return sgn1 * sgn2 == -1 && sgn3 * sgn4 == -1;   }   inline Point getLineIntersection(Line A, Line B) {     Point v = A.Direction(), w = B.Direction();     Point u = B.P - A.P;     return A.P + ((w % u) / (w % v)) * v;   }   int n;   vector<Point> Rect[maxn];   double area1, area2;   inline double getPolygonArea(const vector<Point> &A) {     double ans = 0;     for (auto j = 1u; j + 1 < A.size(); ++j)       ans += (A[j] - A[0]) % (A[j] - A[0]) * 0.5;     return ans;   }   inline bool IsInPolygon(Point P, const vector<Point> &A) {     double area1 = getPolygonArea(A), area2 = 0.0;     for (auto j = 0u; j + 1 < A.size(); ++j)       area2 += (A[j] - P) % (A[j + 1] - P) * 0.5;     return iseq(area1, area2);   }   inline bool IsPolygonOverlap(vector<Point> P[], int i, int j) {     int sgn = 1;     for (auto k = 0u; k < P[i].size(); ++k)       if (!IsInPolygon(P[i][k], P[j])) {         sgn = 0;         break;       }     if (!sgn) return false;     if (iseq(getPolygonArea(P[i]), getPolygonArea(P[j]))) return i < j;     return true;   }   struct info {     Point P;     double ang;     int delta;     info() {}     info(Point x, double y, int z) {       P = x;       ang = y;       delta = z;     }   };   inline int operator<(const info &A, const info &B) {     if (iseq(A.ang, B.ang))       return A.delta > B.delta;     else       return A.ang < B.ang;   }   inline double getPosition(Point P, Line l) {     return ((P - l.P) * l.Direction()) / (l.Direction() * l.Direction());     return (P.x - l.P.x) / (l.Q.x - l.P.x);   }   double ans[maxn];   double getAreaUnion(vector<Point> P[], int n, double *ans) {     for (int i = 1; i <= n; ++i) ans[i] = 0.0;     static vector<pair<double, int>> PointList;     double aans = 0;     for (int i = 1; i <= n; ++i)       for (auto j = 0u; j + 1 < P[i].size(); ++j) {         Line A(P[i][j], P[i][j + 1]);         PointList.clear();         for (int k = 1; k <= n; ++k)           if (i != k)             for (auto w = 0u; w + 1 < P[k].size(); ++w) {               Line B(P[k][w], P[k][w + 1]);               int p1 = sgn((B.P - A.P) % A.Direction());               int p2 = sgn((B.Q - A.P) % A.Direction());               if (!p1 && !p2) {                 if (i < k && sgn(A.Direction() * B.Direction()) == 1) {                   PointList.push_back(                       make_pair(min(1.0, max(getPosition(B.P, A), 0.0)), -1));                   PointList.push_back(                       make_pair(min(1.0, max(getPosition(B.Q, A), 0.0)), 1));                 }               } else {                 Point tp = getLineIntersection(A, B);                 if (p1 >= 0 && p2 < 0)                   PointList.push_back(                       make_pair(min(1.0, max(getPosition(tp, A), 0.0)), -1));                 if (p1 < 0 && p2 >= 0)                   PointList.push_back(                       make_pair(min(1.0, max(getPosition(tp, A), 0.0)), 1));               }             }         PointList.push_back(make_pair(0.0, 1));         PointList.push_back(make_pair(1.0, -1));         sort(PointList.begin(), PointList.end());         double S0 = A.P % A.Q * 0.5;         double lst = 0;         int now = 0;         for (auto l = 0u, r = 0u; l < PointList.size();) {           ans[now] += S0 * (PointList[l].first - lst);           lst = PointList[l].first;           for (r = l + 1; r < PointList.size() && iseq(PointList[r].first, lst);                ++r)             ;           for (auto w = l; w < r; ++w) now += PointList[w].second;           l = r;         }       }     return ans[1];   }   int main() {     scanf( %d , &n);     for (int i = 1; i <= n; ++i) {       for (int j = 1; j <= 4; ++j) {         Point P;         scanf( %lf%lf , &P.x, &P.y);         Rect[i].push_back(P);       }       if (sgn((Rect[i][1] - Rect[i][0]) % (Rect[i][2] - Rect[i][0])) == -1)         reverse(Rect[i].begin(), Rect[i].end());       area1 += (Rect[i][1] - Rect[i][0]) % (Rect[i][3] - Rect[i][0]);       Rect[i].push_back(Rect[i][0]);     }     area2 = getAreaUnion(Rect, n, ans);     printf( %.10lf n , area1 / area2);     return 0;   }