#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e12;
 
struct Point{
    double x,y,z;
    Point(double x, double y, double z):x(x), y(y), z(z){}
    Point(){}
    Point &operator +=(const Point &a){ x+=a.x; y+=a.y; z+=a.z; return *this; }
    Point &operator -=(const Point &a){ x-=a.x; y-=a.y; z-=a.z; return *this; }
    Point &operator *=(const double &a){ x*=a; y*=a; z*=a; return *this; }
    Point operator +(const Point &a) const{ return Point(x+a.x, y+a.y, z+a.z); }
    Point operator -(const Point &a) const{ return Point(x-a.x, y-a.y, z-a.z); }
    Point operator *(const double &a) const{ return Point(a*x, a*y, a*z); }
    Point operator -() { return Point(-x, -y, -z); }
};
struct Obj{
    Point p;
    double r;
    Obj(Point &p, double r):p(p), r(r){}
    Obj(){}
};
 
double dot(const Point &a, const Point &b){
    return a.x*b.x +a.y*b.y +a.z*b.z;
}
Point cross(const Point &a, const Point &b){
    return Point(a.y*b.z -a.z*b.y, a.z*b.x -a.x*b.z, a.x*b.y -a.y*b.x);
}
double abs(const Point &a){
    return sqrt(dot(a, a));
}
Point unit(const Point &a){
    return a *(1/abs(a));
}
bool operator ==(const Point &a, const Point &b){
    return abs(a-b) < EPS;
}

Point projectionLP3(Point p, Point q, Point c){
    double t = dot(unit(q-p), c-p);
    return p +unit(q-p) *t;
}

double distanceLP3(Point p, Point q, Point c){
    return abs(projectionLP3(p, q, c) -c);
}

bool intersectLP3(Point p, Point q, Point c){
    return abs(cross(p-c, q-c)) < EPS;
}

bool isParallel(Point a, Point b, Point c, Point d){
    return abs(cross(b-a, d-c)) < EPS;
}

double distanceLL3(Point a, Point b, Point c, Point d){
    if(isParallel(a, b, c, d)){
        return distanceLP3(a, b, c);
    }
    Point v[2] = {unit(b-a), unit(d-c)};
    double d0 = (dot(v[0], c-a) -dot(v[1], c-a)*dot(v[0], v[1])) /(1 -dot(v[0], v[1])*dot(v[0], v[1]));
    double d1 = (-dot(v[1], c-a) +dot(v[0], c-a)*dot(v[0], v[1])) /(1 -dot(v[0], v[1])*dot(v[0], v[1]));
    return abs((a +v[0]*d0) -(c +v[1]*d1));
}

int main(){
    while(1){
        int n;
        cin >> n;
        if(n == 0) break;

        vector<vector<Point> > p(n, vector<Point>(2));
        Point s, t;
        cin >> s.x >> s.y >> s.z;
        cin >> t.x >> t.y >> t.z;
        int sidx=-1, tidx=-1;
        for(int i=0; i<n; i++){
            cin >> p[i][0].x >> p[i][0].y >> p[i][0].z;
            cin >> p[i][1].x >> p[i][1].y >> p[i][1].z;
            if(intersectLP3(p[i][0], p[i][1], s)){
                sidx = i;
            }
            if(intersectLP3(p[i][0], p[i][1], t)){
                tidx = i;
            }
        }
        if(sidx==-1) cerr << "sidx == -1" << endl;
        if(tidx==-1) cerr << "tidx == -1" << endl;

        vector<vector<double> > adj(n, vector<double>(n, INF));
        for(int i=0; i<n; i++){
            for(int j=i; j<n; j++){
                adj[i][j] = adj[j][i] = distanceLL3(p[i][0], p[i][1], p[j][0], p[j][1]);
            }
        }
        for(int k=0; k<n; k++){
            for(int i=0; i<n; i++){
                for(int j=0; j<n; j++){
                    adj[i][j] = min(adj[i][j], adj[i][k] +adj[k][j]);
                }
            }
        }
        cout << fixed << setprecision(10);
        cout << adj[sidx][tidx] << endl;
    }
    return 0;
}


Measured memory_bytes: 3304