#ifndef ___GEOMETRY_LIBRARY
#define ___GEOMETRY_LIBRARY

#include <vector>
#include <algorithm>

template<class type>
class point2d {
public:
	type x, y;
	point2d() : x(type(0)), y(type(0)) {};
	point2d(type x_, type y_) : x(x_), y(y_) {};
	bool operator==(const point2d& p) { return x == p.x && y == p.y; }
	bool operator!=(const point2d& p) { return x != p.x || y != p.y; }
	point2d& operator+=(const point2d& p) { x += p.x; y += p.y; return *this; }
	point2d& operator-=(const point2d& p) { x -= p.x; y -= p.y; return *this; }
	point2d& operator*=(type val) { x *= val; y *= val; return *this; }
	point2d& operator/=(type val) { x /= val; y /= val; return *this; }
	point2d operator+(const point2d& p) const { return point2d(*this) += p; }
	point2d operator-(const point2d& p) const { return point2d(*this) -= p; }
	point2d operator*(type val) const { return point2d(*this) *= val; }
	point2d operator/(type val) const { return point2d(*this) /= val; }
	type norm() const { return x * x + y * y; }
	type abs() const { return type(std::sqrt(x * x + y * y)); }
	long double fabs() const { return std::sqrt((long double)(x * x + y * y)); }
	type dot(const point2d& p) const { return x * p.x + y * p.y; }
	type cross(const point2d& p) const { return x * p.y - y * p.x; }
	int ccw(const point2d& p1, const point2d& p2) const {
		// Centering at point p, p1 -> p2 is COUNTER-CLOCKWISE : (1)
		// Centering at point p, p1 -> p2 is CLOCKWISE : (-1)
		// Collinear with order p1 -> p -> p2 : (2)
		// Collinear with order p -> p1 -> p2 : (-2)
		// Collinear with order p -> p2 -> p1 : (0)
		point2d pr1 = p1 - point2d(*this);
		point2d pr2 = p2 - point2d(*this);
		if (pr1.cross(pr2) != 0) return pr1.cross(pr2) > 0 ? 1 : -1;
		if (pr1.dot(pr2) < 0) return 2;
		return pr1.norm() < pr2.norm() ? -2 : 0;
	}
};

template<class type>
class segment2d {
public:
	point2d<type> p1, p2;
	segment2d() : p1(point2d<type>()), p2(point2d<type>()) {};
	segment2d(const point2d<type>& p1_, const point2d<type>& p2_) : p1(p1_), p2(p2_) {};
	type norm() const { return (p1 - p2).norm(); }
	type abs() const { return (p1 - p2).abs(); }
	long double fabs() const { return (p1 - p2).fabs(); }
};

// DETERMINE IF "SEGMENT" S1 AND S2 INTERSECTS
template<class type>
bool intersect(const segment2d<type>& s1, const segment2d<type>& s2) {
	int f1 = s1.p1.ccw(s1.p2, s2.p1) * s1.p1.ccw(s1.p2, s2.p2);
	int f2 = s2.p1.ccw(s2.p2, s1.p1) * s2.p1.ccw(s2.p2, s1.p2);
	return (f1 <= 0 && f2 <= 0);
}

// FIND THE DISTANCE OF POINT P AND "LINE/SEGMENT" S
template<class type>
type distance(const point2d<type>& p, const segment2d<type>& s, bool isline) {
	type nx = (s.p2 - s.p1).norm();
	type d = std::abs((s.p2 - s.p1).cross(p - s.p1)) / std::sqrt(nx);
	if (isline) return d;
	type ny = (p - s.p1).norm();
	type nz = (p - s.p2).norm();
	if (nx + ny < nz) return std::sqrt(ny);
	if (nx + nz < ny) return std::sqrt(nz);
	return d;
}

#endif // ___GEOMETRY_LIBRARY

#include <iostream>
#include <algorithm>
using namespace std;
int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);
	int q;
	cin >> q;
	cout.precision(15);
	for (int i = 0; i < q; ++i) {
		segment2d<double> s1, s2;
		cin >> s1.p1.x >> s1.p1.y >> s1.p2.x >> s1.p2.y >> s2.p1.x >> s2.p1.y >> s2.p2.x >> s2.p2.y;
		if (intersect(s1, s2)) {
			cout << 0 << "\n";
		}
		else {
			double d1 = distance(s1.p1, s2, false);
			double d2 = distance(s1.p2, s2, false);
			double d3 = distance(s2.p1, s1, false);
			double d4 = distance(s2.p2, s1, false);
			double ans = min({ d1, d2, d3, d4 });
			cout << ans << endl;
		}
	}
	return 0;
}


Measured memory_bytes: 3316