#include <iostream>
#include <cstdio>
#include <cmath>
#include <complex>
#include <vector>
#include <algorithm>
using namespace std;
const double EPS = 1e-10;
bool EQ(double a, double b){return fabs(a-b) < EPS;}
typedef complex<double> Point;
#define X real()
#define Y imag()
namespace std {
  bool operator == (const Point &a, const Point &b) {
    return EQ(a.X, b.X) && EQ(a.Y, b.Y);
  }
  bool operator < (const Point &a, const Point &b) {
    return a.X != b.X ? a.X < b.X : a.Y < b.Y;
  }
}
struct Segment {
  Point p1, p2;
  Segment(){};
  Segment(Point p1, Point p2) : p1(p1), p2(p2) {};
};
typedef Segment Line;
typedef vector<Point> Polygon;
double dot(Point a, Point b){return real(conj(a) * b);}
double cross(Point a, Point b){return imag(conj(a) * b);}
Point project(Segment s, Point p) {
  double r = dot(p - s.p1, s.p2 - s.p1) / norm(s.p2 - s.p1);
  return s.p1 + (s.p2 - s.p1) * r;
}
Point reflect(Segment s, Point p) {
  return p + (project(s, p) - p) * 2.0;
}
bool isOrthogonal(Line l1, Line l2) {
  return EQ(dot(l1.p1 - l1.p2, l2.p1 - l2.p2), 0.0);
}
bool isParallel(Line l1, Line l2) {
  return EQ(cross(l1.p1 - l1.p2, l2.p1 - l2.p2), 0.0);
}
bool intersectLP(Line l, Point p) {
  return EQ(cross(l.p2 - p, l.p1 - p), 0.0);
}
bool intersectSP(Segment s, Point p) {
  return EQ(abs(s.p1 - p) + abs(p - s.p2), abs(s.p2 - s.p1));
}
const int COUNTER_CLOCKWISE = +1;
const int CLOCKWISE = -1;
const int ONLINE_BACK = +2;
const int ONLINE_FRONT = -2;
const int ON_SEGMENT = 0;
int ccw(Point a, Point b, Point c) {
  Point x = b - a;
  Point y = c - a;
  if(cross(x, y) > EPS) return COUNTER_CLOCKWISE;
  if(cross(x, y) < -EPS) return CLOCKWISE;
  if(dot(x, y) < -EPS) return ONLINE_BACK;
  if(norm(x) < norm(y)) return ONLINE_FRONT;
  return ON_SEGMENT;
}
bool intersectSS(Segment s1, Segment s2) {
  return ccw(s1.p1, s1.p2, s2.p1) * ccw(s1.p1, s1.p2, s2.p2) <= 0 &&
    ccw(s2.p1, s2.p2, s1.p1) * ccw(s2.p1, s2.p2, s1.p2) <= 0;
}
bool intersectLS(Line l, Segment s) {
  return cross(l.p2 - l.p1, s.p1 - l.p1) * cross(l.p2 - l.p1, s.p2 - l.p1) < EPS;
}
Point getCrossPointSS(Segment s1, Segment s2) {
  Point b = s2.p2 - s2.p1;
  double d1 = abs(cross(b, s1.p1 - s2.p1));
  double d2 = abs(cross(b, s1.p2 - s2.p1));
  double t = d1 / (d1 + d2);
  return s1.p1 + (s1.p2 - s1.p1) * t;
}
bool intersectLL(Line l1, Line l2) {
  return !isParallel(l1,l2) ||
    EQ(cross(l1.p2 - l1.p1, l2.p1 - l1.p1), 0.0);
}
Point getCrossPointLL(Line l1, Line l2) {
  Point a = l1.p2 - l1.p1;
  Point b = l2.p2 - l2.p1;
  return l1.p1 + a * cross(b, l2.p1 - l1.p1) / cross(b, a);
}
double distancePP(Point a, Point b) {
  return abs(a - b);
}
double distanceLP(Line l, Point p) {
  return distancePP(p, project(l, p));
}
double distanceSP(Segment s, Point p) {
  if(dot(s.p2 - s.p1, p - s.p1) < -EPS) return distancePP(p, s.p1);
  if(dot(s.p1 - s.p2, p - s.p2) < -EPS) return distancePP(p, s.p2);
  return distanceLP(s, p);
}
double distanceSS(Segment s1, Segment s2) {
  if(intersectSS(s1, s2)) return 0.0;
  return min(min(distanceSP(s1, s2.p1), distanceSP(s1, s2.p2)),
	     min(distanceSP(s2, s1.p1), distanceSP(s2, s1.p2)));
}
double distanceLL(Line l1, Line l2) {
  if(intersectLL(l1, l2)) return 0.0;
  else return distanceLP(l1, l2.p1);
}
#define curr(P,i) P[i]
#define next(P,i) P[(i+1)%P.size()]
double area(Polygon P) {
  double a = 0;
  for(int i = 0; i < P.size(); ++i)
    a += cross(curr(P,i), next(P,i));
  return 0.5 * a;
}
#define prev(P,i) P[(i+P.size()-1) % P.size()]
bool isConvex(Polygon P) {
  for(int i = 0; i < P.size(); ++i)
    if(ccw(prev(P,i), curr(P,i), next(P,i)) == CLOCKWISE) return false;
  return true;
}
const int IN = 2;
const int ON = 1;
const int OUT = 0;
int contains(Polygon P, Point p) {
  bool in = false;
  for(int i = 0; i < P.size(); ++i){
    Point a = curr(P,i) - p;

    Point b = next(P,i) - p;
    if(EQ(cross(a,b), 0.0) && dot(a,b) < EPS) return ON;
    if(a.Y > b.Y) swap(a,b);
    if(a.Y < EPS && EPS < b.Y && cross(a,b) > EPS) in = !in;
  }
  return in ? IN: OUT;
}
int main()
{
  int n;
  cin >> n;

  for(int i=0;i<n;i++){
    Segment l1,l2;
    cin >> l1.p1.X >> l1.p1.Y >> l1.p2.X >> l1.p2.Y;
    cin >> l2.p1.X >> l2.p1.Y >> l2.p2.X >> l2.p2.Y;

    printf("%.10f\n",distanceSS(l1,l2));

  }
}

Measured memory_bytes: 1272