#include<bits/stdc++.h>
using namespace std;

const double PI = asinl(1) * 2;
struct Point{
  double x,y;
  Point(){}
  Point(double x,double y) :x(x),y(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 * (double k) {return Point(x*k,y*k);}
  Point operator / (double k) {return Point(x/k,y/k);}
  double norm(){return x*x+y*y;}
  double abs(){return sqrt(norm());}

  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) < (1e-10) && fabs(y-p.y) < (1e-10);
  }
};
typedef Point Vector;
typedef vector<Point> Polygon;

struct Segment{
  Point p1,p2;
  Segment(){}
  Segment(Point p1, Point p2):p1(p1),p2(p2){}
};
typedef Segment Line;

struct Circle{
  Point c;
  double r;
  Circle(Point c,double r):c(c),r(r){}
};

double norm(Vector a){
  return a.x*a.x+a.y*a.y;
}
double abs(Vector a){
  return sqrt(norm(a));
}
double dot(Vector a,Vector b){
  return a.x*b.x+a.y*b.y;
}
double cross(Vector a,Vector b){
  return a.x*b.y-a.y*b.x;
}

bool isOrthogonal(Vector a,Vector b){
  return (fabs((dot(a,b))-(0.0)) < (1e-10));
}

bool isOrthogonal(Point a1,Point a2,Point b1,Point b2){
  return isOrthogonal(a1-a2,b1-b2);
}

bool isOrthogonal(Segment s1,Segment s2){
  return (fabs((dot(s1.p2-s1.p1,s2.p2-s2.p1))-(0.0)) < (1e-10));
}

bool isParallel(Vector a,Vector b){
  return (fabs((cross(a,b))-(0.0)) < (1e-10));
}

bool isParallel(Point a1,Point a2,Point b1,Point b2){
  return isParallel(a1-a2,b1-b2);
}

bool isParallel(Segment s1,Segment s2){
  return (fabs((cross(s1.p2-s1.p1,s2.p2-s2.p1))-(0.0)) < (1e-10));
}

Point project(Segment s,Point p){
  Vector base = s.p2 - s.p1;
  double r = dot(p-s.p1,base)/norm(base);
  return s.p1 + base * r;
}

Point reflect(Segment s,Point p){
  return p+ (project(s,p)-p)*2.0;
}
static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

int ccw(Point p0,Point p1,Point p2){
  Vector a = p1-p0;
  Vector b = p2-p0;
  if(cross(a,b)>(1e-10)) return COUNTER_CLOCKWISE;
  if(cross(a,b)<-(1e-10)) return CLOCKWISE;
  if(dot(a,b) < -(1e-10)) return ONLINE_BACK;
  if(a.norm()<b.norm()) return ONLINE_FRONT;

  return ON_SEGMENT;
}

bool intersect(Point p1,Point p2,Point p3,Point p4){
  return (ccw(p1,p2,p3)*ccw(p1,p2,p4) <= 0 &&
          ccw(p3,p4,p1)*ccw(p3,p4,p2) <= 0);
}
bool intersect(Segment s1,Segment s2){
  return intersect(s1.p1,s1.p2,s2.p1,s2.p2);
}

double getDistance(Point a,Point b){
  return abs(a-b);
}

double getDistanceLP(Line l,Point p){
  return abs(cross(l.p2-l.p1,p-l.p1)/abs(l.p2-l.p1));
}

double getDistanceSP(Segment s,Point p){
  if(dot(s.p2-s.p1,p-s.p1)<0.0) return abs(p-s.p1);
  if(dot(s.p1-s.p2,p-s.p2)<0.0) return abs(p-s.p2);
  return getDistanceLP(s,p);
}

double getDistance(Segment s1,Segment s2){
  if(intersect(s1,s2)) return 0.0;
  return min(
      min(getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2)),
      min(getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2))
  );
}

using namespace std;

int main(){
    int q;cin >> q;
    for(int i=0;i<q;i++){
        Segment s1,s2;
        cin >> s1.p1.x >> s1.p1.y >> s1.p2.x >> s1.p2.y;
        cin >> s2.p1.x >> s2.p1.y >> s2.p2.x >> s2.p2.y;
        cout << fixed << setprecision(10);
        cout << getDistance(s1,s2) << endl;
    }
}


Measured memory_bytes: 3292