#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a,b) (a<(b)?(a=b,1):0)
#define chmin(a,b) (a>(b)?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
const int INF = 1<<29;
const double EPS = 1e-8;
const double PI = acos(-1);
typedef pair<int,int> pii;
typedef long long ll;

typedef valarray<double> point;
struct line : public vector<point> {
  line() {}
  line(point a, point b) { push_back(a); push_back(b); }
  point v() const { return (*this)[1]-(*this)[0]; }
};
point Point(double x, double y, double z) {
  point p(3);
  p[0]=x;p[1]=y;p[2]=z;
  return p;
}
double dot(const point& a, const point& b) {
  return (a * b).sum();
}
point cross(const point& a, const point& b) {
  return a.cshift(+1)*b.cshift(-1)
       - a.cshift(-1)*b.cshift(+1);
}
double norm(const point &a) {
  return dot(a,a);
}
double length(const point &a) {
  return sqrt(dot(a,a));
}
double angle(const point &a, const point &b) {
  return acos( dot(a,b)/length(a)/length(b) );
}
point input() {
  double a[3];
  REP(i,3) cin >>a[i];
  return point(a,3);
}
ostream &operator<<(ostream &os, const point &a) {
  char str[200];
  snprintf(str, 199, "(%.2f, %.2f, %.2f)", a[0], a[1], a[2]);
  os << str;
  return os;
}

point projection(const line &l, const point &p) {
  double t = dot(p-l[0], l.v()) / norm(l.v());
  return l[0] + t * l.v();
}
bool intersectSP(const line &s, const point &p) {
  return length(s[0]-p) + length(s[1]-p) - length(s[1]-s[0]) < EPS;
}
double distanceLP(const line &l, const point &p) {
  const point r = projection(l,p);
  return length(r-p);
}
double distanceSP(const line &s, const point &p) {
  const point r = projection(s, p);
  if (intersectSP(s, r)) { return length(r-p); }
  return min(length(s[0]-p), length(s[1]-p));
}

int crosspointPlL(const point &p, const point &n, const line &l, point &res) {
  double d = dot(n,l.v());
  if (abs(d) < EPS) return 0;
  double t = -dot(n,l[0]-p) / d;
  res = l[0]+t*l.v();
  return t>-EPS?1:-1;
}

// AOJ2081?
double distanceLL(const line &l, const line &m) {
  point n = cross(l.v(),m.v());
  return abs(dot(n,l[0]-m[0]))/length(n);
}

double dist[102][102];

int main() {
  int n;
  while(cin >> n, n) {
    point ps(input());
    point pt(input());
    vector<line> ls;
    REP(i,n) {
      point a(input());
      point b(input());
      ls.push_back(line(a,b));
    }
    dist[n][n] = dist[n+1][n+1] = 0;
    dist[n][n+1] = dist[n+1][n] = INF;
    REP(i,n) {
      dist[i][n] = dist[n][i] = distanceLP(ls[i],ps);
      dist[i][n+1] = dist[n+1][i] = distanceLP(ls[i],pt);
      REP(j,n) {
        dist[i][j] = distanceLL(ls[i],ls[j]);
      }
    }
    n += 2;
    REP(k,n)REP(i,n)REP(j,n) {
      chmin(dist[i][j],dist[i][k]+dist[k][j]);
    }
    printf("%.10f\n", dist[n-2][n-1]);
  }
}

Measured memory_bytes: 1364