#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
const double EPS=1e-10;
struct point{
	double x,y;
	point(const point&a):x(a.x),y(a.y){}
	point(const double&x=0,const double&y=0):x(x),y(y){}
	point operator+(const point&p)const{return point(x+p.x,y+p.y);}
	point operator-(const point&p)const{return point(x-p.x,y-p.y);}
	point operator*(const double&k)const{return point(x*k,y*k);}
	point operator/(const double&k)const{return point(x/k,y/k);}
	double norm(){return x*x+y*y;}
	double abs(){return sqrt(norm());}
	void operator=(const point&a){
		x=a.x,y=a.y;
	}
	bool operator<(const point&p)const{
		return x!=p.x?x<p.x:y<p.y;
	}
	bool operator==(const point&p)const{
		return fabs(x-p.x)<EPS&&fabs(y-p.y)<EPS;
	}
	friend double dot(const point&a,const point&b){
		return a.x*b.x+a.y*b.y;
	}
	friend double cross(const point&a,const point&b){
		return a.x*b.y-a.y*b.x;
	}
};
typedef point vector;
struct segment{
	point p1,p2;
	segment(const double&a,const double&b,const double&c,const double&d){
		p1.x=a,p1.y=b,p2.x=c,p2.y=d;
	}
	segment(const point&a, const point&b):p1(a),p2(b){}
	point get_vec()const{return point(p2.x-p1.x,p2.y-p1.y);}
	double abs()const{return get_vec().abs();}
};
bool orthogonal(const vector&a,const vector&b){
	return fabs(dot(a,b))<EPS;
}
bool orthogonal(const point&a,const point&b,const point&c,const point&d){
	return fabs(dot(a-b,c-d))<EPS;
}
bool orthogonal(const segment&a,const segment&b){
	return fabs(dot(a.get_vec(),b.get_vec()))<EPS;
}
bool parallel(const vector&a,const vector&b){
	return fabs(cross(a,b))<EPS;
}
bool parallel(const point&a,const point&b,const point&c,const point&d){
	return fabs(cross(a-b,c-d))<EPS;
}
bool parallel(const segment&a,const segment&b){
	return fabs(cross(a.get_vec(),b.get_vec()))<EPS;
}
point project(const segment&s,const point&p){
	vector base=s.get_vec();
	double r=dot(p-s.p1,base)/base.norm();
	return s.p1+base*r;
}
point reflect(const segment&s,const point&p){
	return p+(project(s,p)-p)*2.0;
}
int ccw(const point&a,const point&b,const point&c){
	vector t1=b-a;
	vector t2=c-a;
	if(cross(t1,t2)>EPS) return 1;
	if(cross(t1,t2)<-EPS) return -1;
	if(dot(t1,t2)<-EPS) return -2;
	if(t1.norm()<t2.norm()) return 2;
	return 0;
}
bool intersect(const point&a,const point&b,const point&c,const point&d){
	return ((ccw(a,b,c)*ccw(a,b,d))<=0&&(ccw(c,d,a)*ccw(c,d,b))<=0);
}
bool intersect(const segment&a,const segment&b){
	return intersect(a.p1,a.p2,b.p1,b.p2);
}
point intersect_point(const segment&s1,const segment&s2){
	double d1=fabs(cross(s2.p1-s1.p1,s1.get_vec()));
	double d2=fabs(cross(s2.p2-s1.p1,s1.get_vec()));
	double t=d1/(d1+d2);
	return s2.p1+s2.get_vec()*t;
}
double dis_pos(const segment&s,const point&p){
	return fabs(cross(p-s.p1,s.p2-s.p1))/s.abs();
}
double dis_ps(const segment&s,const point&p){
	if(dot(p-s.p1,s.p2-s.p1)<0) return (p-s.p1).abs();
	if(dot(p-s.p2,s.p1-s.p2)<0) return (p-s.p2).abs();
	return dis_pos(s,p);
}
double dis_seg(const segment&s1,const segment&s2){
	if(intersect(s1,s2)) return 0.0;
	else{
		return min(min(dis_ps(s1,s2.p1),dis_ps(s1,s2.p2)),min(dis_ps(s2,s1.p1),dis_ps(s2,s1.p2)));
	}
}
int main(){
	double a,b,c,d;
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a>>b>>c>>d;
		segment s1(a,b,c,d);
		cin>>a>>b>>c>>d;
		segment s2(a,b,c,d);
		cout<<setprecision(10)<<fixed<<dis_seg(s1,s2)<<endl;
	}
	return 0;
}



Measured memory_bytes: 3288