#include<iostream>
#include<queue>
#include<map>
#include<vector>
#include<cmath>
#include<complex>
#include<algorithm>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define mp         make_pair
#define pb         push_back

template<class T> void pp(T a,int n){rep(i,n)cout<<a[i]<<" ";cout<<endl;}

typedef complex<double> P;
typedef pair<P,P>       Line;

const int N = 1000010;
const double eps = 1e-10;
const double PI  = acos(-1);
const double inf = 1e10;

namespace std{
  bool operator<(const P &a,const P &b){
    if (a.real()!=b.real())return a.real()<b.real();
    return a.imag() < b.imag();
  }
}

bool isp(P a,P b,P c){
  return abs(a-c)+abs(b-c) < abs(a-b) +eps;
}

double dot(P a,P b){
  return a.real()*b.real()+a.imag()*b.imag();
}

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

double distance_lp(P a,P b,P c){
  return abs( cross(b-a,c-a))/abs(b-a);
}

bool is_intersected_ll(P a1,P a2,P b1,P b2){
  return !(fabs(cross(a1-a2,b1-b2))<eps);
}

P intersection_ll(P a1,P a2,P b1,P b2){
  P a= a2-a1,b=b2-b1;
  return a1+ a*cross(b,b1-a1)/cross(b,a);
}

P mapping(P a,P b){//mapping b to a
  double tmp = dot(a,b);
  tmp/=abs(a);
  return a/abs(a)*tmp;
}

P getp(P a,P b){
  P t=b-a;
  swap(t.real(),t.imag());
  t.real()*=-1;
  return t+a;
}

void connect(P a,P b,P c,vector<Line> &in){
  if (isp(a,b,c)){
    in.pb(mp(getp(a,b)-a+c,c));
  }else if (dot(b-a,c-a)>=0 && dot(a-b,c-b)>=0)
    in.pb(mp(mapping(b-a,c-a)+a,c));
  return;
}

void make(P a,P b,vector<Line> &all,vector<Line>&in){
  int n = all.size();
  rep(i,n){
    connect(all[i].first,all[i].second,a,in);
    connect(all[i].first,all[i].second,b,in);
  }
}

void per(vector<Line> &in,vector<Line> &in2){
  rep(i,in.size()){
    in2.pb(mp(getp(in[i].first,in[i].second),in[i].first));
    in2.pb(mp(getp(in[i].second,in[i].first),in[i].second));
  }
}

int getindex(P a,map<P,int> & M){
  int index = M.size();
  if (M.find(a) == M.end())M[a]=index;//,cout << a <<" " << index << endl;
  return M[a];
}

class state{
public:
  int now;
  double cost;
  bool operator<(const state&a)const{
    return cost > a.cost;
  }
};

vector<state> edge[N];
double cost[N];
double dijkstra(int s,int g,int n){
  rep(i,n)cost[i]=inf;
  priority_queue<state> Q;
  Q.push((state){s,0});
  cost[s]=0;
  while(!Q.empty()){
    state now = Q.top();Q.pop();
    if (cost[now.now] >now.cost)continue;
    //    cout << now.now <<" " << cost[now.now] << endl;
    if (now.now == g)return cost[now.now];
    rep(i,edge[now.now].size()){
      int nex=edge[now.now][i].now;
      double nec=cost[now.now]+edge[now.now][i].cost;
      if (nec < cost[nex]){
	cost[nex]=nec;
	Q.push((state){nex,nec});
      }
    }
  }
  return -1;
}


double solve(P s,P g,vector<Line> &in){
  vector<Line> in2;
  per(in,in2);
  make(s,g,in,in2);
  in.clear();

  vector<P> all;
  all.pb(s);
  all.pb(g);
  rep(i,in2.size()){
    all.pb(in2[i].first);
    all.pb(in2[i].second);
    REP(j,i+1,in2.size())
      if (is_intersected_ll(in2[i].first,in2[i].second,in2[j].first,in2[j].second))
	all.pb(intersection_ll(in2[i].first,in2[i].second,in2[j].first,in2[j].second));
  }
  sort(all.begin(),all.end());
  all.erase(unique(all.begin(),all.end()),all.end());

  rep(i,in2.size()){
    //    cout << in2[i].first <<" " << in2[i].second << endl;
  }

  map<P,int> M;
  rep(i,in2.size()){
    vector<P> l;
    rep(j,all.size())
      if (distance_lp(in2[i].first,in2[i].second,all[j])<eps)l.pb(all[j]);
    sort(l.begin(),l.end());
    //    pp(l,l.size());
    rep(i,(int)l.size()-1){
      int fr=getindex(l[i],M),to=getindex(l[i+1],M);
      double dist=abs(l[i]-l[i+1]);
      //      cout << l[i]<<" " << l[i+1]<<" " << dist << endl;
      edge[fr].pb((state){to,dist});
      edge[to].pb((state){fr,dist});
    }
  }

  double ans = dijkstra(getindex(s,M),getindex(g,M),M.size());
  rep(i,M.size())edge[i].clear();
  return ans;
}

main(){
  int n;
  int tc = 1;
  while(cin>>n && n){
    P s,g;
    cin>>s.real()>>s.imag()>>g.real()>>g.imag();
    vector<Line> in(n);
    rep(i,n){
      rep(j,2){
	cin>>in[i].first.real()>>in[i].first.imag();
	swap(in[i].first,in[i].second);
      }
    }
    double ans = solve(s,g,in);
    if (ans < 0)printf("Case %d: Impossible\n",tc++);
    else        printf("Case %d: %.5lf\n",tc++,ans);
  }
  return false;
}

Measured memory_bytes: 15000