#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<set>
#include<queue>
#include<cstdlib>
#include<algorithm>

using namespace std;
#define pb push_back
#define mp make_pair
#define SZ(x) (int)(x).size()

typedef long long LL;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef pair<LL, LL> pll;

const double eps = 1e-10;
const double PI = acos(-1.0);
//const double PI = 3.14159265358979323846264338327950288419716939937510
int dcmp(const double &x) { if (fabs(x) < eps) return 0; return x < 0 ? -1 : 1; }
const int MOD = 1e9 + 7;
const int INF = 2e9;
const double INF_d = 1e64;

template<class T> 
T qmod(T a, T b){ T ret = 1; while (b){ if (b & 1) ret *= a; b >>= 1; a *= a; } return ret; }
template<class T>
T gcd(T a, T b){ return !b ? a : gcd(b, a % b); }
template<class T>
T ex_gcd(T a, T b, T &x, T &y){
    if (!b){ x = 1, y = 0; return a; }
    T t, ret;
    ret = ex_gcd(b, a % b, x, y);
    t = x, x = y, y = t - a / b * y;
    return ret;
}
template<class T>
T inv(T t, T p){ return t == 1 ? 1 : (p - p / t) * inv(p % t, p) % p; }
// head

typedef double db;

struct point{
    db x, y;
    point(){}
    point(db a, db b): x(a), y(b){}
    point operator + (const point &p){ return point(x + p.x, y + p.y); }
    point operator - (const point &p){ return point(x - p.x, y - p.y); }
    point operator * (const db &k){ return point(x * k, y * k); }
    point operator / (const db &k){ return point(x / k, y / k); }
    db operator ^ (const point &p){ return x * p.y - y * p.x; }
    db operator * (const point &p){ return x * p.x + y * p.y; }
    bool operator == (const point &p){ return !dcmp(x - p.x) && !dcmp(y - p.y); }
    bool operator != (const point &p){ return dcmp(x - p.x) || dcmp(y - p.y); }
    bool operator < (const point &p){ return x == p.x ? y < p.y : x < p.x; }
    void read(){
        scanf("%lf%lf", &x, &y);
    }
    void print(){
        printf("%.10f %.10f\n", x, y);
    }
    point rotate(db &ang){ return point(x * cos(ang) - y * sin(ang), y * cos(ang) + x * sin(ang)); }
    point norm() { return point(-y, x); }
    db len() { return sqrt(x * x + y * y); }
    db len2(){ return x * x + y * y; }
};

point err = point(INF_d, INF_d);

point proj_SP(point A, point B, point P){ // projection point of P in segment AB
    point AB = B - A, AP = P - A;
    return A + AB * (AP * AB / AB.len2());
}

point refl_SP(point A, point B, point P){ // reflection point of P int segment AB
    return proj_SP(A, B, P) * 2 - P;
}

struct line{
    point p[2], u;
    line(){}
    line(point s, point t){
        p[0] = s, p[1] = t;
        u = p[1] - p[0];
    }
    point get_point(double t){
        return point(p[0] + u * t);
    }
};

bool parallel(line L1, line L2){ // check whether two lines L1 and L2 are parallel
    return !dcmp(L1.u ^ L2.u);
}

bool orthogonal(line L1, line L2){ // check whether two lines L1 and L2 are orthogonal
    return !dcmp(L1.u * L2.u);
}

pair<bool, point> inter_LL(line L1, line L2){ // calculate the intersection of two lines L1 and L2
    if (parallel(L1, L2)) return mp(false, err);
    double t = ((L2.p[0] - L1.p[0]) ^ L2.u) / (L1.u ^ L2.u);
    return mp(true, L1.get_point(t));
}

bool one_dimention_check(db a, db b, db c, db d){ // check whether two one-dimention segments has intersection
    if (dcmp(a - b) > 0) swap(a, b);
    if (dcmp(c - d) > 0) swap(c, d);
    return dcmp(b - c) >= 0 && dcmp(a - d) <= 0; 
}

bool check_SS(point A, point B, point C, point D){ // check whether two segments AB and CD has intersection
    bool flag = one_dimention_check(A.x, B.x, C.x, D.x) && one_dimention_check(A.y, B.y, C.y, D.y);
    double a = dcmp((A - C) ^ (D - C)), b = dcmp((B - C) ^ (D - C)),
            c = dcmp((C - A) ^ (B - A)), d = dcmp((D - A) ^ (B - A));
    return flag && dcmp(a * b) <= 0 && dcmp(c * d) <= 0;
}
// calculate the intersection point of two segments, first check and then call inter_LL to get the cross point

bool inmid(db a, db b, db c){  // check whether a <= c <= b
    return dcmp(dcmp(b - c) * dcmp(a - c)) <= 0; 
}

bool inmid(point A, point B, point P){ // check whether point P is in the rectangle of segment AB
    return inmid(A.x, B.x, P.x) && inmid(A.y, B.y, P.y);
}

db dis_SP(point A, point B, point P){
    point p_proj = proj_SP(A, B, P);
    if (inmid(A, B, p_proj)) return (P - p_proj).len();
    else return min((P - A).len(), (P - B).len());
}

db dis_SS(point A, point B, point C, point D){
    db res = INF_d;
    if (check_SS(A, B, C, D)) res = 0;
    res = min(res, dis_SP(A, B, C));
    res = min(res, dis_SP(A, B, D));
    res = min(res, dis_SP(C, D, A));
    res = min(res, dis_SP(C, D, B));
    return res;
}

int n;

int main(){
    scanf("%d", &n);
    for (int i = 0; i < n; i++){
        point p[4];
        for (int j = 0; j < 4; j++){
            p[j].read();
        }
        
        printf("%.10f\n", dis_SS(p[0], p[1], p[2], p[3]));
    }
    return 0;
}


Measured memory_bytes: 3192