#include <iostream>
#include <cstdio>
#include <vector>
#include <list>
#include <complex>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <cstring>
#include <stack>
#include <cmath>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <cassert>
#include <numeric>
using namespace std;
typedef long long ll;
typedef pair<int,int> PI;
#define EPS (1e-10)
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define REP(i, n) rep (i, n)
#define F first
#define S second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define min3(a,b,c) min((a),min((b),(c)))
#define min4(a,b,c,d) min((a),min3((b),(c),(d)))
#define SZ(a) (int)((a).size())
#define ALL(a) a.begin(),a.end()
#define FLL(a,b) memset((a),b,sizeof(a))
#define CLR(a) memset((a),0,sizeof(a))
#define FOR(it,a) for(__typeof(a.begin())it=a.begin();it!=a.end();++it)
template<typename T,typename U> ostream& operator<< (ostream& out, const pair<T,U>& val){return out << "(" << val.F << ", " << val.S << ")";}
template<class T> ostream& operator<< (ostream& out, const vector<T>& val){out << "{";rep(i,SZ(val)) out << (i?", ":"") << val[i];return out << "}";}
typedef double FP;
typedef complex<FP> pt;
typedef pt P;
typedef pair<pt,pt> line;
FP dot(P a,P b){return real(conj(a)*b);}
FP crs(P a,P b){return imag(conj(a)*b);}
P ortho(P a){return a*P(0,1);}
P ortho(line a){return ortho(a.S-a.F);}
P crspt(P a,P b,P c,P d){b-=a,d-=c;return a+b*crs(d,c-a)/crs(d,b);}
P crspt(line a,line b){return crspt(a.F,a.S,b.F,b.S);}
bool onl(P a1,P a2,P b){return abs(b-a1)+abs(b-a2)<abs(a1-a2)+EPS;}
bool onl(line a,P b){return onl(a.F,a.S,b);}
bool iscrs(line a,line b){P c=crspt(a,b);return onl(a,c)&&onl(b,c);}
void pkuassert(bool t){t=1/t;};
int dx[]={0,1,0,-1,1,1,-1,-1};
int dy[]={1,0,-1,0,-1,1,1,-1};
enum{TOP,BTM,LFT,RGT,FRT,BCK};
int dxdy2ce[]={RGT,FRT,LFT,BCK};
template<class T> T shift(T a,int b,int c,int d,int e){
 __typeof(a[0])t=a[b];a[b]=a[c];a[c]=a[d];a[d]=a[e];a[e]=t;
 return a;}
template<class T> T rgt(T a){return shift(a,TOP,LFT,BTM,RGT);}
template<class T> T lft(T a){return shift(a,TOP,RGT,BTM,LFT);}
template<class T> T frt(T a){return shift(a,TOP,BCK,BTM,FRT);}
template<class T> T bck(T a){return shift(a,TOP,FRT,BTM,BCK);}
line mkl(P a,P v){return line(a,a+v);}
FP lpdist(line a,P b){return abs(b-crspt(a,mkl(b,ortho(a))));}
FP spdist(line a,P b){
  P c(crspt(a,mkl(b,ortho(a))));
  return onl(a,c)?abs(b-c):min(abs(a.F-b),abs(a.S-b));
}
FP ssdist(line a,line b){
 return
  iscrs(a,b)?0.:
   min4(spdist(a,b.F),spdist(a,b.S),
        spdist(b,a.F),spdist(b,a.S));
}
namespace std{
  bool operator<(const P&a,const P&b){
    return mp(real(a),imag(a))<mp(real(b),imag(b));
  }
}
int ccw(P a, P b, P c) {
	double d = crs(b -= a, c -= a);
	return d>EPS ? 1 : d<-EPS ? -1 : dot(b,c)<-EPS ? 2 : norm(b)+EPS<norm(c) ? -2 : 0;
}
#define CCW(l, a) ccw((l).first, (l).second, (a))
#define EQ(a, b) (abs((a)-(b)) < EPS)
#define DI(l) ((l).second-(l).first)
typedef line L;
bool intersectSP(const L &s, const P &p) { return EQ(abs(s.first-p)+abs(s.second-p)-abs(DI(s)), 0); }
bool intersectSS(const L &s, const L &t) { return CCW(s,t.first)*CCW(s,t.second)<=0 && CCW(t,s.first)*CCW(t,s.second)<=0; }
bool parallel(const L &l, const L &m) { return EQ(crs(DI(l), DI(m)), 0); }
bool sameline(const L &l, const L &m) { return parallel(l, m) && EQ(crs(DI(l), m.second-l.first), 0); }


