#include<bits/stdc++.h>

typedef long double     lf;

using namespace std;

const lf EPS = 1e-9;
const lf oo = 1e15;

struct pt {
  lf x, y;
  pt( ) { }
  pt( lf x, lf y ) : x( x ), y ( y ) { }
};

inline lf x( pt P ) { return P.x; }
inline lf y( pt P ) { return P.y; }

istream& operator >> ( istream& in, pt& p ) {
  lf x,y; in >> x >> y;
  p = pt(x,y); return in;
}

ostream& operator << ( ostream& out, const pt& p ) {
  out << double(p.x) << " " << double(p.y);
  return out;
}

pt operator + ( const pt& A, const pt& B ) {
  return pt( x(A)+x(B), y(A)+y(B) );
}

pt operator - ( const pt& A, const pt& B ) {
  return pt( x(A)-x(B), y(A)-y(B) );
}


pt operator * ( const lf& B, const pt& A ) {
  return pt( x(A)*B, y(A)*B );
}

pt operator * ( const pt& A, const lf& B ) {
  return pt( x(A)*B, y(A)*B  );
}

inline lf dot( pt A, pt B ) {
  return x(A)*x(B) + y(A)*y(B);
}

inline lf norm( pt A ) {
  return x(A)*x(A) + y(A)*y(A);
}

inline lf abs( pt A ) {
  return sqrt( norm(A) );
}

inline lf dist ( pt A, pt B ) { return abs( B - A ); }

lf distToLine (pt p, pt A, pt B, pt &c) {
  lf u = dot( p-A , B-A ) / norm( B-A );
  c = A + u*( B-A );
  return dist( p , c );
}

pt refPoint(pt X, pt A, pt B) {
  pt aux; distToLine(X, A, B, aux);
  return X + lf(2.0)*(aux-X);
}

inline bool same ( lf a, lf b ) {
  return a+EPS > b && b+EPS > a;
}

inline lf cross( pt A, pt B ) {
  return x(A)*y(B) - y(A)*x(B);
}

///CHANGE
// 0  for collineal points ( angle = 0 )
// 1  for angle BAX counter clockwise
// -1 for angle BAX clockwise
inline int ccw (pt X, pt A, pt B) {
  lf c = cross( B-A, X-A );
  if( same( c, 0.0 ) ) { return 0; }
  if( c > EPS ) { return 1; }
  return -1;
}

///CHANGE
inline bool segContains ( pt X, pt A, pt B) {
  if ( !same ( 0, cross ( A-X, B-X ) ) ) return 0;
  return ( dot ( A-X, B-X ) < EPS );
}

inline bool parallel( pt A, pt B, pt C, pt D ) {
  return same ( 0, cross( B-A, D-C ) );
}

///NEW
inline bool ortho( pt A, pt B, pt C, pt D ) {
  return same ( 0, dot( B-A, D-C ) );
}

inline bool samePt ( pt A, pt B ) {
  return same ( x(A), x(B) ) && same ( y(A), y(B) );
}

pt linesIntersection ( pt A, pt B, pt C, pt D ) {
  lf x = cross ( C, D-C ) - cross ( A, D-C );
  x /= cross ( B-A, D-C );
  return A + x*(B-A);
}

inline bool collinearSegsIntersects ( pt A, pt B, pt C, pt D ) {
  return segContains(A,C,D) || segContains(B,C,D)
      || segContains(C,A,B) || segContains(D,A,B);
}

bool segmentsIntersect(pt A, pt B, pt C, pt D) {
  if( samePt(A,B) )
    return segContains( A, C, D );
  if( samePt(C,D) )
    return segContains( C, A, B );
  if( parallel(A,B,C,D) )
    return collinearSegsIntersects( A,B,C,D );
  pt aux = linesIntersection(A,B,C,D);
  return segContains(aux,A,B) && segContains(aux,C,D);
}

/// --------------------------------------------

lf distToSegment(pt p, pt A, pt B, pt &c) {
  lf u = dot( p-A , B-A ) / norm( B-A );
  if( u < -EPS ) { c = A; return dist( p , A ); }
  if( (u-1.0) > EPS ) { c = B; return dist( p, B ); }
  return distToLine(p,A,B,c);
}

int n;

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

  cin >> n;
  for( int i = 0; i < n; ++i ) {
    pt A,B,C,D, aux;
    cin >> A >> B >> C >> D;
    lf ans = oo;
    if( segmentsIntersect( A, B, C, D ) ) {
      ans = 0.0;
    }
    ans = min( ans, distToSegment( C, A, B, aux ) );
    ans = min( ans, distToSegment( D, A, B, aux ) );
    ans = min( ans, distToSegment( A, C, D, aux ) );
    ans = min( ans, distToSegment( B, C, D, aux ) );
    cout << double(ans) << '\n';
  }
}

Measured memory_bytes: 3304