#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;

const int N = 300 + 10;
const int V = N * N;
const int M = V * 10;
const double INF = 1e10;
const double EPS = 1e-8;

int sign(long double x)
{
	return x < -EPS ? -1 : x > EPS;
}

struct Edge
{
	double w;
	int t;
	Edge *n;
};

Edge edges[M], *totEdge, *firstEdge[V];

struct Point
{
	long double x, y;
	Point() {}
	Point(long double x, long double y) : x(x), y(y) {
	}
	Point operator + (const Point &that) const {
		return Point(x + that.x, y + that.y);
	}
	Point operator - (const Point &that) const {
		return Point(x - that.x, y - that.y);
	}
	Point operator * (const long double &that) const {
		return Point(x * that, y * that);
	}
	Point operator / (const long double &that) const {
		return Point(x / that, y / that);
	}
	void read() {
		cin >> x >> y;
	}
	Point rot90() {
		return Point(y, -x);
	}
	int operator < (const Point &that) const {
		int d = sign(x - that.x);
		if (d) return d < 0;
		return sign(y - that.y) < 0;
	}
	long double det(const Point &that) const {
		return x * that.y - that.x * y;
	}
	long double distTo(const Point &that) const {
		return hypot(x - that.x, y - that.y);
	}
	void write() {
		cout << "(" << x << "," << y << ") ";
	}
};

#define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))
#define crossOp(p1,p2,p3) sign(cross(p1,p2,p3))

int n, tot;
vector<pair<Point, Point> > lines;
vector<Point> pointList;
vector<int> pointOnLine[N];
map<Point, int> points;
Point s, t;
Point a[N][2];

int insert(Point u)
{
	if (points.count(u) == 0) {
		pointList.push_back(u);
		points[u] = tot ++;
	}
	return points[u];
}

Point isSS(Point p1, Point p2, Point q1, Point q2)
{
	long double a1 = cross(q1, q2, p1), a2 = -cross(q1, q2, p2);
	return (p1 * a2 + p2 * a1) / (a1 + a2);
}

int cmp(const int &a, const int &b)
{
	return pointList[a] < pointList[b];
}

void addEdge(int s, int t, long double w)
{
	Edge *e = totEdge ++;
	e->w = w; e->t = t; e->n = firstEdge[s]; firstEdge[s] = e;
}

long double dij(int s, int t)
{
	priority_queue< pair<double, int> > que;
	int in[V];
	double dis[V];
	for(int i = 0; i < tot; ++ i) {
		dis[i] = INF;
		in[i] = false;
	}
	dis[s] = 0;
	que.push(make_pair(0, s));

	for( ; que.size(); ) {
		int u = que.top().second;
		que.pop();
		if (in[u]) continue;
		in[u] = true;
		if (u == t) return dis[t];
		for(Edge *e = firstEdge[u]; e; e = e->n) {
			int v = e->t;
			if (dis[v] > dis[u] + e->w) {
				dis[v] = dis[u] + e->w;
				que.push(make_pair(-dis[v], v));
			}
		}
	}
	return INF;
}

void solve()
{
	lines.clear();
	s.read(); t.read();
	for(int i = 0; i < n; ++ i) {
		a[i][0].read();
		a[i][1].read();
		Point vec = (a[i][1] - a[i][0]).rot90();
		Point s1 = a[i][0], t1 = s1 + vec;
		Point s2 = a[i][1], t2 = s2 + vec;
		lines.push_back(make_pair(s1, t1));
		lines.push_back(make_pair(s2, t2));
		if (crossOp(s1, t1, s) * crossOp(s2, t2, s) <= 0) {
			lines.push_back(make_pair(s, s + vec));
		}
		if (crossOp(s1, t1, t) * crossOp(s2, t2, t) <= 0) {
			lines.push_back(make_pair(t, t + vec));
		}
	}
	
	pointList.clear();
	tot = 0;
	points.clear();
	insert(s);
	insert(t);

	for(int i = 0; i < lines.size(); ++ i) {
		pointOnLine[i].clear();
	}
	for(int i = 0; i < lines.size(); ++ i) {
		if (crossOp(lines[i].first, lines[i].second, s) == 0) {
			pointOnLine[i].push_back(insert(s));
		}
		if (crossOp(lines[i].first, lines[i].second, t) == 0) {
			pointOnLine[i].push_back(insert(t));
		}
		for(int j = i + 1; j < lines.size(); ++ j) {
			if (sign((lines[i].second - lines[i].first).det(lines[j].second - lines[j].first)) == 0) 
				continue;
			Point p = isSS(lines[i].first, lines[i].second, lines[j].first, lines[j].second);
			int id = insert(p);
			pointOnLine[i].push_back(id);
			pointOnLine[j].push_back(id);
		}
	}

	totEdge = edges;
	for(int i = 0; i < tot; ++ i) {
		firstEdge[i] = 0;
	}
	for(int i = 0; i < lines.size(); ++ i) {
		sort(pointOnLine[i].begin(), pointOnLine[i].end(), cmp);
		pointOnLine[i].resize(unique(pointOnLine[i].begin(), pointOnLine[i].end()) - pointOnLine[i].begin());
		for(int j = 1; j < pointOnLine[i].size(); ++ j) {
			int u = pointOnLine[i][j - 1], v = pointOnLine[i][j];
			addEdge(u, v, pointList[u].distTo(pointList[v]));
			addEdge(v, u, pointList[u].distTo(pointList[v]));
		}
	}

	double ret = dij(points[s], points[t]);
	if (ret >= INF) cout << "Impossible" << endl;
	else {
		printf("%.12f\n", (double)ret);
	}
}

int main()
{
	int test = 0;
	for( ; cin >> n && n; ) {
		printf("Case %d: ", ++ test);
		solve();
	}
	return 0;
}

Measured memory_bytes: 8548