void arrange_segments(const vector<L> &ls, vector<vector<pair<int, double> > > &G, vector<P> &ps) {
  
	rep(i, SZ(ls)) {
		ps.push_back(ls[i].first);
		ps.push_back(ls[i].second);
		rep(j, i) if (intersectSS(ls[i], ls[j]) && !sameline(ls[i], ls[j]))
			ps.push_back(crspt(ls[i], ls[j]));
	}
	sort(ALL(ps));
	ps.erase(unique(ALL(ps)), ps.end());

	G.assign(SZ(ps), vector<pair<int, double> >());
	rep(i, SZ(ls)) {
		vector<pair<double, int> > as;
		rep(j, SZ(ps)) if (intersectSP(ls[i], ps[j]))
			as.push_back(make_pair(norm(ls[i].first - ps[j]), j));
		sort(ALL(as));
		rep(j, SZ(as)-1) {
			int a = as[j].second, b = as[j+1].second;
			double l = abs(ps[a] - ps[b]);
			G[a].push_back(make_pair(b, l));
			G[b].push_back(make_pair(a, l));
		}
	}
	rep(i, SZ(G)) {
		sort(ALL(G[i]));
		G[i].erase(unique(ALL(G[i])), G[i].end());
	}
}

int n;
P in[100];
bool app[2000];

bool ok(P a){
  vector<double> di;
  rep(i,n)
    di.pb(abs(a-in[i]));
  sort(ALL(di));
  return n>=2 && EQ(di[0],di[1]);
}

void solve(){
  rep(i,n) cin >> in[i].real() >> in[i].imag();

  CLR(app);
  vector<line> li;
  rep(i,n)rep(j,i){
    line ij(ortho(in[i]-in[j])+(in[i]+in[j])*0.5,(in[i]+in[j])*0.5);
    P t=ij.F-ij.S;
    t *= 10/abs(t);
    ij.F+=t;
    ij.S-=t;
    li.pb(ij);
  }
  li.pb(line(P(0,-1),P(0,5)));
  li.pb(line(P(4,-1),P(4,5)));
  vector<vector<pair<int, double> > > G;
  priority_queue<pair<double,int> > q;  
  vector<P> ps;
  arrange_segments(li,G,ps);
  FOR(it,ps) if(onl(line(P(0,0),P(0,4)),*it)) 
    q.push(mp(0,it-ps.begin()));
  while(!q.empty()){
    double cc=-q.top().F;
    int cv=q.top().S;
    q.pop();
    double cx=real(ps[cv]);
    double cy=imag(ps[cv]);
    
    if(min(cx,cy)<-EPS || max(cx,cy)>4+EPS) continue;
    if(app[cv]) continue;
    if(EQ(cx,4)){
      printf("%.8f\n",cc);
      return;
    }
    app[cv]=true;
    FOR(it,G[cv]){
      line ed(ps[cv],ps[it->F]);
      if(ok(ed.F) && ok(ed.S) && ok((ed.F+ed.S)*0.5))
        q.push(mp(-cc-it->S,it->F));
    }

  }

  cout << "impossible" << endl;
}

int main(int argc, char *argv[])
{
  while(cin >> n && n) solve();
  return 0;
}

Measured memory_bytes: 1500