#include <cstdio>
#include <utility>
#include <vector>
#include <complex>
#include <cmath>

using namespace std;

static const double EPS=1e-12;
static const double INF=1e24;

using Point=complex<double>;
using Plane=vector<Point>;

bool operator<(const Point &a, const Point &b) {
    return real(a)!=real(b)? real(a)<real(b) : imag(a)<imag(b);
}

double cross_prod(const Point &a, const Point &b) {
    return imag(conj(a)*b);
}

double dot_prod(const Point &a, const Point &b) {
    return real(conj(a)*b);
}

enum {
    ONLINE_FRONT=-2,
    CLOCKWISE,
    ON_SEGMENT,
    COUNTER_CLOCKWISE,
    ONLINE_BACK,
};

int ccwise(const Point &a, Point b, Point c) {
    b -= a; c -= a;

    if (cross_prod(b, c) > 0) {
        return COUNTER_CLOCKWISE;
    } else if (cross_prod(b, c) < 0) {
        return CLOCKWISE;
    } else if (dot_prod(b, c) < 0) {
        return ONLINE_BACK;
    } else if (norm(b) < norm(c)) {
        return ONLINE_FRONT;
    } else {
        return ON_SEGMENT;
    }
}

template <class LineType>
int ccwise(LineType l, const Point &c) {
    return ccwise(l.first, l.second, c);
}

struct Line: public pair<Point, Point> {
    Line() {}
    Line(const Point &a, const Point &b) {
        first = a;
        second = b;
    }
};

struct LineSeg: public pair<Point, Point> {
    LineSeg() {}
    LineSeg(const Point &a, const Point &b) {
        first = a;
        second = b;
    }
};

bool intersects(const Line &lhs, const Line &rhs) {
    if (abs(cross_prod(lhs.second-lhs.first, rhs.second-rhs.first)) > EPS)
        return true;

    return abs(cross_prod(lhs.second-lhs.first, rhs.first-lhs.first)) < EPS;
}

bool intersects(const Line &lhs, const Point &rhs) {
    return abs(cross_prod(lhs.second-rhs, lhs.first-rhs)) < EPS;
}

bool intersects(const LineSeg &lhs, const Line &rhs) {
    return (
        cross_prod(rhs.second-rhs.first, lhs.first-rhs.first) *
        cross_prod(rhs.second-rhs.first, lhs.second-rhs.first)
    ) < EPS;
}

bool intersects(const LineSeg &lhs, const LineSeg &rhs) {
    if (ccwise(lhs, rhs.first) * ccwise(lhs, rhs.second) > 0)
        return false;

    return ccwise(rhs, lhs.first) * ccwise(rhs, lhs.second) <= 0;
}

bool intersects(const LineSeg &lhs, const Point &rhs) {
    return (
        abs(lhs.first-rhs)+abs(lhs.second-rhs)-abs(lhs.second-lhs.first) < EPS
    );
}

double get_distance(const LineSeg &l, const Point &p) {
    if (dot_prod(l.second-l.first, p-l.first) < -EPS) {
        return abs(p-l.first);
    } else if (dot_prod(l.first-l.second, p-l.second) < -EPS) {
        return abs(p-l.second);
    }

    return abs(cross_prod(l.second-l.first, p-l.first))/abs(l.second-l.first);
}

double get_distance(const LineSeg &l, const LineSeg &m) {
    if (intersects(l, m))
        return 0.0;

    return min(
        min(get_distance(l, m.first), get_distance(l, m.second)),
        min(get_distance(m, l.first), get_distance(m, l.second))
    );
}

int main() {
    size_t q;
    scanf("%zu", &q);
    for (size_t i=0; i<q; ++i) {
        double x, y;
        scanf("%lf %lf", &x, &y);
        Point p0(x, y);

        scanf("%lf %lf", &x, &y);
        Point p1(x, y);

        scanf("%lf %lf", &x, &y);
        Point p2(x, y);

        scanf("%lf %lf", &x, &y);
        Point p3(x, y);

        LineSeg l(p0, p1), m(p2, p3);
        printf("%.9f\n", get_distance(l, m));
    }

    return 0;
}

Measured memory_bytes: 2808