#include <bits/stdc++.h>

using namespace std;

const double EPS = 1e-10, PI = acos(-1);

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

#define curr(P, i) P[i]
#define next(P, i) P[(i+1)%P.size()]
#define prev(P, i) P[(i+P.size()-1) % P.size()]

enum
{
  OUT, ON, IN
};
namespace Geometory
{
  struct Point
  {
    double x, y;

    Point() {};

    Point(double x, double y) : x(x), y(y) {};

    Point operator+(const Point &b) const { return Point(x + b.x, y + b.y); }

    Point operator-(const Point &b) const { return Point(x - b.x, y - b.y); }

    Point operator*(const double b) const { return Point(x * b, y * b); }

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

    Point operator/(const double b) const { return Point(x / b, y / b); }

    bool operator<(const Point &b) const { return x != b.x ? x < b.x : y < b.y; }

    bool operator==(const Point &b) const { return eq(x, b.x) && eq(y, b.y); }

    double norm() { return x * x + y * y; }

    double arg() { return atan2(x, y); }

    double abs() { return sqrt(norm()); }

    Point rotate(double theta) { return Point(cos(theta) * x - sin(theta) * y, sin(theta) * x + cos(theta) * y); }

    Point rotate90() { return Point(-y, x); }

    friend ostream &operator<<(ostream &os, Point &p) { return os << "(" << p.x << "," << p.y << ")"; }

    friend istream &operator>>(istream &is, Point &a) { return is >> a.x >> a.y; }
  };

  struct Line
  {
    Point a, b;

    Line() {};

    Line(Point a, Point b) : a(a), b(b) {};

    friend ostream &operator<<(ostream &os, Line &p) { return os << "(" << p.a.x << "," << p.a.y << ") to (" << p.b.x << "," << p.b.y << ")"; }

    friend istream &operator>>(istream &is, Line &a) { return is >> a.a.x >> a.a.y >> a.b.x >> a.b.y; }
  };

  struct Segment
  {
    Point a, b;

    Segment() {};

    Segment(Point a, Point b) : a(a), b(b) {};

    friend ostream &operator<<(ostream &os, Segment &p) { return os << "(" << p.a.x << "," << p.a.y << ") to (" << p.b.x << "," << p.b.y << ")"; }

    friend istream &operator>>(istream &is, Segment &a) { return is >> a.a.x >> a.a.y >> a.b.x >> a.b.y; }
  };

  typedef vector< Point > Polygon;
  typedef vector< Segment > Segments;

  double cross(const Point &a, const Point &b)
  {
    return a.x * b.y - a.y * b.x;
  }

  double dot(const Point &a, const Point &b)
  {
    return a.x * b.x + a.y * b.y;
  }

  int ccw(const Point &a, Point b, Point c)
  {
    b = b - a, c = c - a;
    if(cross(b, c) > EPS) return +1;
    if(cross(b, c) < -EPS) return -1;
    if(dot(b, c) < 0) return +2;
    if(b.norm() < c.norm()) return -2;
    return 0;
  }

  Point Crosspoint(const Line &l, const Line &m)
  {
    double A = cross(l.b - l.a, m.b - m.a);
    double B = cross(l.b - l.a, l.b - m.a);
    if(abs(A) < EPS && abs(B) < EPS) return m.a;
    return m.a + (m.b - m.a) * B / A;
  }

  Line Bisector(Point a, Point b)
  {
    Point c = (a + b) * 0.5;
    Point p = Point(c.x + (a.y - b.y), c.y + (b.x - a.x));
    return (Line(c, p));
  }

  Polygon Convex_Cut(Polygon &U, Line l)
  {
    Polygon ret;
    for(int i = 0; i < U.size(); i++) {
      Point now = curr(U, i), nxt = next(U, i);
      if(ccw(l.a, l.b, now) != -1) ret.push_back(now);
      if(ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) < 0) {
        ret.push_back(Crosspoint(Line(now, nxt), l));
      }
    }
    return (ret);
  }
};

int main()
{
  int N;
  while(cin >> N, N) {
    vector< Geometory::Point > points(N);
    Geometory::Polygon U(4);
    U[0] = Geometory::Point(0, 0);
    U[1] = Geometory::Point(4, 0);
    U[2] = Geometory::Point(4, 4);
    U[3] = Geometory::Point(0, 4);

    for(int i = 0; i < N; i++) {
      cin >> points[i];
    }

    vector< Geometory::Polygon > voronoi(N);
    for(int i = 0; i < N; i++) {
      voronoi[i] = U;
      for(int j = 0; j < N; j++) {
        if(i == j) continue;
        voronoi[i] = Geometory::Convex_Cut(voronoi[i], Geometory::Bisector(points[i], points[j]));
      }
    }

    vector< Geometory::Point > ventex;
    for(int i = 0; i < N; i++) {
      for(auto &point : voronoi[i]) ventex.push_back(point);
    }

    vector< vector< double > > g(ventex.size(), vector< double >(ventex.size(), 1e9));

    for(int i = 0; i < ventex.size(); i++) {
      for(int j = i + 1; j < ventex.size(); j++) {
        auto &a = ventex[i], &b = ventex[j];
        int near = 0;
        for(int k = 0; k < N; k++) {
          for(int l = 0; l < voronoi[k].size(); l++) {
            auto &c = curr(voronoi[k], l), &d = next(voronoi[k], l);
            if((a == c && b == d) || (a == d && b == c)) ++near;
          }
        }
        if(near >= 2) g[i][j] = g[j][i] = (ventex[i] - ventex[j]).abs();
      }
    }


    for(int k = 0; k < ventex.size(); k++) {
      for(int i = 0; i < ventex.size(); i++) {
        for(int j = 0; j < ventex.size(); j++) {
          g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
        }
      }
    }

    double cost = 1e9;
    for(int i = 0; i < ventex.size(); i++) {
      for(int j = 0; j < ventex.size(); j++) {
        if(eq(ventex[i].x, 0) && eq(ventex[j].x, 4)) cost = min(cost, g[i][j]);
      }
    }

    if(eq(cost, 1e9)) cout << "impossible" << endl;
    else cout << fixed << setprecision(15) << cost << endl;
  }
}

Measured memory_bytes: 3216