#include<iostream>
#include<vector>
#include<complex>
#include<algorithm>
#include<iterator>

using namespace std;

const double eps=1e-9;
const double PI=acos(0)*2;
typedef complex<double> P;

double cross(P a,P b){
  return (conj(a)*b).imag();
}

bool intersects(P a1,P a2,P b1,P b2){
  P a=a1-a2;
  P b=b1-b2;
  return cross(b1-a2,a)*cross(b2-a2,a)<=0&&cross(a1-b2,b)*cross(a2-b2,b)<=0;
}

P intersection(P a1,P a2,P b1,P b2){
  P a=a2-a1;
  P b=b2-b1;
  return a1+a*cross(b,b1-a1)/cross(b,a);
}
  
P rotate(P d,P s,double a){
  return (d-s)*polar(1.,a)+s;
}

P mirror_image(P r,P a,P b){
  return rotate(r,a,2*(arg(b-a)-arg(r-a)));
}

int n;
vector<P> PXY,QXY;
P T,L;


bool over_mirror(P p,int x,P d){
  if(x<0)return true;
  P is=intersection(p,d,PXY[x],QXY[x]);
  return abs(is-p)<abs(d-p);
}

int closest_mirror(P p,int cm,double a){
  int cx=-1;
  for(int i=0;i<n;i++){
    if(i==cm)continue;
    P fp=p+polar(999.,a);
    if(intersects(p,fp,PXY[i],QXY[i])){
      P cp=intersection(p,fp,PXY[i],QXY[i]);
      if(over_mirror(p,cm,cp)){
	bool f;
	if(cx<0){
	  f=true;
	}else{
	  P ncp=intersection(p,fp,PXY[cx],QXY[cx]);
	  f=abs(cp-p)<abs(ncp-p);
	}
	if(f){
	  cx=i;
	}
      }
    }
  }
  return cx;
}

double mirror_angle(double a,int x){
  double ba=arg(QXY[x]-PXY[x]);
  double ra=-(a-ba)+ba;
  while(ra<-2*acos(0)){
    ra+=4*acos(0);
  }
  while(ra>2*acos(0)){
    ra-=4*acos(0);
  }
  return ra;
}

double dfs(P p,int mx,double f,double l,int d);

double rdfs(P p,int cx,double f,double l,int d){
  P mp=mirror_image(p,PXY[cx],QXY[cx]);
  double nf=mirror_angle(l,cx);
  double nl=mirror_angle(f,cx);
  if(nf<nl){
    return dfs(mp,cx,nf,nl,d+1);
  }else{
    return min(dfs(mp,cx,nf,2*acos(0),d+1),dfs(mp,cx,-2*acos(0),nl,d+1));
  }
}

double dfs(P p,int mx,double f,double l,int d){
  // cout<<p<<'\t'<<mx<<'\t'<<f<<'\t'<<l<<endl;
  // cout<<abs(T-p)<<'\t'<<arg(T-p)<<endl;
  auto valid=[&](P d){
    return mx<0||intersects(p,d,PXY[mx],QXY[mx]);
  };
  double ta=arg(T-p);
  bool ft=ta<f||l<ta||!valid(T);
  for(int i=0;i<n;i++){
    if(mx==i)continue;
    if(intersects(p,T,PXY[i],QXY[i])){
      P is=intersection(p,T,PXY[i],QXY[i]);
      ft|=valid(is);
    }
  }
  if(!ft)return abs(T-p);
  if(d==5)return 1e99;
  int cx=closest_mirror(p,mx,f);
  vector<pair<P,int> > PQ;
  auto in_range=[&](P pp){
    double a=arg(pp-p);
    return valid(pp)&&eps+f<a&&a<l-eps;
  };
  for(int i=0;i<n;i++){
    if(in_range(PXY[i])){
      PQ.emplace_back(make_pair(PXY[i],i));
    }
    if(in_range(QXY[i])){
      PQ.emplace_back(make_pair(QXY[i],i));
    }
  }
  sort(begin(PQ),end(PQ),[&](pair<P,int> a,pair<P,int> b){
      return arg(a.first-p)<arg(b.first-p);
    });
  double ret=1e99;
  for(auto e:PQ){
    if(cx<0){
      cx=e.second;
      f=arg(e.first-p);
    }else if(cx==e.second){
      ret=min(ret,rdfs(p,cx,f,arg(e.first-p),d));
      f=arg(e.first-p);
      cx=closest_mirror(p,cx,f);
    }else if(valid(e.first)){
      double ang=arg(e.first-p);
      P cp=intersection(p,p+polar(999.,ang),PXY[cx],QXY[cx]);
      P dp=intersection(p,p+polar(999.,ang),PXY[e.second],QXY[e.second]);
      if(abs(dp-p)<abs(cp-p)){
	ret=min(ret,rdfs(p,cx,f,arg(e.first-p),d));
	cx=e.second;
	f=arg(e.first-p);
      }
    }
  }
  if(cx>=0){
    ret=min(ret,rdfs(p,cx,f,l,d));
  }
  return ret;
}

int main(){
  while(cin>>n,n){
    PXY.clear();
    QXY.clear();
    for(int i=0;i<n;i++){
      int px,py,qx,qy;
      cin>>px>>py>>qx>>qy;
      PXY.emplace_back(px,py);
      QXY.emplace_back(qx,qy);
    }
    int tx,ty,lx,ly;
    cin>>tx>>ty>>lx>>ly;
    T=P(tx,ty);
    L=P(lx,ly);
    cout<<fixed<<dfs(L,-1,-2*acos(0),2*acos(0),0)<<endl;
  }
}

Measured memory_bytes: 1372