#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <set>
#include <algorithm>
#include <array>
#include <complex>
#include <string>
#include <utility>
#include <map>
#include <queue>
#include <list>
#include <functional>
#include <numeric>
#include <stack>
#include <tuple>

using namespace std;
int dx[4] = { -1,0,1,0 };
int dy[4] = { 0,1,0,-1 };
const int INF = 100000000;
const long long LINF = 1000000000000000000;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-6;
using pii = std::pair<int, int>;
using ll = long long;
using pLL = std::pair<ll, ll>;
#define SORT(v) std::sort(v.begin(), v.end())
#define RSORT(v) std::sort(v.rbegin(), v.rend())
using Point = complex<double>; //点
#define X real() //実部
#define Y imag() //虚部
double dot(Point a, Point b) { //内積
    return (a.X * b.X + a.Y * b.Y);
}
using Line = pair<Point, Point>; //直線
Point Projection(Line s, Point p) { //点から直線への射影
    Point vase = s.second - s.first;
    p -= s.first;
    return s.first + dot(p, vase) / norm(vase) * vase;
}
Point Reflection(Line s, Point p) { //直線に対して線対称な点
    return p + (Projection(s, p) - p) * 2.0;
}
double cross(Point a, Point b) { //外積
    return a.X * b.Y - a.Y * b.X;
}
int ccw(Point a, Point b, Point c) { //直線に対する点の位置
    if (cross(b - a, c - a) > EPS)return 1;
    if (cross(b - a, c - a) < -EPS)return -1;
    if (dot(b - a, c - a) < -EPS)return 2;
    if (abs(b - a) + EPS < abs(c - a))return -2;
    return 0;
}
bool isOrthogonal(Line a, Line b) { //直行判定
    return dot(a.second - a.first, b.second - b.first) ? 0 : 1;
}
bool isParallel(Line a, Line b) { //平行判定
    return cross(a.second - a.first, b.second - b.first) ? 0 : 1;
}
bool isCross(Line a, Line b) { //交差判定
    if (ccw(a.first, a.second, b.first) * ccw(a.first, a.second, b.second) <= 0 and
        ccw(b.first, b.second, a.first) * ccw(b.first, b.second, a.second) <= 0) {
        return true;
    }
    return false;
}
Point CrossPoint(Line a, Line b) { //直線の交点
    double x, d;
    Point p1, p2, p3, p4;
    p1 = a.first;
    p2 = a.second;
    p3 = b.first;
    p4 = b.second;
    x = (p4.Y - p3.Y) * (p4.X - p1.X) - (p4.X - p3.X) * (p4.Y - p1.Y);
    d = (p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y);
    return p1 + x / d * (p2 - p1);
}
double PointLineDis(Line l, Point p) {
    Point a = l.first, b = l.second, c = p;
    return abs(cross(c - a, b - a)) / abs(b - a);
}
double PointSegDis(Line a, Point p) {
    Point p1 = a.first, p2 = a.second;
    if (dot(p2 - p1, p - p1) < EPS)return abs(p - p1);
    if (dot(p1 - p2, p - p2) < EPS)return abs(p - p2);
    return PointLineDis(a, p);
}
double SegSegDis(Line a, Line b) {
    if (isCross(a, b)) return 0;
    double res = PointSegDis(a, b.first);
    res = min(res, PointSegDis(a, b.second));
    res = min(res, PointSegDis(b, a.first));
    res = min(res, PointSegDis(b, a.second));
    return res;
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    Point p1, p2, p3, p4;
    int q;
    cin >> q;
    for (int i = 0; i < q; ++i) {
        double x1, x2, y1, y2, x3, x4, y3, y4;
        cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> x4 >> y4;
        p1 = Point(x1, y1);
        p2 = Point(x2, y2);
        p3 = Point(x3, y3);
        p4 = Point(x4, y4);
        Line l1 = Line(p1, p2), l2 = Line(p3, p4);
        printf("%.9f\n", SegSegDis(l1, l2));
    }
    return 0;

}


Measured memory_bytes: 3368