#include <iostream>
#include <cmath>
#include <string>
#include <cstdio>
#include <algorithm>
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)
using namespace std;

//点を表す構造体
class Point{
public:
  double x, y;

  Point(double x=0, double y=0){
    this->x = x;
    this->y = y;
  }

  Point operator+(const Point &seg2){
    return Point(x+seg2.x, y+seg2.y);
  }

  Point operator-(const Point &seg2){
    return Point(x-seg2.x, y-seg2.y);
  }

  Point operator*(const double k){
    return Point(x*k, y*k);
  }

  Point &operator=(const Point &p){
    x = p.x;
    y = p.y;
    return *this;
  }

  bool operator < (const Point &p) const{
    return x != p.x? x<p.x : y<p.y;
  }

  bool operator == (const Point &p) const{
    return equals(x, p.x) && equals(y, p.y);
  }
};

//ベクトルを点の別表記でも表せるようにしておく
class Vector : public Point{
public:
  Vector() : Point() {}

  Vector(double x, double y) : Point(x, y) {}

  Vector(Point p) : Point(){
    x = p.x;
    y = p.y;
  }

  double norm(){
    return x*x + y*y;
  }

  double abs(){
    return sqrt(norm());
  }

  static double dot(Vector a, Vector b){
    return a.x*b.x + a.y*b.y;
  }

  static double cross(Vector a, Vector b){
    return a.x*b.y - a.y*b.x;
  }

  static bool isOrthogonal(Vector a, Vector b){
    return equals(dot(a, b), 0.0);
  }

  static bool isParallel(Vector a, Vector b){
    return equals(cross(a, b), 0.0);
  }
};

//線分(ベクトルを用いて)を表す構造体。両端の点が定義されている点に注意
class Segment{
public:
  Point p1, p2;

  Segment(Point p1, Point p2){
    this->p1 = p1;
    this->p2 = p2;
    x = p2.x-p1.x;
    y = p2.y-p1.y;
  }

  static bool isOrthogonal(Segment a, Segment b){
    return equals(dot(a, b), 0.0);
  }

  static bool isParallel(Segment a, Segment b){
    return equals(cross(a, b), 0.0);
  }

private:
  int x, y;
  static double dot(Segment a, Segment b){
    return a.x*b.x + a.y*b.y;
  }

  static double cross(Segment a, Segment b){
    return a.x*b.y - a.y*b.x;
  }
};

typedef Segment Line;

class Circle{
public:
  Point c;
  double r;
  Circle(Point c = Point(), double r = 0.0): c(c), r(r){}
};

string ccw_str(Point p0, Point p1, Point p2){
  //enum res {COUNTER_CLOCKWISE=0, CLOCKWISE, ONLINE_BACK, ONLINE_FRONT, ON_SEGMENT};
  Vector a = p1-p0;
  Vector b = p2-p0;
  if(Vector::cross(a, b) > EPS) return "COUNTER_CLOCKWISE";
  if(Vector::cross(a, b) < -EPS) return "CLOCKWISE";
  if(Vector::dot(a, b) < -EPS) return "ONLINE_BACK";
  if(a.norm() < b.norm()) return "ONLINE_FRONT";
  return "ON_SEGMENT";
}

int ccw_int(Point p0, Point p1, Point p2){
  enum res {COUNTER_CLOCKWISE=-1, CLOCKWISE=1, ONLINE_BACK=2, ONLINE_FRONT=-2, ON_SEGMENT=0};
  Vector a = p1-p0;
  Vector b = p2-p0;
  if(Vector::cross(a, b) > EPS) return COUNTER_CLOCKWISE;
  if(Vector::cross(a, b) < -EPS) return CLOCKWISE;
  if(Vector::dot(a, b) < -EPS) return ONLINE_BACK;
  if(a.norm() < b.norm()) return ONLINE_FRONT;
  return ON_SEGMENT;
}

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

Point reflect(Segment s, Point p){
  Point pro = project(s, p);
  return p + (pro-p)*2.0;
}

bool intersect(Point p1, Point p2, Point p3, Point p4){
  return ccw_int(p1, p2, p3)*ccw_int(p1, p2, p4)<=0 && ccw_int(p3, p4, p1)*ccw_int(p3, p4, p2)<=0;
}

bool intersect(Segment s1, Segment s2){
  return intersect(s1.p1, s1.p2, s2.p1, s2.p2);
}

Point crossPoint(Point p1, Point p2, Point p3, Point p4){
  Vector base = p2-p1;
  double d1 = fabs(Vector::cross(base, p4-p1))/fabs(base.abs());
  double d2 = fabs(Vector::cross(base, p3-p1))/fabs(base.abs());
  double t = d1/(d1+d2);
  Point x = p4 + (p3-p4)*t;
  return x;
}

double getDistance(Point p1, Point p2){
  Vector base=p2-p1;
  return base.abs();
}

double getDistance(Point p, Segment s){
  double dot1, dot2;
  Vector base = s.p2-s.p1;
  dot1 = Vector::dot(base, p-s.p1);
  dot2 = Vector::dot(base*(-1.0), p-s.p2);

  double ans;
  if(dot1<-EPS) ans = getDistance(s.p1, p);
  else if(dot2<-EPS) ans = getDistance(s.p2, p);
  else ans = fabs(Vector::cross(p-s.p1, base))/base.abs();

  return ans;
}

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

int main(){
  int q; cin >> q;

  double q1_x, q1_y, q2_x, q2_y, q3_x, q3_y, q4_x, q4_y;
  for(int i=0; i<q; i++){
    cin >> q1_x >> q1_y >> q2_x >> q2_y >> q3_x >> q3_y >> q4_x >> q4_y;
    Point p1(q1_x, q1_y), p2(q2_x, q2_y), p3(q3_x, q3_y), p4(q4_x, q4_y);
    Segment s1(p1, p2), s2(p3, p4);
    double ans = getDistance(s1, s2);
    printf("%.10lf\n", ans);
  }

  return 0;
}



Measured memory_bytes: 3288