#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxp = 1010;
int sgn(double x) {
  if (fabs(x) < eps) return 0;
  if (x < 0)
    return -1;
  else
    return 1;
}
inline double sqr(double x) { return x * x; }
struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(y) {}
  void input() { scanf("%lf%lf", &x, &y); }
  void output() { printf("%.2f.%.2f\n", x, y); }
  bool operator==(Point b) const {
    return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
  }
  bool operator<(Point b) const {
    return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : x < b.x;
  }
  double operator^(const Point &b) const { return x * b.y - y * b.x; }
  double operator*(const Point &b) const { return x * b.x + y * b.y; }
  double len() { return sqrt(x * x + y * y); }
  double len2() { return x * x + y * y; }
  double distance(Point p) {
    return sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y));
  }
  Point operator+(const Point &b) const { return Point(x + b.x, y + b.y); }
  Point operator-(const Point &b) const { return Point(x - b.x, y - b.y); }
  Point operator*(const double &k) const { return Point(x * k, y * k); }
  Point operator/(const double &k) const { return Point(x / k, y / k); }
};
struct polygon {
  int n;
  Point p[maxp];
  void input(int _n) {
    n = _n;
    for (int i = 0; i < n; i++) p[i].input();
  }
  void add(Point q) { p[n++] = q; }
  bool getdir() {
    double sum = 0;
    for (int i = 0; i < n; i++) sum += (p[i] ^ p[(i + 1) % n]);
    if (sgn(sum) > 0) return 1;
    return 0;
  }
  void adjust() {
    for (int i = 1; i <= n / 2; i++) swap(p[i], p[n - i]);
  }
  double getarea() {
    double sum = 0;
    for (int i = 0; i < n; i++) sum += (p[i] ^ p[(i + 1) % n]);
    return fabs(sum) / 2;
  }
};
Point crosspoint(Point s1, Point e1, Point s2, Point e2) {
  double a1 = (e2 - s2) ^ (s1 - s2);
  double a2 = (e2 - s2) ^ (e1 - s2);
  return Point((s1.x * a2 - e1.x * a1) / (a2 - a1),
               (s1.y * a2 - e1.y * a1) / (a2 - a1));
}
struct polygons {
  vector<polygon> p;
  polygons() { p.clear(); }
  void clear() { p.clear(); }
  void push(polygon q) {
    if (sgn(q.getarea())) p.push_back(q);
  }
  vector<pair<double, int> > e;
  void ins(Point s, Point t, Point X, int i) {
    double r = fabs(t.x - s.x) > eps ? (X.x - s.x) / (t.x - s.x)
                                     : (X.y - s.y) / (t.y - s.y);
    r = min(r, 1.0);
    r = max(r, 0.0);
    e.push_back(make_pair(r, i));
  }
  double polyareaunion() {
    double ans = 0.0;
    int c0, c1, c2, i, j, k, w;
    for (i = 0; i < p.size(); i++) {
      if (p[i].getdir() == 0) p[i].adjust();
    }
    for (i = 0; i < p.size(); i++) {
      for (k = 0; k < p[i].n; k++) {
        Point &s = p[i].p[k], &t = p[i].p[(k + 1) % p[i].n];
        if (!sgn(s ^ t)) continue;
        e.clear();
        e.push_back(make_pair(0.0, 1));
        e.push_back(make_pair(1.0, -1));
        for (j = 0; j < p.size(); j++)
          if (i != j) {
            for (w = 0; w < p[j].n; w++) {
              Point a = p[j].p[w], b = p[j].p[(w + 1) % p[j].n],
                    c = p[j].p[(w - 1 + p[j].n) % p[j].n];
              c0 = sgn((t - s) ^ (c - s));
              c1 = sgn((t - s) ^ (a - s));
              c2 = sgn((t - s) ^ (b - s));
              if (c1 * c2 < 0)
                ins(s, t, crosspoint(s, t, a, b), -c2);
              else if (!c1 && c0 * c2 < 0)
                ins(s, t, a, -c2);
              else if (!c1 && !c2) {
                int c3 = sgn((t - s) ^ (p[j].p[(w + 2) % p[j].n] - s));
                int dp = sgn((t - s) * (b - a));
                if (dp && c0)
                  ins(s, t, a, dp > 0 ? c0 * ((j > i) ^ (c0 < 0)) : -(c0 < 0));
                if (dp && c3)
                  ins(s, t, b, dp > 0 ? -c3 * ((j > i) ^ (c3 < 0)) : c3 < 0);
              }
            }
          }
        sort(e.begin(), e.end());
        int ct = 0;
        double tot = 0.0, last;
        for (j = 0; j < e.size(); j++) {
          if (ct == 1) tot += e[j].first - last;
          ct += e[j].second;
          last = e[j].first;
        }
        ans += s ^ t * tot;
      }
    }
    return fabs(ans) * 0.5;
  }
} ps;
int main() {
  int i, j, k;
  int n;
  scanf("%d", &n);
  double ans = 0;
  for (i = 0; i < n; i++) {
    polygon pl;
    pl.input(4);
    ans += pl.getarea();
    ps.push(pl);
  }
  printf("%.12lf\n", ans / ps.polyareaunion());
  return 0;
}
