#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstdio>
#include<algorithm>
using namespace std;
#define EPS 1e-10
static const int COUNTER_CLOCKWISE = 1;					//逆时针   
static const int CLOCKWISE = -1;							//顺时针
static const int ONLINE_BACK = 2;						//p2 在直线后面
static const int ONLINE_FRONT = -2;						//p2 在直线前面
static const int ON_SEGMENT = 0;						//p2 在直线上
int equals(double a, double b) { return fabs(a - b) < EPS; };
class Point {
public:
	double x, y;
	Point(double x=0, double y=0) :x(x), y(y) { };
	Point operator + (Point& p) {
		return Point(p.x + x, p.y + y);
	}
	Point operator - (Point& p) {
		
		return Point(x - p.x, y - p.y);
	}
	Point operator * (double k) {
		return Point(k*x, k*y);
	}
	double abs() {					//向量长度;
		return sqrt(x * x + y * y);
	}
};
typedef Point Vector;
double dot(Vector a, Vector b) {			//内积 x1*x2 + y1*y2
	return a.x * b.x + a.y * b.y;
}
double cross(Vector a, Vector b) {		  //外积  x1*y2 - x2*y1
	return a.x * b.y - a.y * b.x;
}
struct Segment           //线段
{
	Point a, b;
};
typedef Segment Line;   //线段表示直线；
class Circle {
public:
	Point c;
	double r;
	Circle(Point c = Point(), double x = 0) :c(c), r(x) {};
};
void Parallel_Orthogonal() {				//判断平行或正交
	Point a, b,c,d;
	Point e, f;
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a.x >> a.y >> b.x >> b.y>>c.x>>c.y>>d.x>>d.y;
		e = a - b;
		f = c - d;
		if (equals(dot(e, f), 0)) cout << "1" << endl;
		else if (equals(cross(e, f), 0))cout << "2" << endl;
		else cout <<"0" <<endl;
	}
}
Point Projection(Point& a, Point& b, Point& c) {		//计算投影点
	Point p;
	Vector v1 = b - a;
	Vector v2 = c - a;
	double len = dot(v1, v2);
	double len2 = len/ v1.abs();
	p.x = a.x + len2 / v1.abs() * v1.x;
	p.y = a.y + len2 / v1.abs() * v1.y;
	return p;
}
Point Reflection(Point& a, Point& b, Point& c) {	//算映像
	Point p = Projection(a, b, c);					//算出映射点
	return p*2 - c;									//映射点 是 该点与映像点中点  x + c = 2*p；
}
double getDistancePP(Point a, Point b) {				//两点距离;
	return ((a - b).abs());
}
double getDistancePL(Point a, Line b) {			//求点到直线距离 外积 = |a|.|b|.sin0  在直线上取两点，然后以其中一点为端点求出外
	Vector m = b.a - b.b;						//积的大小 再除以直线上的向量大小 则可以求解。
	Vector m2 = a - b.b;
	return abs(cross(m, m2) / m.abs());
}
int ccw(Point a, Point b, Point c) {			//三个点的位置关系
	Vector p = b - a;
	Vector p2 = c - a;
	if (cross(p, p2) > EPS) return COUNTER_CLOCKWISE;		//逆时针方向向外 结果为正
	if (cross(p, p2) < -EPS) return CLOCKWISE;				//顺时针方向为内 结果为负
	if (dot(p, p2) < -EPS) return ONLINE_BACK;
	if (dot(p, p2) > EPS&& p2.abs() > p.abs()) return ONLINE_FRONT;
	return ON_SEGMENT;
}
double getDistancePS(Point a, Segment b) {		//点到线段的距离;
	Point p1, p2;
	p1 = a - b.a;
	p2 = b.b - b.a;
	if (dot(p1, p2) < 0) {
		return p1.abs();
	}
	p1 = a - b.b;
	p2 = b.a - b.b;
	if (dot(p1, p2) < 0) {
		return p1.abs();
	}
	else {
		return getDistancePL(a, b);
	}
}
bool Intersection(Point a, Point b, Point c, Point d) {    //判断两线段是否相交  如果相交 则两个边的两个个端点会在另一条边的两边或线上
	return (ccw(a, b, c) * ccw(a, b, d) <= 0 && ccw(c, d, a) * ccw(c, d, b) <= 0);
}
Point Cross_Ponit(Point a, Point b, Point c, Point d) {	  //求两线段交点  通过面积求两边高  通过高求两边长度比例
	double s1 = cross(b - a, c - a);
	double s2 = cross(b - a, d - a);
	double d1 =  fabs(s1 * 2 / (b - a).abs());
	double d2 = fabs(s2 * 2 / (b - a).abs());
	Point p;
	p.x = d1 / (d1 + d2) * (d - c).x + c.x;
	p.y = d1 / (d1 + d2) * (d - c).y + c.y;
	return p;
}
double getDistanceSS(Point a, Point b, Point c, Point d) { //如果两者相交则直接返回0 否则是4个点到另一条直线最短的为距离
	if (Intersection(a, b, c, d)) return 0;
	double p1,p2;
	Segment s1,s2;
	s1.a = a;
	s1.b = b;
	s2.a = c;
	s2.b = d;
	p1 = min(getDistancePS(a,s2),getDistancePS(b,s2));
	p2 = min(getDistancePS(c, s1), getDistancePS(d, s1));
	return min(p1, p2);
}
int main(void) {				
	Point a, b, c, d;
	Point p;
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y >> d.x >> d.y;
		p = getDistanceSS(a, b, c, d);
		printf("%.10f\n",p);
	}
}


Measured memory_bytes: 3292