#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <climits>
#include <cstring>

#define rep(i, m, n) for(int i=int(m);i<int(n);i++)
#define all(c) begin(c),end(c)

template<typename T1, typename T2>
inline void chmin(T1 &a, T2 b) { if (a > b) a = b; }

template<typename T1, typename T2>
inline void chmax(T1 &a, T2 b) { if (a < b) a = b; }

typedef long long int ll;
using ll = long long int;
using ull = long long unsigned int;
using Int = long long int;
using namespace std;
#define INF (1 << 30) - 1
#define INFl (ll)5e15
#define DEBUG 0
#define dump(x)  cerr << #x << " = " << (x) << endl
#define MOD 1000000007


//edit


namespace Geometory {
    const double EPS = 1e-10;

    inline bool equals(double a, double b) {
        return fabs(a - b) < EPS;
    }

    struct Point {
        double x, y;

        Point(double x = 0.0, double y = 0.0) : x(x), y(y) {}

        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 double k) {
            return Point(x * k, y * k);
        }

        double norm() const {
            return x * x + y * y;
        }

        double abs() const {
            return sqrt(norm());
        }

        double dot(Point p) {
            return x * p.x + y * p.y;
        }

        double cross(Point p) {
            return x * p.y - y * p.x;
        }

        bool operator<(const Point &p) const {
            return x != p.x ? x < p.x : y < p.y;
        }

        bool operator==(const Point &p) const {
            return equals(x, p.x) && equals(y, p.y);
//            return fabs(x - p.x) < EPS && fabs(y - p.y) < EPS;
        }


    };

    using Vector = Point;

    struct Segment {
        Point p1, p2;

        Segment(Point p1, Point p2) : p1(p1), p2(p2) {}

        Segment(double x1, double y1, double x2, double y2) : p1(x1, y1), p2(x2, y2) {}
    };

    using Line = Segment;


    double norm(Vector p) {
        return p.x * p.x + p.y * p.y;
    }

    double abs(Vector a) {
        return sqrt(norm(a));
    }

    double dot(Vector a, Vector b) {
        return a.dot(b);
    }

    double cross(Vector a, Vector b) {
        return a.cross(b);
    }

    //直行判定
    bool is_orthogonal(Vector a, Vector b) {
        return equals(dot(a, b), 0.0);
    }

    bool is_orthogonal(Point a1, Point a2, Point b1, Point b2) {
        return is_orthogonal(a1 - a2, b1 - b2);
    }

    bool is_orthogonal(Segment s1, Segment s2) {
        return equals(dot(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
    }

    //平行判定
    bool is_parallel(Vector a, Vector b) {
        return equals(cross(a, b), 0.0);
    }

    bool is_parallel(Point a1, Point a2, Point b1, Point b2) {
        return is_parallel(a1 - a2, b1 - b2);
    }

    bool is_parallel(Segment s1, Segment s2) {
        return equals(cross(s1.p2 - s1.p1, s2.p2 - s2.p1), 0.0);
    }

    //反時計回り
    static const int CCW = 1; // Counter Clockwise
    static const int CW = -1; // Clockwise
    static const int OB = 2; // Online Back
    static const int OF = -2; // Online Front
    static const int OS = 0; // On Segment

    // p0を中心としたとき、p2は{反時計回り、時計回り、p2->p0->p1で同一直線上、p0->p1->p2で直線上、p2がp0p1線分上} (後ろの3つの説明は雑)
    int ccw(Point p0, Point p1, Point p2) {
        Vector a = p1 - p0;
        Vector b = p2 - p0;
        if (cross(a, b) > EPS) return CCW;
        if (cross(a, b) < -EPS) return CW;
        if (dot(a, b) < -EPS) return OB;
        if (a.norm() < b.norm()) return OF;

        return OS;
    }

    //交差判定
    bool is_intersect(Point p1, Point p2, Point p3, Point p4) {
        return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
               ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0;
    }

    //交差判定
    bool is_intersect(Segment s1, Segment s2) {
        return is_intersect(s1.p1, s1.p2, s2.p1, s2.p2);
    }

    //射影を求める
    //pからsに垂直に線を引いたときの座標を返す
    Point project(Segment s, Point p) {
        Vector base = s.p2 - s.p1;
        double r = dot(p - s.p1, base) / norm(base);
        return s.p1 + base * r;
    }

    // 反射
    // pを線分sを対称軸として線対称の位置にある点を求める。
    Point reflect(Segment s, Point p) {
//        return p + (project(s, p) - p) * 2;
        return project(s, p) * 2 - p;
    }


    //距離シリーズ
    //2点間の距離
    double get_distance(Point a, Point b) {
        return abs(a - b);
    }

    // 直線lと点pの距離
    double get_distanceLP(Line l, Point p) {
        return abs(cross(l.p2 - l.p1, p - l.p1) / abs(l.p2 - l.p1));
    }

    // 線分sと点pの距離
    double get_distanceSP(Segment s, Point p) {
        if (dot(s.p2 - s.p1, p - s.p1) < 0.0) return abs(p - s.p1);
        if (dot(s.p1 - s.p2, p - s.p2) < 0.0) return abs(p - s.p2);
        return get_distanceLP(s, p);
    }

    //線分と線分の距離
    double get_distance(Segment s1, Segment s2) {
        if (is_intersect(s1, s2)) return 0.0;
        return min({get_distanceSP(s1, s2.p1),
                    get_distanceSP(s1, s2.p2),
                    get_distanceSP(s2, s1.p1),
                    get_distanceSP(s2, s1.p2),
                   });
    }


    struct Circle {
        Point c;
        double r;

        Circle(Point c = Point(), double r = 0.0) : c(c), r(r) {}
    };

    using Polygon = vector<Point>;

    std::ostream &operator<<(std::ostream &os, const Point &p) {
//        os << "(" << p.x << ", " << p.y << ")";
        os << "" << p.x << " " << p.y << "";
        return os;
    }

};

using namespace Geometory;


class Solve {
public:
    void solve() {
        Int q;
        cin >> q;
        while (q--) {
            vector<Point> p(4);
            for (int i = 0; i < 4; ++i) {
                cin >> p[i].x >> p[i].y;
            }
            Segment s1(p[0], p[1]), s2(p[2], p[3]);
            double dist = get_distance(s1, s2);
            cout << dist << endl;
        }


    }

};


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    Solve().solve();


    return 0;
}



Measured memory_bytes: 3316