#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#ifndef NULL
#define NULL 0
#endif
using namespace std;

const int MAXN = 50000 + 10;
const double pi = acos(-1.0);
const double inf = 1e100;
const double eps = 1e-12;

inline double read() //浮点型快读
{
    double num;
    char in;
    double Dec = 0.1;
    bool IsN = false, IsD = false;
    in = getchar();
    while (in != '-' && in != '.' && (in < '0' || in > '9'))
        in = getchar();
    if (in == '-') {
        IsN = true;
        num = 0;
    } else if (in == '.') {
        IsD = true;
        num = 0;
    } else
        num = in - '0';
    if (!IsD) {
        while (in = getchar(), in >= '0' && in <= '9') {
            num *= 10;
            num += in - '0';
        }
    }
    if (in != '.') {
        if (IsN)
            num = -num;
        return num;
    } else {
        while (in = getchar(), in >= '0' && in <= '9') {
            num += Dec * (in - '0');
            Dec *= 0.1;
        }
    }
    if (IsN)
        num = -num;
    return num;
}

int zhengfu(double d)
{
    if (fabs(d) < eps)
        return 0;
    if (d > 0)
        return 1;
    return -1;
}
int bijiao(double x, double y)
{
    if (fabs(x - y) < eps)
        return 0;
    if (x > y)
        return 1;
    return -1;
}
int bijiao2(double x, double y)
{
    if (fabs(x - y) < eps || x > y)
        return 1;
    return 0;
}

struct vec {
    double x, y;
    vec(double x, double y)
    {
        this->x = x;
        this->y = y;
    }
    vec() {}
    vec operator*(const vec& i_T) const
    {
        return vec(x * i_T.x, y * i_T.y);
    }
    vec operator*(double u) const
    {
        return vec(x * u, y * u);
    }
    bool operator==(const vec& i_T) const
    {
        return x == i_T.x && y == i_T.y;
    }
    vec operator/(double u) const
    {
        return vec(x / u, y / u);
    }
    vec operator+(const vec& i_T)
    {
        return vec(x + i_T.x, y + i_T.y);
    }
    vec operator-(const vec& i_T)
    {
        return vec(x - i_T.x, y - i_T.y);
    }
} p[MAXN];

double chaji(vec A, vec B)
{
    return A.x * B.y - A.y * B.x; // 正为A->B左旋
}
double dianji(vec A, vec B)
{
    return A.x * B.x + A.y * B.y;
}

double changdu(vec a) //长度
{
    return sqrt(a.x * a.x + a.y * a.y);
}
vec touying(vec a, vec b, vec c) //c投影在ab上的位置
{
    vec A = b - a;
    vec B = c - a;
    double La = changdu(A);
    double Lc = dianji(A, B) / (La * La);
    return vec(Lc * A.x, Lc * A.y) + a;
}
vec fanshe(vec a, vec b, vec c) //求c关于ab的对称点c'
{
    vec A = touying(a, b, c);
    return (A - c) * 2.0 + c;
}
bool bijiao3(vec a, vec b, vec c)
{
    if (a.x <= c.x && c.x <= b.x && ((a.y <= c.y && c.y <= b.y || b.y <= c.y && c.y <= a.y)))
        return 1;
    return 0;
}
bool xiangjiao(vec a, vec b, vec c, vec d) //两线段是否有交点
{
    if (a.x == b.x) {
        if (a.y > b.y)
            swap(a, b);
    } else if (a.x > b.x)
        swap(a, b);
    if (c.x == d.x) {
        if (c.y > d.y)
            swap(c, d);
    } else if (c.x > d.x)
        swap(c, d);

    double c1 = chaji(b - a, c - a), d1 = chaji(b - a, d - a);
    double c2 = chaji(d - c, a - c), d2 = chaji(d - c, b - c);
    //cout << c1 << ' ' << d1 << ' ' << c2 << ' ' << d2 << endl;
    if (zhengfu(c1 * d1) < 0 && zhengfu(c2 * d2) < 0) //ab横穿cd
        return 1;
    else if (zhengfu(c1 * d1) != 0 && zhengfu(c2 * d2) == 0) { //ab不穿过cd
        if (zhengfu(c2) == 0) {
            if (bijiao3(c, d, a))
                return 1;
        }
        if (zhengfu(d2) == 0)
            if (bijiao3(c, d, b))
                return 1;
    } else if (zhengfu(c1 * d1) == 0 && zhengfu(c2 * d2) != 0) { //cd不穿过ab
        if (c1 == 0)
            if (bijiao3(a, b, c))
                return 1;
        if (d1 == 0)
            if (bijiao3(a, b, d))
                return 1;
    } else if (zhengfu(c1 * d1) == 0 && zhengfu(c2 * d2) == 0) { //平行
        if (a == c || a == d || b == c || b == d)
            return 1;
        if (bijiao3(a, b, c) == 1)
            return 1;
        if (bijiao3(c, d, a) == 1)
            return 1;
    }
    return 0;
}
bool pingxing(vec a, vec b)
{
    return bijiao(a.x * b.y, a.y * b.x) == 0;
}
vec zhixian_jiaodian(vec a, vec b, vec c, vec d)
{ //两直线交点
    double tmpLeft, tmpRight, x = inf, y = inf;
    if (xiangjiao(a, b, c, d)) {
        tmpLeft = (d.x - c.x) * (a.y - b.y) - (b.x - a.x) * (c.y - d.y);
        tmpRight = (a.y - c.y) * (b.x - a.x) * (d.x - c.x) + c.x * (d.y - c.y) * (b.x - a.x) - a.x * (b.y - a.y) * (d.x - c.x);

        x = tmpRight / tmpLeft;

        tmpLeft = (a.x - b.x) * (d.y - c.y) - (b.y - a.y) * (c.x - d.x);
        tmpRight = b.y * (a.x - b.x) * (d.y - c.y) + (d.x - b.x) * (d.y - c.y) * (a.y - b.y) - d.y * (c.x - d.x) * (b.y - a.y);
        y = tmpRight / tmpLeft;
    }
    return vec(x, y);
}
double mianji(vec a, vec b, vec c)
{
    return fabs(chaji(b - a, c - a));
}
double diandaoxianduan(vec a,vec b,vec c)
{
    double l=changdu(b-a);
    double r=dianji(b-a,c-a)/(l*l);
    //cout<<r<<endl;
    if(zhengfu(r)==-1){
        return changdu(c-a);
    }
    else if(bijiao2(r,1)){
        return changdu(c-b);
    }
    else{
        double l=r*changdu(b-a),l2=changdu(c-a);
        return sqrt(l2*l2-l*l);
    }
}
double xianduanjuli(vec a, vec b, vec c, vec d)
{
    if(xiangjiao(a,b,c,d))
        return 0.0;
    double minn=inf;
    double l=diandaoxianduan(a,b,c);
    minn=bijiao2(minn,l)?l:minn;
    l=diandaoxianduan(a,b,d);
    minn=bijiao2(minn,l)?l:minn;
    l=diandaoxianduan(c,d,a);
    minn=bijiao2(minn,l)?l:minn;
    l=diandaoxianduan(c,d,b);
    minn=bijiao2(minn,l)?l:minn;
    return minn;
}
int main()
{
    int n;
    cin >> n;
    double minn = 0;
    for (int i = 0; i < n; i++) {
        vec a, b, c, d;
        cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y >> d.x >> d.y;
        printf("%.10f\n", xianduanjuli(a,b,c,d));
    }
    return 0;
}


Measured memory_bytes: 3292