#include <bits/stdc++.h>
#define int long long
#define uint unsigned int
#define pii pair<int, int>
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define FORR(i,a,b) for(int i=(a);i>=(b);--i)
#define REP(i,n) FOR(i,0,n)
#define REPR(i,n) FORR(i,n,0)
#define ALL(c) ((c).begin(),(c).end())
#define PB(a) push_back(a)
#define EMPB(...) emplace_back(__VA_ARGS__)
#define EMP(...) emplace(__VA_ARGS__)
#define MP(a,b) make_pair(a,b)
#define MT(...) make_tuple(__VA_ARGS__)
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
#define MINF(a) memset(a,0x3f,sizeof(a))
#define PW(n) (1LL<<(n))
using namespace std;
template <class T> inline bool CHMIN(T& a, T b) { if(a>b) { a=b; return 1; } return 0; }
template <class T> inline bool CHMAX(T& a, T b) { if(a<b) { a=b; return 1; } return 0; }
template <class T> inline void SORT(T& a) { sort(ALL(a)); }
template <class T> inline void REV(T& a) { reverse(ALL(a)); }
template <class T> inline void UNI(T& a) { SORT(a); a.erase(unique(ALL(a)),a.end()); }
template <class S, class T> ostream& operator<<(ostream& os, const pair<S,T> a) {
  return os << a.first << ' ' << a.second;
}
const int MOD = 1000000007;
// const int INF = 0x3f3f3f3f3f3f3f3f;
// const double EPS = 1e-10;
/* ---------------------------------------------------------------------------------------------------- */

/* 基本要素 */
using D = double; // 座標値の型 doubleかlong double
using P = complex<D>; // Point
using L = pair<P,P>;  // Line
using VP = vector<P>;
const double EPS = 1e-8;  // 許容誤差
const double INF = 1e12;
#define X real()
#define Y imag()
#define LT(n,m) ((n)+EPS<(m)) // n < m ?
#define LE(n,m) ((n)-EPS<(m)) // n <= m ?
#define GT(n,m) LT(m,n) // n > m ?
#define GE(n,m) LE(m,n) // n >= m ?
#define EQ(n,m) (abs((n)-(m))<EPS)
#define NE(n,m) !EQ(n,m)
#define rep(i,n) for (int i=0;i<(n);++i)

namespace std {
  istream& operator >> (istream& is, P& p) {
    int F, S;
    is >> F >> S;
    p = P(F,S);
    return is;
  }
}

// 内積
D dot(P a, P b) {
  return (conj(a)*b).X;
}
// 外積
D cross(P a, P b) {
  return (conj(a)*b).Y;
}
// 点aから見た、点bから点cへの方向
int ccw(P a, P b, P c) {
  b -= a; c -= a;
  if (GT(cross(b,c),0)) return +1;  // counter clockwise
  if (LT(cross(b,c),0)) return -1;  // clockwise
  if (LT(dot(b,c),0)) return +2;  // c--a--b on line
  if (LT(norm(b),norm(c))) return -2; // a--b--c on line or a==b
  return 0;                     // a--c--b on line or a==c or b==c
}

/* 交差判定 直線・線分は縮退してはならない．接する場合は交差するとみなす */
// 直線と点
bool isecLP(P a1, P a2, P b) {
  return NE(abs(ccw(a1,a2,b)),1);
}
// 直線と直線
bool isecLL(P a1, P a2, P b1, P b2) {
  return !isecLP(a2-a1,b2-b1,0) || isecLP(a1,b1,b2);
}
// 直線と線分
bool isecLS(P a1, P a2, P b1, P b2) {
  return LE(cross(a2-a1,b1-a1)*cross(a2-a1,b2-a1),0);
}
// 線分と線分
bool isecSS(P a1, P a2, P b1, P b2) {
  return ccw(a1,a2,b1) * ccw(a1,a2,b2) <= 0 && ccw(b1,b2,a1)*ccw(b1,b2,a2) <= 0;
}
// 線分と点
bool isecSP(P a1, P a2, P b) {
  return !ccw(a1, a2, b);
}

/* 距離 各直線・線分は縮退してはならない */
// 点pの直線aへの射影点を返す
P proj(P a1, P a2, P p) {
  return a1 + dot(a2-a1,p-a1)/norm(a2-a1) * (a2-a1);
}
// 点pの直線aへの反射点を返す
P reflection(P a1, P a2, P p) {
  return 2.0*proj(a1,a2,p)-p;
}
// 直線と点
D distLP(P a1, P a2, P p) {
  return abs(proj(a1,a2,p)-p);
}
// 直線と直線
D distLL(P a1, P a2, P b1, P b2) {
  return isecLL(a1,a2,b1,b2) ? 0 : distLP(a1,a2,b1);
}
// 直線と線分
D distLS(P a1, P a2, P b1, P b2) {
  return isecLS(a1,a2,b1,b2) ? 0 : min(distLP(a1,a2,b1),distLP(a1,a2,b2));
}
// 線分と点
D distSP(P a1, P a2, P p) {
  P r = proj(a1,a2,p);
  if (isecSP(a1,a2,r)) return abs(r-p);
  return min(abs(a1-p),abs(a2-p));
}
// 線分と線分
D distSS(P a1, P a2, P b1, P b2) {
  if (isecSS(a1,a2,b1,b2)) return 0;
  return min(min(distSP(a1,a2,b1),distSP(a1,a2,b2)),min(distSP(b1,b2,a1),distSP(b1,b2,a2)));
}

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(10);

  int q;
  cin >> q;
  REP(i,q) {
    P p0, p1, p2, p3;
    cin >> p0 >> p1 >> p2 >> p3;
    cout << distSS(p0,p1,p2,p3) << endl;
  }

  return 0;
}


Measured memory_bytes: 3356