/**
 * Computing Geometry Library
 * @author Sshwy
 */
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define ROF(i,a,b) for(int i=(a);i>=(b);--i)

namespace cg{
    typedef long double vtyp;
    const vtyp eps = 1e-9;
    bool isZero(vtyp x){ return -eps < x && x < eps; }
    bool equal(vtyp x, vtyp y){ return isZero(x-y); }
    bool lt(vtyp x,vtyp y){ return !equal(x,y) && x<y; }
    bool gt(vtyp x,vtyp y){ return !equal(x,y) && x>y; }
    struct vec {
        vtyp x,y;
        vec(){ x = y = 0; }
        vec(vtyp _x, vtyp _y){ x = _x, y = _y; }
        vec operator+(const vec V) const { return vec(x+V.x, y+V.y); }
        vec operator-() const { return vec(-x, -y); }
        vec operator-(const vec V) const { return *this + (-V); }
        vec operator*(const vtyp a) const { return vec(x*a, y*a); }
        friend vec operator*(const vtyp a, const vec v){ return v*a; }
        vec operator/(const vtyp a) const { return vec(x/a, y/a); }
        operator bool() const { return !(isZero(x) && isZero(y)); }
        bool operator==(const vec V) const { return bool(*this-V) == 0; }
        vtyp length(){ return sqrt(x*x + y*y); }
        /**
         * 方向角，单位 rad
         */
        vtyp ang() const { return atan2(y,x); }
        /**
         * 方向向量
         * @return 0向量或者一个单位向量
         */
        vec dir() const {
            if(*this){
                vtyp ang = atan2(y,x);
                return vec(cos(ang), sin(ang));
            } else return vec(0,0);
        }
        void read(){ scanf("%Lf%Lf",&x,&y); }
    };
    typedef vec point;

    struct line {
        point p1, p2;
        line(point _p1, point _p2){ p1 = _p1, p2 = _p2; }
    };
    typedef line segment;

    istream & operator>>(istream & in, vec & v){ 
        return in >> v.x >> v.y, in; 
    }
    ostream & operator<<(ostream & out, const vec & v){ 
        return out << v.x << " " << v.y, out;
    }
    ifstream & operator>>(ifstream & in, vec & v){ 
        return in >> v.x >> v.y, in; 
    }
    ofstream & operator<<(ofstream & out, const vec & v){ 
        return out << v.x << " " << v.y, out;
    }
    /**
     * 点积
     * a dot b == |a||b|cos theta
     */
    vtyp dot(const vec a, const vec b){ return a.x*b.x + a.y*b.y; }
    /**
     * 叉积
     * 两个向量围成的有向面积
     */
    vtyp det(const vec a, const vec b){ return a.x*b.y - a.y*b.x; }


    /**
     * 投影
     * @param L 直线
     * @param p 要求投影的点
     * @return p 在 L 上的投影坐标（即垂足）
     */
    point projection(line L, point p){
        vec d = L.p2 - L.p1;
        return L.p1 + (dot(d, p-L.p1)/d.length()) * d.dir();
    }
    /**
     * 对称点
     * @param L 直线
     * @param p 点
     * @return p 关于直线 L 的对称点
     */
    point reflection(line L, point p){
        point o = projection(L,p);
        return vtyp(2)*(o-p)+p;
    }

    /**
     * 判断向量是否平行
     */
    bool parallel(vec a, vec b){ return isZero(det(a,b)); }
    /**
     * 判断直线是否平行
     */
    bool parallel(line a, line b){ return parallel(a.p2-a.p1, b.p2-b.p1); }
    /**
     * 判断向量是否垂直
     */
    bool orthogonal(vec a, vec b){ return isZero(dot(a,b)); }
    /**
     * 判断直线是否垂直
     */
    bool orthogonal(line a, line b){ return orthogonal(a.p2-a.p1, b.p2-b.p1); }
    /**
     * 判断点 p 是否在直线L上
     */
    bool online(line L, point p){
        return parallel(L.p2-L.p1,p-L.p1);
    }
    /**
     * 判断两直线是否重合
     */
    bool coincident(line a, line b){
        return online(a, b.p1) && online(a, b.p2);
    }
    /**
     * 判断点 p 是否与有向线段共线且在反向延长线上
     */
    bool online_back(segment sl, point p){
        vec a = sl.p2-sl.p1, b = p-sl.p1;
        return parallel(a,b) && lt(dot(a,b),0);
    }
    /**
     * 判断点 p 是否与有向线段共线且在正向延长线上
     */
    bool online_front(segment sl, point p){
        vec a = sl.p1-sl.p2, b = p-sl.p2; // 倒过来
        return parallel(a,b) && lt(dot(a,b),0);
    }
    /**
     * 判断点 p 是否在线段上（含端点）
     */
    bool on_segment(segment sl, point p){
        return online(sl,p) && !online_back(sl,p) && !online_front(sl,p);
    }
    /**
     * 两条直线的交点
     * 需确保两条直线不平行
     */
    point intersection(line a, line b){
        assert(!parallel(a,b));
        vtyp x = det(a.p1-b.p1,b.p2-b.p1);
        vtyp y = det(b.p2-b.p1,a.p2-b.p1);
        return a.p1 + (a.p2-a.p1)*x/(x+y);
    }
    /**
     * 判断两个线段是否相交（含边界）
     */
    bool check_segment_intersection(segment a, segment b){
        if(cg::coincident(a,b)){
            if(on_segment(a,b.p1) 
                    || on_segment(a,b.p2)
                    || on_segment(b,a.p1) 
                    || on_segment(b,a.p2))return true;
            else return false;
        }else if(cg::parallel(a,b)){
            return false;
        }else{
            point o = cg::intersection(a,b);
            if(cg::on_segment(a,o) && cg::on_segment(b,o))return true;
            else return false;
        }
    }
    /**
     * 两个点的距离
     */
    vtyp distance(point a,point b){ return (b-a).length(); }
    /**
     * 两个线段的距离
     */
    vtyp distance(segment a,segment b){
        if(check_segment_intersection(a,b))return 0;
        vtyp res = distance(a.p1,b.p1);
        res = min(res,distance(a.p1,b.p2));
        res = min(res,distance(a.p2,b.p1));
        res = min(res,distance(a.p2,b.p2));
        point o;
        if(o = projection(b,a.p1), on_segment(b,o)){
            res = min(res,distance(a.p1,o));
        }
        if(o = projection(b,a.p2), on_segment(b,o)){
            res = min(res,distance(a.p2,o));
        }
        if(o = projection(a,b.p1), on_segment(a,o)){
            res = min(res,distance(b.p1,o));
        }
        if(o = projection(a,b.p2), on_segment(a,o)){
            res = min(res,distance(b.p2,o));
        }
        return res;
    }
}
using cg::point;
using cg::line;
using cg::segment;


int main(){
    int q;
    cin>>q;
    FOR(i,1,q){
        point p[4];
        cin>>p[0]>>p[1]>>p[2]>>p[3];
        segment s1(p[0],p[1]),s2(p[2],p[3]);
        cout<<setiosflags(ios::fixed) <<setprecision(10)
            <<cg::distance(s1,s2)<<endl;
    }
    return 0;
}



Measured memory_bytes: 3624