#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0);
const double eps = 1e-10;
const double INF = 1e5;
int dcmp(double x) {
  if (fabs(x) < eps)
    return 0;
  else
    return x < 0 ? -1 : 1;
}
struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(y) {}
  bool operator<(const Point &A) const {
    return dcmp(x - A.x) < 0 || (dcmp(x - A.x) == 0 && dcmp(y - A.y) < 0);
  }
  void read() { scanf("%lf%lf", &x, &y); }
};
Point operator+(const Point &A, const Point &B) {
  return Point(A.x + B.x, A.y + B.y);
}
Point operator-(const Point &A, const Point &B) {
  return Point(A.x - B.x, A.y - B.y);
}
Point operator*(const Point &A, double b) { return Point(A.x * b, A.y * b); }
Point operator/(const Point &A, double b) { return Point(A.x / b, A.y / b); }
bool operator==(const Point &A, const Point &B) {
  return dcmp(A.x - B.x) == 0 && dcmp(A.y - B.y) == 0;
}
double Dot(const Point &A, const Point &B) { return A.x * B.x + A.y * B.y; }
double Cross(const Point &A, const Point &B) { return A.x * B.y - A.y * B.x; }
double Length(const Point &A) { return sqrt(Dot(A, A)); }
double Area2(const Point &A, const Point &B, const Point &C) {
  return Cross(B - A, C - A);
}
Point Rotate(const Point &A, double ang) {
  return Point(cos(ang) * A.x - sin(ang) * A.y,
               sin(ang) * A.x + cos(ang) * A.y);
}
Point Normal(const Point &A) {
  double L = Length(A);
  return Point(-A.y / L, A.x / L);
}
struct Line {
  Point A, B, v;
  double ang;
  Line() {}
  Line(Point A, Point B) : A(A), B(B) {
    v = B - A;
    ang = atan2(v.y, v.x);
  }
  Line(double a, double b, double c) {
    v = Point(b, -a);
    if (fabs(a) > fabs(b))
      A = Point(-c / a, 0);
    else
      A = Point(0, -c / b);
    B = A + v;
    ang = atan2(v.y, v.x);
  }
  bool operator<(const Line &A) const { return ang < A.ang; }
  Point point(double t) const { return A + v * t; }
  double pos(Point p) const { return Dot(p - A, v) / Dot(v, v); }
};
int LineLineIntersection(const Line &L1, const Line &L2, Point *p,
                         double *t = 0) {
  if (dcmp(Cross(L1.v, L2.v)) == 0)
    return dcmp(Cross(L1.v, L2.A - L1.A)) == 0 ? -1 : 1;
  p[0] = L1.point(Cross(L2.v, L1.A - L2.A) / Cross(L1.v, L2.v));
  if (t) t[0] = Cross(L2.v, L1.A - L2.A) / Cross(L1.v, L2.v);
  return 1;
}
double DistanceToLine(const Point &P, const Line &L) {
  return fabs(Cross(L.v, P - L.A)) / Length(L.v);
}
Point GetLineProjection(const Point &P, const Line &L) {
  return L.point(Dot(P - L.A, L.v) / Dot(L.v, L.v));
}
int Position(const Point &P, const Line &L) {
  return dcmp(Cross(L.v, P - L.A));
}
double DistanceToSegment(const Point &P, const Line &L) {
  if (dcmp(Dot(L.v, P - L.A)) < 0)
    return Length(P - L.A);
  else if (dcmp(Dot(L.v, P - L.B) > 0))
    return Length(P - L.B);
  else
    return DistanceToLine(P, L);
}
bool SegmentProperIntersection(const Line &L1, const Line &L2) {
  int c1 = Position(L2.A, L1), c2 = Position(L2.B, L1), c3 = Position(L1.A, L2),
      c4 = Position(L1.B, L2);
  return c1 * c2 < 0 && c3 * c4 < 0;
}
bool OnSegment(const Point &P, const Line &L) {
  return dcmp(Cross(L.A - P, L.B - P)) == 0 && dcmp(Dot(L.A - P, L.B - P)) <= 0;
}
bool OnSegment2(const Point &P, const Line &L) {
  return dcmp(L.A.x - P.x) * dcmp(L.B.x - P.x) <= 0 &&
         dcmp(L.A.y - P.y) * dcmp(L.B.y - P.y) <= 0;
}
void print(const vector<Point> &A) {
  for (int i = 0; i < A.size(); ++i) printf("%.2lf %.2lf\n", A[i].x, A[i].y);
}
double PolygonArea(const vector<Point> &p) {
  int n = p.size();
  double area = 0;
  for (int i = 1; i < n - 1; ++i) area += Area2(p[0], p[i], p[i + 1]);
  return area / 2.0;
}
int isPointInPolygon(const Point &P, const vector<Point> &p) {
  int n = p.size();
  int wn = 0;
  for (int i = 0; i < n; ++i) {
    const Point &p1 = p[i];
    const Point &p2 = p[(i + 1) % n];
    if (P == p1 || P == p2 || OnSegment(P, Line(p1, p2))) return -1;
    int k = dcmp(Cross(p2 - p1, P - p1));
    int d1 = dcmp(p1.y - P.y);
    int d2 = dcmp(p2.y - P.y);
    if (k > 0 && d1 <= 0 && d2 > 0) ++wn;
    if (k < 0 && d2 <= 0 && d1 > 0) --wn;
  }
  return wn != 0;
}
vector<Point> ConvexHull(vector<Point> p) {
  int n = p.size();
  sort(p.begin(), p.end());
  vector<Point> q(n + 1);
  int m = 0;
  for (int i = 0; i < n; ++i) {
    while (m > 1 && Cross(q[m - 1] - q[m - 2], p[i] - q[m - 2]) <= 0) --m;
    q[m++] = p[i];
  }
  int k = m;
  for (int i = n - 2; i >= 0; --i) {
    while (m > k && Cross(q[m - 1] - q[m - 2], p[i] - q[m - 2]) <= 0) --m;
    q[m++] = p[i];
  }
  if (n > 1) m--;
  q.resize(m);
  return q;
}
void PolygonsIntersectionArea(vector<vector<Point> > &ps, double *ans) {
  int n = ps.size();
  for (int i = 0; i < n + 1; ++i) ans[i] = 0;
  static vector<pair<double, int> > ev;
  for (int i = 0; i < n; ++i)
    for (int pi = 0; pi < ps[i].size(); ++pi) {
      Line L0 = Line(ps[i][pi], ps[i][(pi + 1) % ps[i].size()]);
      ev.clear();
      for (int j = 0; j < n; ++j)
        if (i != j)
          for (int pj = 0; pj < ps[j].size(); ++pj) {
            Line L = Line(ps[j][pj], ps[j][(pj + 1) % ps[j].size()]);
            int p1 = Position(L.A, L0), p2 = Position(L.B, L0);
            if (!p1 && !p2) {
              if (i < j && dcmp(Dot(L0.v, L.v)) > 0) {
                ev.push_back(make_pair(min(max(L0.pos(L.A), 0.0), 1.0), 1));
                ev.push_back(make_pair(min(max(L0.pos(L.B), 0.0), 1.0), -1));
              }
            } else {
              Point p;
              double t;
              int x = LineLineIntersection(L0, L, &p, &t);
              if (p1 >= 0 && p2 < 0)
                ev.push_back(make_pair(min(max(t, 0.0), 1.0), 1));
              if (p1 < 0 && p2 >= 0)
                ev.push_back(make_pair(min(max(t, 0.0), 1.0), -1));
            }
          }
      ev.push_back(make_pair(0.0, 1));
      ev.push_back(make_pair(1.0, -1));
      sort(ev.begin(), ev.end());
      int cv = 0;
      double S0 = Cross(L0.A, L0.B) / 2.0;
      double lst = 0;
      for (int l = 0, r; l < ev.size();) {
        ans[cv] += S0 * (ev[l].first - lst);
        lst = ev[l].first;
        for (r = l + 1; r < ev.size() && ev[r].first <= ev[l].first; ++r)
          ;
        for (int p = l; p < r; ++p) cv += ev[p].second;
        l = r;
      }
    }
}
const int maxn = 510;
int n;
vector<vector<Point> > rects;
double area[maxn];
void solve() {
  scanf("%d", &n);
  rects.resize(n);
  double S0 = 0.0;
  for (int i = 0; i < n; ++i) {
    vector<Point> rect(4);
    for (int pi = 0; pi < 4; ++pi) rect[pi].read();
    if (Cross(rect[1] - rect[0], rect[2] - rect[0]) < 0) swap(rect[1], rect[3]);
    rects[i] = rect;
    S0 += PolygonArea(rect);
  }
  PolygonsIntersectionArea(rects, area);
  printf("%.10lf\n", S0 / area[1]);
}
int main() {
  solve();
  return 0;
}
