#include <bits/stdc++.h>
using namespace std;
double EPS = 0.00000001;
int sign(double x){
	if (x > EPS){
		return 1;
	} else if (x < -EPS){
		return -1;
	} else {
		return 0;
	}
}
bool equals(double x, double y){
	return abs(x - y) < EPS;
}
struct point{
	double x;
	double y;
	point(){
		x = 0;
		y = 0;
	}
	point(double X, double Y){
		x = X;
		y = Y;
	}
	point operator +(){
		return point(x, y);
	}
	point operator -(){
		return point(-x, -y);
	}
	point operator +(point P){
		return point(x + P.x, y + P.y);
	}
	point operator -(point P){
		return point(x - P.x, y - P.y);
	}
	point& operator +=(point P){
		x += P.x;
		y += P.y;
		return *this;
	}
	point& operator -=(point P){
		x -= P.x;
		y -= P.y;
		return *this;
	}
	point operator *(double k){
		return point(x * k, y * k);
	}
	point operator /(double k){
		return point(x / k, y / k);
	}
	point& operator *=(double k){
		x *= k;
		y *= k;
		return *this;
	}
	point& operator /=(double k){
		x /= k;
		y /= k;
		return *this;
	}
	bool operator ==(point P){
		return equals(x, P.x) && equals(y, P.y);
	}
	bool operator !=(point P){
		return !(*this == P);
	}
	bool operator <(point P){
		return sign(P.x - x) == 1 || equals(x, P.x) && sign(P.y - y) == 1;
	}
	bool operator >(point P){
		return (P < *this);
	}
	point& rotate(double t){
	    double X = x * cos(t) - y * sin(t);
	    double Y = x * sin(t) + y * cos(t);
	    x = X;
	    y = Y;
	    return *this;
	}
	point& rotate(point P, double t){
	    *this -= P;
	    (*this).rotate(t);
	    *this += P;
	    return *this;
	}
	point& rotate90(){
	    swap(x, y);
	    x = -x;
	    return *this;
	}
};
istream& operator >>(istream &is, point &p){
	double x, y;
	is >> x >> y;
	p = point(x, y);
	return is;
}
ostream& operator <<(ostream &os, point p){
	os << p.x << ' ' << p.y;
	return os;
}
double norm(point P){
	return P.x * P.x + P.y * P.y;
}
double abs(point P){
	return sqrt(norm(P)); 
}
double dot(point P, point Q){
	return P.x * Q.x + P.y * Q.y;
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
double dist(point P, point Q){
	return abs(P - Q);
}
int ccw(point P, point Q, point R){
	Q -= P;
	R -= P;
	if (sign(cross(Q, R)) == 1){
		return 1;
	} else if (sign(cross(Q, R)) == -1){
		return -1;
	} else if (sign(dot(Q, R)) == -1){
		return -2;
	} else if (sign(abs(R) - abs(Q)) == 1){
		return 2;
	} else {
		return 0;
	}
}
struct line{
	point A;
	point B;
	line(){
	}
	line(point P){
	  B = P;
	}
	line(point P, point Q){
		A = P;
		B = Q;
	}
	line(double a, double b){
		A = point(0, b);
		B = point(1, a + b);
	}
	line(double a, double b, double c){
		if (sign(b) == 0){
			A = point(-c / a, 0);
			B = point(-c / a, 1);
		} else {
			A = point(0, -c / a);
			B = point(1, -(b + c) / a);
		}
	}
	bool operator == (line L){
		return abs(ccw(A, B, L.A)) != 1 && abs(ccw(A, B, L.B)) != 1;
	}
	bool operator !=(line L){
		return !(*this == L);
	}
	bool operator <(line L){
		return A < L.A || A == L.A && B < L.B;
	}
	bool operator >(line L){
		return (L < *this);
	}
};
using ray = line;
using segment = line;
istream& operator >>(istream &is, line &L){
	point A, B;
	is >> A >> B;
	L = line(A, B);
	return is;
}
ostream& operator <<(ostream &os, line L){
	os << L.A << ' ' << L.B;
	return os;
}
point vec(line L){
	return L.B - L.A;
}
bool is_orthogonal(line a, line b){
	return sign(dot(vec(a), vec(b))) == 0;
}
bool is_parallel(line a, line b){
  return sign(cross(vec(a), vec(b))) == 0;
}
bool is_on_line(point P, line L){
	return abs(ccw(L.A, L.B, P)) != 1;
}
bool is_on_ray(point P, ray L){
  int x = ccw(L.A, L.B, P);
  return x == 0 || x == 2;
}
bool is_on_segment(point P, segment L){
	return ccw(L.A, L.B, P) == 0;
}
bool is_intersecting_line(line a, line b){
	return !is_parallel(a, b);
}
pair<bool, point> line_intersection(line L1, line L2){
	if (L1 == L2){
		return make_pair(true, L2.A);
	} else if (is_parallel(L1, L2)){
		return make_pair(false, point());
	} else {
	  point P = L1.A + vec(L1) * cross(vec(L2), L2.A - L1.A) / cross(vec(L2), vec(L1));
		return make_pair(true, P);
	}
}
pair<bool, point> line_segment_intersection(line L, segment S){
	auto P = line_intersection(L, S);
	if (P.first && is_on_segment(P.second, S)){
		return make_pair(true, P.second);
	} else {
		return make_pair(false, point());
	}
}
pair<bool, point> segment_intersection(segment S1, segment S2){
	if (S1 == S2){
		if (is_on_segment(S2.A, S1)){
			return make_pair(true, S2.A);
		} else if (is_on_segment(S2.B, S1)){
			return make_pair(true, S2.B);
		} else if (is_on_segment(S1.A, S2)){
			return make_pair(true, S1.A);
		} else {
			return make_pair(false, point());
		}
	}
	pair<bool, point> P = line_intersection(S1, S2);
	if (!P.first){
		return P;
	} else if (is_on_segment(P.second, S1) && is_on_segment(P.second, S2)){
		return P;
	} else {
		return make_pair(false, point());
	}
}
double angle(point A, point B, point C){
	A -= B;
	C -= B;
	return acos(dot(A, C) / (abs(A) * abs(C)));
}
int angle_type(point A, point B, point C){
	return sign(dot(A - B, C - B));
}
double point_line_distance(point P, line L){
	return abs(cross(P - L.A, vec(L))) / abs(vec(L));
}
double point_segment_distance(point P, segment S){
	if (angle_type(P, S.A, S.B) == -1){
		return dist(P, S.A);
	} else if (angle_type(P, S.B, S.A) == -1){
		return dist(P, S.B);
	} else {
		return point_line_distance(P, S);
	}
}
double line_segment_distance(line L, segment S){
	if (line_segment_intersection(L, S).first){
		return 0;
	} else {
		return min(point_line_distance(S.A, L), point_line_distance(S.B, L));
	}
}
double segment_distance(segment S1, segment S2){
	if (segment_intersection(S1, S2).first){
		return 0;
	} else {
		double ans1 = min(point_segment_distance(S1.A, S2), point_segment_distance(S1.B, S2));
		double ans2 = min(point_segment_distance(S2.A, S1), point_segment_distance(S2.B, S1));
		return min(ans1, ans2);
	}
}
int main(){
  cout << fixed << setprecision(20);
  int q;
  cin >> q;
  for (int i = 0; i < q; i++){
    segment s1, s2;
    cin >> s1 >> s2;
    cout << segment_distance(s1, s2) << endl;
  }
}


Measured memory_bytes: 3292