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

using namespace std;

typedef complex<double> Point;

struct Segment{ Point p1, p2; };

const double EPS = 1e-2;
const double INF = 1e5;

bool equals(double a, double b){
  return abs(a-b) < EPS;
}

double dot(Point a, Point b){
  return real(conj(a) * b);
}

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

Point project(Segment s, Point p){
  Point base = s.p2 - s.p1;
  double t = dot(p - s.p1, base) / norm(base);
  return s.p1 + base * t;
}

Point reflect(Segment s, Point p){
  return p + (project(s, p) - p) * 2.0;
}

int ccw(Point p0, Point p1, Point p2){
  Point a = p1 - p0;
  Point b = p2 - p0;
  if(cross(a, b) > EPS) return 1;
  if(cross(a, b) < -EPS) return -1;
  if(dot(a, b) < -EPS) return 2;
  if(norm(a) < norm(b)) return -2;
  return 0;
}

bool isIntersect(Point p1, Point p2, Point p3, Point p4){
  return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
          ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);
}

bool isIntersect(Segment s1, Segment s2){
  return isIntersect(s1.p1, s1.p2, s2.p1, s2.p2);
}

Point getCrossPoint(Segment s1, Segment s2){
  Point base = s2.p2 - s2.p1;
  double d1 = abs(cross(base, s1.p1 - s2.p1));
  double d2 = abs(cross(base, s1.p2 - s2.p1));
  double t = d1 / (d1 + d2);
  return s1.p1 + (s1.p2 - s1.p1) * t;
}

double getDistance(Point a, Point b){
  return abs(a - b);
}

vector<Point> targets;
vector<Segment> mirrors;
int n;

double calc(Point s, Point t, Point d){
  double res = 0.0;
  Point cur = s;
  Point dir = d;
  for(int k=0;k<6;k++){
    int id = -1;
    double valm = INF;
    dir = cur + (dir - cur) * INF;
    Segment seg = (Segment){cur, dir};
    Point c;
    for(int i=0;i<mirrors.size();i++){
      if(ccw(mirrors[i].p1, mirrors[i].p2, cur) == 0) continue;
      if(//!equals(abs(cross(dir-cur, mirrors[i].p2-mirrors[i].p1)), 0.0) &&
         isIntersect(seg, mirrors[i]) &&
         ccw(cur, dir, mirrors[i].p1) != 0 &&
         ccw(cur, dir, mirrors[i].p2) != 0){
        double tmp = getDistance(cur, getCrossPoint(seg, mirrors[i]));
        if(equals(tmp, 0.0)) continue;
        if(valm > tmp + EPS){
          valm = tmp;
          id = i;
          c = getCrossPoint(seg, mirrors[i]);
        }
      }
    }
    if(ccw(cur, dir, t) == 0){
      double tmp = getDistance(cur, t);
      if(valm > tmp + EPS) return res + tmp;
    }
    if(id == -1) break;
    if(k < 5){
      res += valm;
      Point vec = mirrors[id].p2 - mirrors[id].p1;
      Point nor(-vec.imag(), vec.real());
      dir = reflect((Segment){c+nor, c}, cur);
      cur = c;
    }
  }
  return INF;
}

void init(){
  targets.clear();
  mirrors.clear();
}

main(){
  while(cin >> n && n){
    init();
    for(int i=0;i<n;i++){
      Segment in;
      cin >> in.p1.real() >> in.p1.imag();
      cin >> in.p2.real() >> in.p2.imag();
      mirrors.push_back(in);
    }
    Point s, t;
    cin >> t.real() >> t.imag();
    cin >> s.real() >> s.imag();
    targets.push_back(t);
    for(int i=0;i<5;i++){
      int size = targets.size();
      for(int j=0;j<size;j++){
        for(int k=0;k<n;k++){
          targets.push_back(reflect(mirrors[k], targets[j]));
        }
      }
    }
    double ans = INF;
    for(int i=0;i<targets.size();i++){
      ans = min(ans, calc(s, t, targets[i]));
    }
    printf("%.14f\n", ans);
  }
}

Measured memory_bytes: 1400