#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int,int> pii;
#define REP(i,n) for(ll i=0;i<n;++i)
#define REPR(i,n) for(ll i=1;i<n;++i)
#define FOR(i,a,b) for(ll i=a;i<b;++i)
 
#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()
 
#define MOD (ll)(1e9+7)
#define ADD(a,b) a=((a)+(b))%MOD
#define FIX(a) ((a)%MOD+MOD)%MOD
 
#define EPS 1e-9
 
struct line{
public:
  P a,b;
  line(P a,P b):a(a),b(b){}
  line(){}
};
 
bool operator< (const P &l,const P &r){
  if(l.real()!=r.real())return l.real()<r.real();
  return l.imag()<r.imag();
}
 
bool operator< (const line &l,const line &r){
  if(l.a!=r.a)return l.a<r.a;
  return l.b<r.b;
}
 
double dot(P a,P b){
  return (conj(a)*b).real();
}
double cross(P a,P b){
  return (conj(a)*b).imag();
}
 
// http://www.deqnotes.net/acmicpc/2d_geometry/lines
double distance_ls_p(P a, P b, P c) {
  if ( dot(b-a, c-a) < EPS ) return abs(c-a);
  if ( dot(a-b, c-b) < EPS ) return abs(c-b);
  return abs(cross(b-a, c-a)) / abs(b-a);
}
bool is_intersected_ls(P a1, P a2, P b1, P b2) {
  return ( cross(a2-a1, b1-a1) * cross(a2-a1, b2-a1) < EPS ) &&
         ( cross(b2-b1, a1-b1) * cross(b2-b1, a2-b1) < EPS );
}
P intersection_ls(P a1, P a2, P b1, P b2) {
  P b = b2-b1;
  double d1 = abs(cross(b, a1-b1));
  double d2 = abs(cross(b, a2-b1));
  double t = d1 / (d1 + d2);
 
  return a1 + (a2-a1) * t;
}
 
double nrm(P a){
  return a.real()*a.real() + a.imag()*a.imag();
}

int n;
vector<P> poi_;
void dfs(vi po,vector<line> mir,P orient){
  poi_.push_back(orient);
  if(po.size()>=5)return;
  REP(i,n){
    if(po.size()>0 && po[po.size()-1]==i)continue;
    vi npo = po;
    vector<line> nmir = mir;
    P nori = orient;

    npo.push_back(i);
    P beg = mir[i].a;
    P vec = mir[i].b-mir[i].a;
    REP(j,n){
      nmir[i].a = conj((nmir[i].a-beg)/vec)*vec+beg;
      nmir[i].b = conj((nmir[i].b-beg)/vec)*vec+beg;
    }
    nori = conj((nori-beg)/vec)*vec+beg;
    dfs(npo,nmir,nori);
  }
}
 
int main(){
  cout.precision(10);
  while(true){
    cin>>n;
    if(n==0)break;
    vector<line> mirrors(n);
    int x,y;
    REP(i,n){
      cin>>x>>y;
      P a = P(x,y);
      cin>>x>>y;
      P b = P(x,y);
      mirrors[i] = line(a,b);
    }
    P start,end;
    cin>>x>>y;
    start = P(x,y);
    cin>>x>>y;
    end = P(x,y);
    // reflect imaging
    poi_.clear();
    dfs(vi(),mirrors,end);

    // target point list is poi1
    double minlen = 1e18;
    REP(poiiii,poi_.size()){
      P poi = poi_[poiiii];
      if(abs(poi-start)==0.0)continue;
      double ret = 0.0;
      bool okflag = false;
      P poib = start;
      P poit = poi;
      P porient = (poit-poib); porient /= abs(porient);
      // poit = poit + (poit-poib)*100000.0;
      int befmer = 100;
      // ray from poib to poit
      // reflect and check of end
      REP(_,6){
        // 5times reflect and once check <= 6times
        // search nearest crossing point
        double nearestlen = 1e18;
        int nearestid = -1;
        REP(i,n+1){
          if(i==befmer)continue;
          if(i==n){
            // goal check
            if(distance_ls_p(poib,poib+porient*100000.0,end) < EPS){
              // on line
              double nelen = nrm(end-poib);
              if(nearestlen > nelen){
                nearestlen = nelen;
                nearestid = i;
              }
            }
          }else{
            // reflect check
            if(is_intersected_ls(poib,poib+porient*100000.0,mirrors[i].a,mirrors[i].b)){
              // crossing
              P inte = intersection_ls(poib,poib+porient*100000.0,mirrors[i].a,mirrors[i].b);
              double nelen = nrm(inte-poib);
              if(nearestlen > nelen){
                nearestlen = nelen;
                nearestid = i;
              }
            }
          }
        }
        if(nearestid == -1)break;
        if(nearestid == n){
          ret += sqrt(nearestlen);
          okflag = true;
          break;
        }else{
          ret += sqrt(nearestlen);
          int i = nearestid;
          P inte = intersection_ls(poib,poib+porient*100000.0,mirrors[i].a,mirrors[i].b);
 
          P beg = mirrors[i].a;
          P vec = mirrors[i].b - mirrors[i].a;
          // poit = conj((poit-beg)/vec)*vec+beg;
          poib = inte;
          porient = vec/(porient/vec); porient /= abs(porient);
 
          befmer = i;
        }
      }
      if(okflag) minlen = min(ret,minlen);
    }
    cout << fixed << minlen << endl;
  }
  return 0;
}

Measured memory_bytes: 1384