#include<cmath>
#include<cstdio>
#include<vector>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const double EPS=1e-7;
const double INF=1e77;
const double PI=acos(-1);

template<class T>
struct point{
	T x,y;
	point &operator-=(const point &a){ x-=a.x; y-=a.y; }
	point operator+(const point &a)const{ return (point){x+a.x,y+a.y}; }
	point operator-(const point &a)const{ return (point){x-a.x,y-a.y}; }
};

template<class T>
point<T> operator*(T c,const point<T> &a){ return (point<T>){c*a.x,c*a.y}; }

template<class T>
T dot(const point<T> &a,const point<T> &b){ return a.x*b.x+a.y*b.y; }

template<class T>
T cross(const point<T> &a,const point<T> &b){ return a.x*b.y-a.y*b.x; }

template<class T>
T abs2(const point<T> &a){ return a.x*a.x+a.y*a.y; }

template<class T>
double arg(const point<T> &a){
	double t=atan2(a.y,a.x);
	return t<0?t+2*PI:t;
}

template<class T>
struct line{ point<T> a,b; };

template<class T>
struct segment{
	point<T> a,b;
	operator line<T>()const{ return (line<T>){a,b}; }
};

template<class T>
point<double> proj(const point<T> &p,const line<T> &L){
	return L.a+dot(p-L.a,L.b-L.a)/abs2(L.b-L.a)*(L.b-L.a);
}

template<class T>
double dist(const point<T> &a,const point<T> &b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

enum {CCW=1,CW=-1,ON=0};
int ccw(const point<double> &a,const point<double> &b,const point<double> &c){
	double rdir=cross(b-a,c-a);
	if(rdir> EPS) return CCW;
	if(rdir<-EPS) return CW;
	return ON;
}

bool cover(const segment<double> &S,const point<double> &p){
	return dist(S.a,p)+dist(p,S.b)<dist(S.a,S.b)+EPS;
}

bool intersect(const segment<double> &S1,const segment<double> &S2){
	if(max(S1.a.x,S1.b.x)+EPS<min(S2.a.x,S2.b.x)
	|| max(S1.a.y,S1.b.y)+EPS<min(S2.a.y,S2.b.y)
	|| max(S2.a.x,S2.b.x)+EPS<min(S1.a.x,S1.b.x)
	|| max(S2.a.y,S2.b.y)+EPS<min(S1.a.y,S1.b.y)) return false;
	return ccw(S1.a,S1.b,S2.a)*ccw(S1.a,S1.b,S2.b)<=0
		&& ccw(S2.a,S2.b,S1.a)*ccw(S2.a,S2.b,S1.b)<=0;
}

point<double> get_intersect(const line<double> &L1,const line<double> &L2){
	double a1=cross(L1.b-L1.a,L2.b-L2.a);
	double a2=cross(L1.b-L1.a,L1.b-L2.a);
	if(abs(a1)<EPS) return L1.a;
	return L2.a+a2/a1*(L2.b-L2.a);
}

double simulate(double theta,int n,const segment<double> *S,point<double> g){
	point<double> p={0,0};
	int pre=-1;
	double sum=0;
	rep(t,6){
		point<double> v={cos(theta),sin(theta)};
		segment<double> V={p,p+1000.*v}; // lay
		int i0=-1; // ツ暗ェツ氾板渉可づ淞づ可づ板づつつゥツづゥツ静シツ閉ェツづ個氾板債?
		double d0;
		rep(i,n) if(i!=pre && intersect(S[i],V)) {
			point<double> c=get_intersect(S[i],V);
			double d=dist(p,c);
			if(i0==-1 || d<d0) i0=i, d0=d;
		}

		if(cover(V,g) && (i0==-1 || dist(p,g)<d0)) return sum+dist(p,g);
		if(i0==-1){ // ツづ?づ個静シツ閉ェツづ?づ?づ板づつつゥツづァツづ按つゥツづ?つス
			return INF;
		}
		else{
			pre=i0;
			sum+=d0;
			p=get_intersect(V,S[i0]);
			point<double> tmp1=2.*proj(V.a,(line<double>)S[i0])-V.a;
			point<double> tmp2=2.*proj(V.b,(line<double>)S[i0])-V.b;
			theta=arg(tmp2-tmp1);
		}
	}
	return INF;
}

vector<double> cand; // ツ板ュツ偲仰陛サツ古シツづ個古ウツ陛「

void dfs(int t,int n,const segment<double> *S,point<double> g){
	if(t>0) cand.push_back(arg(g));
	if(t==5) return;

	segment<double> T[5];
	rep(i,n){
		line<double> L=S[i]; // S[i] ツづ?板スツ偲仰つウツつケツづゥ
		rep(j,n){
			T[j].a=2.*proj(S[j].a,L)-S[j].a;
			T[j].b=2.*proj(S[j].b,L)-S[j].b;
		}
		dfs(t+1,n,T,2.*proj(g,L)-g);
	}
}

int main(){
	for(int n;scanf("%d",&n),n;){
		segment<double> S[5];
		rep(i,n) scanf("%lf%lf%lf%lf",&S[i].a.x,&S[i].a.y,&S[i].b.x,&S[i].b.y);
		point<double> s,g;
		scanf("%lf%lf%lf%lf",&g.x,&g.y,&s.x,&s.y);
		g-=s;
		rep(i,n) S[i].a-=s, S[i].b-=s;

		cand.clear();
		dfs(0,n,S,g);

		double ans=INF;
		rep(i,cand.size()) ans=min(ans,simulate(cand[i],n,S,g));
		printf("%.9f\n",ans);
	}

	return 0;
}

Measured memory_bytes: 940