#include <climits>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;

template<class T> void chmin(T &a, const T &b) {if(b < a) a = b;}

const double EPS = 1e-9;

struct point {
	double x, y;
	point(double x = 0.0, double y = 0.0):x(x), y(y) {}
	point(const point& p):x(p.x), y(p.y) {}

	point operator+ (const point& p) const {
		return point(x + p.x, y + p.y);
	}

	point operator- (const point& p) const {
		return point(x - p.x, y - p.y);
	}

	point operator* (const double s) const {
		return point(x * s, y * s);
	}

	point operator* (const point& p) const {
		return point(x * p.x - y * p.y, x * p.y + y * p.x);
	}

	point operator/ (const double s) const {
		return point(x / s, y / s);
	}

	bool operator< (const point& p) const {
		return x + EPS < p.x || abs(x - p.x) < EPS && y + EPS < p.y;
	}

	bool operator== (const point& p) const {
		return abs(x - p.x) < EPS && abs(y - p.y) < EPS;
	}
};

inline point rotate90(const point& p) {
	return point(-p.y, p.x);
}

inline double angle(const point& p) {
	return atan2(p.y, p.x);
}

inline double abs(const point& p) {
	return sqrt(p.x * p.x + p.y * p.y);
}

inline double norm(const point& p) {
	return p.x * p.x + p.y * p.y;
}

inline double dot(const point& l, const point& r) {
	return l.x * r.x + l.y * r.y;
}

inline double cross(const point& l, const point& r) {
	return l.x * r.y - l.y * r.x;
}

struct line {
	point a, b;
	line(const point& a, const point& b):a(a), b(b){}
};

struct segment {
	point a, b;
	segment(const point& a, const point& b):a(a), b(b){}
};

inline int ccw(const point& a, point b, point c) {
	b = b - a;
	c = c - a;
	const double tmp = cross(b, c);
	if(tmp > EPS) return 1; // ccw
	if(tmp < -EPS) return -1; // cw
	if(dot(b, c) < 0) return 2; // c, a, b 順に一直線上
	if(norm(b) < norm(c)) return -2; // a, b, c 順に一直線上
	return 0; //a, c, b 順で一直線上
}

inline point projection(const line& l, const point& p) {
	const point dif = l.b - l.a;
	const double tmp = dot(p - l.a, dif) / norm(dif);
	return l.a + dif * tmp;
}

inline bool intersect(const segment& s, const segment& t) {
	return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
		ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

inline bool intersect(const segment& s, const point& p) {
	return ccw(s.a, s.b, p) == 0;
}

inline double dist(const point& a, const point& b) {
	return abs(a - b);
}

inline point crosspoint(const segment& s, const segment& t) {
	if(!intersect(s, t)) // 交点を持たない
		return s.a; // 用改善

	const double tmp = cross(s.b - s.a, t.b - t.a);
	if(abs(tmp) < EPS) { // 一直線上
		if(intersect(s, t.a)) return t.a;
		if(intersect(s, t.b)) return t.b;
		if(intersect(t, s.a)) return s.a;
		return s.b;
	}

	return t.a + (t.b - t.a) * cross(s.b - s.a, s.b - t.a) * (1.0 / tmp);
}

inline point next_point() {
	double x, y;
	cin >> x >> y;
	return point(x, y);
}

const int MAX_REFLECTION = 5;
int n;
double ans;
point start, goal;
vector<segment> mirrors;

inline void reflect(point &a, const segment &target) {
	const point p = projection(line(target.a, target.b), a);
	a = a + (p - a) * 2;
}

inline void reflect(vector<segment> &segments, const segment &target) {
	for(auto& seg : segments) {
		reflect(seg.a, target);
		reflect(seg.b, target);
	}
}

double calc(vector<int> &order) {
	vector<segment> t_mirrors(mirrors);
	point t_goal(goal);

	for(int i = 0; i < static_cast<int>(order.size()); ++i) {
		const int idx = order[i];
		if(min(dist(start, t_mirrors[idx].a), dist(start, t_mirrors[idx].b)) + EPS > ans)
			return INT_MAX;

		reflect(t_mirrors, t_mirrors[idx]);
		reflect(t_goal, t_mirrors[idx]);
	}

	t_mirrors = mirrors;
	point current(start);

	for(int i = 0; i < static_cast<int>(order.size()); ++i) {
		const int idx = order[i];
		const segment rest_beam(current, t_goal);
		if(!intersect(rest_beam, t_mirrors[idx])) return -1.0;

		const point cp = crosspoint(rest_beam, t_mirrors[idx]);
		const segment next_beam(current, cp);

		for(int j = 0; j < n; ++j) {
			if(j == idx) continue;
			if(i && j == order[i - 1]) continue;
			if(intersect(next_beam, t_mirrors[j])) return -2.0;
		}

		current = cp;
		reflect(t_mirrors, t_mirrors[idx]);
	}

	const segment last_beam(current, t_goal);
	for(int i = 0; i < n; ++i) {
		if(order.size() && order.back() == i) continue;
		if(intersect(last_beam, t_mirrors[i])) return -3.0;
	}

	return dist(start, t_goal);
}

void dfs(vector<int> &order) {
	const double result = calc(order);
	if(result >= 0.0) {
		chmin(ans, result);
		return;
	}

	if(order.size() == MAX_REFLECTION) return;

	for(int i = 0; i < n; ++i) {
		if(order.size() && order.back() == i) continue;
		order.emplace_back(i);
		dfs(order);
		order.pop_back();
	}
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout.flags(ios::fixed);
	cout.precision(4);

	while(cin >> n && n) {
		mirrors.clear();
		mirrors.reserve(n);
		for(int i = 0; i < n; ++i) {
			mirrors.emplace_back(next_point(), next_point());
		}

		goal = next_point();
		start = next_point();

		ans = INT_MAX;
		vector<int> order;
		dfs(order);
		cout << ans << endl;
	}

	return EXIT_SUCCESS;
}

Measured memory_bytes: 1320