#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); } 
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
namespace LibraryOfComputationalGeometry {
	typedef long double ld;
	const ld eps = 1e-9;
	struct point {ld x, y; };
	struct line {point a, b; }; //Be sure that a and b are distinct.
	void ReadPointInt(point &a) {read(a.x), read(a.y); }
	void PrintPoint(point a) {printf("%.10Lf %.10Lf\n", a.x, a.y); }
	void ReadLineInt(line &a) {ReadPointInt(a.a), ReadPointInt(a.b); }
	void CerrPoint(point a) {cerr << a.x << ' ' << a.y << endl; }
	void CerrLine(line a) {cerr << a.a.x << ' ' << a.a.y << ' ' << a.b.x << ' ' << a.b.y << endl; }
	point operator + (point a, point b) {return (point) {a.x + b.x, a.y + b.y}; }
	point operator - (point a, point b) {return (point) {a.x - b.x, a.y - b.y}; }
	point operator * (point a, ld b) {return (point) {a.x * b, a.y * b}; }
	ld dot(point a, point b) {return a.x * b.x + a.y * b.y; }
	ld operator * (point a, point b) {return a.x * b.y - a.y * b.x; }
	ld moo(point a) {return sqrtl(a.x * a.x + a.y * a.y); }
	ld dist(point a, point b) {return moo(a - b); }
	point unit(point a) {
		ld tmp = moo(a);
		assert(tmp > eps);
		return a * (1.0 / tmp);
	}
	point Projection(point x, line a) {
		ld d = dot(x - a.a, a.b - a.a) / dist(a.a, a.b);
		return a.a + unit(a.b - a.a) * d;
	}
	point Reflection(point x, line a) {
		return Projection(x, a) * 2 - x;
	}
	bool OnLine(point x, line a) {
		return fabsl((a.b - a.a) * (x - a.a)) <= eps;
	}
	bool OnSegment(point x, line a) {
		return dist(x, a.a) + dist(x, a.b) - dist(a.a, a.b) <= eps;
	}
	bool Parallel(line a, line b) {
		return fabsl((a.b - a.a) * (b.b - b.a)) <= eps;
	}
	bool Orthogonal(line a, line b) {
		return fabsl(dot(a.b - a.a, b.b - b.a)) <= eps;
	}
	bool SegmentIntersect(line a, line b) {
		if (Parallel(a, b)) return OnSegment(b.a, a) || OnSegment(b.b, a) || OnSegment(a.a, b) || OnSegment(a.b, b);
		ld tmp = ((a.b - a.a) * (b.a - a.a)) * ((a.b - a.a) * (b.b - a.a));
		ld tnp = ((b.b - b.a) * (a.a - b.a)) * ((b.b - b.a) * (a.b - b.a));
		return tmp <= eps && tnp <= eps;
	}
	point LineIntersection(line a, line b) {
		assert(!Parallel(a, b));
		ld tmp = (b.a - a.a) * (b.b - a.a);
		ld tnp = (b.b - a.b) * (b.a - a.b);
		return (a.a * tnp + a.b * tmp) * (1 / (tmp + tnp));
	}
	ld DistanceToSegment(point x, line a) {
		point tmp = Projection(x, a);
		if (OnSegment(tmp, a)) return dist(x, tmp);
		else return min(dist(x, a.a), dist(x, a.b));
	}
}
int main() {
	using namespace LibraryOfComputationalGeometry;
	int q; read(q);
	while (q--) {
		line a, b;
		ReadLineInt(a);
		ReadLineInt(b);
		if (SegmentIntersect(a, b)) printf("%.10Lf\n", (ld) 0.0);
		else printf("%.10Lf\n", min(min(DistanceToSegment(a.a, b), DistanceToSegment(a.b, b)),
					    min(DistanceToSegment(b.a, a), DistanceToSegment(b.b, a))));
	}
	return 0;
}


Measured memory_bytes: 3244