#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const double eps = 1E-7;
const int inf = int(1e9) + 7;
int sgn(double x) {
  if (x < -eps) return -1;
  if (x > eps) return 1;
  return 0;
}
struct Point {
  double x, y;
  Point(double _x, double _y) : x(_x), y(_y) {}
  Point() {}
};
struct Seg {
  Point p0, p1;
  Seg(Point _p0, Point _p1) : p0(_p0), p1(_p1) {}
  Seg() {}
};
struct Circle {
  Point o;
  double r;
  Circle() {}
  Circle(Point _o, double _r) : o(_o), r(_r) {}
};
inline Point operator+(const Point &p1, const Point &p2) {
  return Point(p1.x + p2.x, p1.y + p2.y);
}
inline Point operator-(const Point &p1, const Point &p2) {
  return Point(p1.x - p2.x, p1.y - p2.y);
}
inline Point operator*(const Point &p, double k) {
  return Point(p.x * k, p.y * k);
}
inline double operator^(const Point &p1, const Point &p2) {
  return (p1.x * p2.y - p2.x * p1.y);
}
inline double operator*(const Point &p1, const Point &p2) {
  return p1.x * p2.x + p1.y * p2.y;
}
inline double cross(Point &p0, Point &p1, Point &p2) {
  return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
inline double get_dis(const Point &p1, const Point &p2) {
  return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
bool seg_jiao(Seg s1, Seg s2, Point &p) {
  double area1 = cross(s1.p0, s1.p1, s2.p0);
  double area2 = cross(s1.p0, s1.p1, s2.p1);
  if (sgn(area1 - area2) == 0) return false;
  p = Point((s2.p0.x * area2 - s2.p1.x * area1) / (area2 - area1),
            (s2.p0.y * area2 - s2.p1.y * area1) / (area2 - area1));
  if (get_dis(p, s2.p0) + get_dis(p, s2.p1) > get_dis(s2.p0, s2.p1) + eps)
    return false;
  if (get_dis(p, s1.p0) + get_dis(p, s1.p1) > get_dis(s1.p0, s1.p1) + eps)
    return false;
  if (sgn(get_dis(p, s1.p0)) == 0 || sgn(get_dis(p, s1.p1)) == 0 ||
      sgn(get_dis(p, s2.p0)) == 0 || sgn(get_dis(p, s2.p1)) == 0)
    return false;
  return true;
}
bool seg_jiao2(Seg &s1, Seg &s2, Point &p) {
  double area1 = cross(s1.p0, s1.p1, s2.p0);
  double area2 = cross(s1.p0, s1.p1, s2.p1);
  if (sgn(area1 - area2) == 0) return false;
  p = Point((s2.p0.x * area2 - s2.p1.x * area1) / (area2 - area1),
            (s2.p0.y * area2 - s2.p1.y * area1) / (area2 - area1));
  if (get_dis(p, s2.p0) + get_dis(p, s2.p1) > get_dis(s2.p0, s2.p1) + eps)
    return false;
  return true;
}
bool strictOnSeg(Point p, Seg s) {
  if (get_dis(p, s.p0) + get_dis(p, s.p1) > get_dis(s.p0, s.p1) + eps)
    return false;
  if (sgn(get_dis(p, s.p0)) == 0 || sgn(get_dis(p, s.p1)) == 0) return false;
  return true;
}
const int maxN = 2000 + 5;
Seg sa[maxN];
int n, m;
double totArea;
bool inside(Point p) {
  for (int(i) = 0; (i) < (n); ++(i)) {
    double base = cross(sa[i * 4].p0, sa[i * 4].p1, p);
    int tmp;
    bool in = true;
    for (int(j) = (1); (j) < (4); ++(j)) {
      if (sgn(base) * sgn(cross(sa[i * 4 + j].p0, sa[i * 4 + j].p1, p)) <= 0)
        in = false;
    }
    if (in) return true;
  }
  return false;
}
struct node {
  int tag;
  double x;
} na[maxN];
bool cmp1(const node &a1, const node &a2) { return (a1.x < a2.x); }
struct line {
  double y, len;
} la[100000];
bool cmp2(const line &a1, const line &a2) { return (a1.y < a2.y); }
bool operator<(const Point &p1, const Point &p2) { return (p1.y + eps < p2.y); }
set<Point> mp;
int lineNum;
void add2(Point p) {
  if (mp.count(p)) return;
  mp.insert(p);
  Seg s = Seg(p, Point(p.x + 10, p.y));
  double tmp[4];
  int nodeNum = 0;
  for (int(i) = 0; (i) < (n); ++(i)) {
    int np = 0;
    for (int(j) = 0; (j) < (4); ++(j))
      if (seg_jiao2(s, sa[i * 4 + j], p)) {
        tmp[np++] = p.x;
      }
    if (np == 2) {
      if (tmp[0] > tmp[1]) swap(tmp[0], tmp[1]);
      na[nodeNum].tag = 1;
      na[nodeNum].x = tmp[0];
      nodeNum++;
      na[nodeNum].tag = -1;
      na[nodeNum].x = tmp[1];
      nodeNum++;
    }
  }
  sort(na, na + nodeNum, cmp1);
  int tag = 0;
  double len = 0;
  for (int(i) = 0; (i) < (nodeNum); ++(i)) {
    if (tag > 0) len += na[i].x - na[i - 1].x;
    tag += na[i].tag;
  }
  la[lineNum].y = s.p0.y;
  la[lineNum].len = len;
  lineNum++;
}
int rr, rc;
void add(Point p, bool flag) {
  rr++;
  if (!flag)
    if (inside(p)) return;
  add2(Point(p.x, p.y - eps));
  add2(Point(p.x, p.y + eps));
  rc++;
}
void work() {
  sort(la, la + lineNum, cmp2);
  double ans = 0;
  for (int(i) = (1); (i) < (lineNum); ++(i)) {
    ans += (la[i].y - la[i - 1].y) * (la[i].len + la[i - 1].len);
  }
  printf("%.8lf\n", totArea / ans);
}
void init() {
  Point tmp[5];
  scanf("%d", &n);
  m = 0;
  for (int(r) = 0; (r) < (n); ++(r)) {
    for (int(i) = 0; (i) < (4); ++(i)) scanf("%lf%lf", &tmp[i].x, &tmp[i].y);
    tmp[4] = tmp[0];
    for (int(i) = 0; (i) < (4); ++(i)) sa[m++] = Seg(tmp[i], tmp[i + 1]);
    totArea +=
        abs(cross(tmp[0], tmp[2], tmp[1])) + abs(cross(tmp[0], tmp[2], tmp[3]));
  }
  Point p;
  for (int(i1) = 0; (i1) < (n); ++(i1))
    for (int(j1) = 0; (j1) < (4); ++(j1))
      for (int(i2) = (i1); (i2) < (n); ++(i2))
        for (int(j2) = 0; (j2) < (4); ++(j2))
          if (i1 != i2) {
            if (seg_jiao(sa[i1 * 4 + j1], sa[i2 * 4 + j2], p)) add(p, 0);
          }
  for (int(i) = 0; (i) < (n); ++(i)) {
    add(sa[i * 4].p0, 0);
    add(sa[i * 4].p1, 0);
    add(sa[i * 4 + 2].p0, 0);
    add(sa[i * 4 + 2].p1, 0);
  }
}
int main() {
  init();
  work();
  return 0;
}
