//zelovoc
#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cstring>
#include<cmath>
#include<complex>

using namespace std;
#define For(i,n) for(int i = 0; i<int(n); ++i)
#define INF 1023456789
#define LINF 1023456789123456789LL
#define EPS 1e-7

typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<int> vint;

#define db(x) //cerr << #x << " = " << x << endl

typedef complex<double> point;
typedef pair<point, point> line;


bool operator<(const point a, const point b) {
	if (a.real() < b.real()) return 1;
	if (a.real() > b.real()) return 0;
	return (a.imag() > b.imag());
}

double myabs(double x) {
	return (x>0)?x:-x;
}

int sign(double x) {
	if (myabs(x) < EPS) return 0;
	return (x<0)?-1:1;
}

point mymin(point a, point b) {
	return (a<b)?a:b;
}
point mymax(point a, point b) {
	return (b<a)?a:b;
}

double cross(point a, point b) {
	return imag(conj(a)*b);
}
double scalar(point a, point b) {
	return real(conj(a)*b);
}

vector<point> intersect(line p, line q) {
	vector<point> res;
	point A = p.first, B = p.second, C = q.first, D = q.second;
	point U = B-A, V = D-C;
	if (sign(cross(U,V)) == 0) return res;
	double k = (cross(C,V) - cross(A,V)) / cross(U,V);
	res.push_back(A + k*U);
	return res;
}

bool krizuju(line p, line q) {
	point A = p.first, B = p.second, C = q.first, D = q.second;
	if (sign(cross(B-A, C-A)) * sign(cross(B-A, D-A)) != -1) return 0;
	if (sign(cross(D-C, A-C)) * sign(cross(D-C, B-C)) != -1) return 0;
	return 1;
}


bool vnutri(point p, point a, point b, point c) {
	int s1 = sign(cross(b-a, p-a));
	int s2 = sign(cross(c-b, p-b));
	int s3 = sign(cross(a-c, p-c));
	return (s1 == s2 && s2 == s3 && s1 != 0);
}

bool zaclana(point p, line kto, line koho) {
	if (krizuju(kto, line(p, koho.first))) return 1;
	if (krizuju(kto, line(p, koho.second))) return 1;
	if (vnutri(kto.first, p, koho.first, koho.second)) return 1;	
	if (vnutri(kto.second, p, koho.first, koho.second)) return 1;	
	return 0;
}

bool mensi(const point a, const point b) {
	return a<b;
}


int main() {
	int n;
	while(scanf("%d", &n) > 0 && n >0) {
		vector<line> aviary;
		vector<point> avi;
		vector<line> badl;
		vector<point> badp;

		point T1, T2;
		int a,b,c,d,e,f,g,h;
		scanf("%d%d%d%d", &a, &b, &c, &d);
		db(n);
		
		T1 = point(a,b);
		T2 = point(c,d);

		scanf("%d%d%d%d%d%d%d%d", &a, &b, &c, &d, &e, &f, &g, &h);
		point p[4] = {point(a,b), point(c,d), point(e,f), point(g,h)};
		For(i, 4) avi.push_back(p[i]);
		For(i, 4) aviary.push_back(line(p[i], p[(i+1)%4]));

		For(i, n-1) {
			scanf("%d%d%d%d%d%d%d%d", &a, &b, &c, &d, &e, &f, &g, &h);
			point p[4] = {point(a,b), point(c,d), point(e,f), point(g,h)};
			//if (sign(cross(T2-T1,p[0]-T1))*sign(cross(T2-T1,avi[0]-T1))>1)
			//	continue;
			
			For(i, 4) badp.push_back(p[i]);
			For(i, 4) badl.push_back(line(p[i], p[(i+1)%4]));
		}

		vector<point> fine;
		
		For(i, avi.size()) For(j, badp.size()) {
			point a = avi[i];
			point b = badp[j];
			vector<point> body = intersect(line(a,b), line(T1,T2));
			For(k, body.size()) fine.push_back(body[k]);
		}
		fine.push_back(T1);
		fine.push_back(T2);
		sort(fine.begin(), fine.end(), mensi);
		
		db("--------------------------------------------------------");
		double result = 0.0;
		For(i, fine.size()-1) {
			if (fine[i] < mymin(T1, T2)) continue;
			if (mymax(T1, T2) < fine[i+1]) continue;
			point stred = (fine[i] + fine[i+1])*0.5;
			
			bool dobre = 1;

			For(j, aviary.size()) {
				For(k, badl.size()) {
					if (zaclana(stred, badl[k], aviary[j])) {
						dobre = 0;
						break;
					}
				}
				if (!dobre) break;
			}
			db(i);
			db(stred);
			db(abs(fine[i]-fine[i+1]));

			if (dobre) {
				result += abs(fine[i]-fine[i+1]);
			}
		}
		printf("%.10lf\n", result);

	}
	
	
}