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

const double eps = 1e-10;
bool dless(double d1, double d2) { return d1 < d2 + eps; }
bool dcmp(double d, double d2 = 0) { return abs(d - d2) < eps; }
double sgn(double d) {
  if (dcmp(d))
    return 0;
  if (d > 0)
    return 1;
  return -1;
}

struct vec {
  double x, y;
  vec(double x, double y) : x(x), y(y) {}
  vec() : x(0), y(0) {}
  const bool operator==(const vec &v) const {
    return dcmp(x, v.x) && dcmp(y, v.y);
  }
  const bool operator!=(const vec &v) const { return !(*this == v); }
  const vec operator+(const vec &v) const { return vec(x + v.x, y + v.y); }
  const vec operator-() const { return vec(-x, -y); }
  const vec operator-(const vec &v) const { return *this + (-v); }
  const vec operator*(const double d) const { return vec(x * d, y * d); }
  const vec operator/(const double d) const { return *this * (1 / d); }
  const vec unit() const { return *this / len(); };
  const double len() const { return sqrt(x * x + y * y); }
  const double dot(const vec &v) const { return x * v.x + y * v.y; }
  const double cross(const vec &v) const { return x * v.y - y * v.x; }
  const bool parallel(const vec &v) const { return dcmp(cross(v)); }
  const bool perpendicular(const vec &v) const { return dcmp(dot(v)); }
};

typedef vec point;

template <class T> struct optional {
  bool has;
  T val;
  optional() : has(false) {}
  optional(T t) : has(true), val(t) {}
};

struct line {
  double a, b, c;
  line(point p1, point p2) {
    a = p1.y - p2.y;
    b = p2.x - p1.x;
    c = (p1.x - p2.x) * p1.y + (p2.y - p1.y) * p1.x;
    double m1 = a * p1.x + b * p1.y + c;
    double m2 = a * p2.x + b * p2.y + c;
  }
  bool parallel(line l) { return dcmp(a * l.b, b * l.a); }
  optional<point> intersect(line l) {
    if (parallel(l))
      return optional<point>();
    return point(-(c * l.b - b * l.c) / (a * l.b - b * l.a),
                 (c * l.a - a * l.c) / (a * l.b - b * l.a));
  }
  bool contains(point p) { return dcmp(a * p.x + b * p.y + c); }
  point project(point p) {
    double t = -(a * p.x + b * p.y + c) / (a * a + b * b);
    return point(p.x + a * t, p.y + b * t);
  }
};

struct segment {
  point p1, p2;
  segment(point p1, point p2) : p1(p1), p2(p2) {}
  line sline() { return line(p1, p2); }
  bool contains(point p) {
    double x1 = min(p1.x, p2.x), x2 = max(p1.x, p2.x);
    double y1 = min(p1.y, p2.y), y2 = max(p1.y, p2.y);
    bool ok = sline().contains(p) && (dless(x1, p.x) && dless(p.x, x2)) &&
              (dless(y1, p.y) && dless(p.y, y2));
    return ok;
  }
  bool intersect(segment s) {
    vec v0 = p2 - p1;
    vec v1 = s.p2 - s.p1;
    if (v0.parallel(v1)) {
      return (contains(s.p1) || contains(s.p2)) ||
             (s.contains(p1) || s.contains(p2));
    }
    point a = p1, b = p2, c = s.p1, d = s.p2;
    return sgn((a - b).cross(b - c)) != sgn((a - b).cross(b - d)) &&
           sgn((c - d).cross(d - a)) != sgn((c - d).cross(d - b));
  }
  double distance(point p) {
    point p0 = sline().project(p);
    if (contains(p0)) {
      return (p0 - p).len();
    } else {
      return min((p1 - p).len(), (p2 - p).len());
    }
  }
  double distance(segment s) {
    if (intersect(s))
      return 0.0;
    return min(min(distance(s.p1), distance(s.p2)),
               min(s.distance(p1), s.distance(p2)));
  }
};

int main() {
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    point p0, p1, p2, p3;
    cin >> p0.x >> p0.y >> p1.x >> p1.y >> p2.x >> p2.y >> p3.x >> p3.y;
    segment l0(p0, p1);
    segment l1(p2, p3);
    double d = l0.distance(l1);
    printf("%.10lf\n", d);
  }
}


Measured memory_bytes: 3296