Problem: For given two segments s1 and s2, print the distance between them.

s1 is formed by end points p0 and p1, and s2 is formed by end points p2 and p3.

Constraints

* 1 ≤ q ≤ 1000
* -10000 ≤ xpi, ypi ≤ 10000
* p0 ≠ p1 and p2 ≠ p3.

Input

The entire input looks like:


q (the number of queries)
1st query
2nd query
...
qth query


Each query consists of integer coordinates of end points of s1 and s2 in the following format:


xp0 yp0 xp1 yp1 xp2 yp2 xp3 yp3


Output

For each query, print the distance. The output values should be in a decimal fraction with an error less than 0.00000001.

Example

Input

3
0 0 1 0 0 1 1 1
0 0 1 0 2 1 1 2
-1 0 1 0 0 1 0 -1


Output

1.0000000000
1.4142135624
0.0000000000

Solution (in CPP):

Solution:
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <bitset>
#include <deque>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
#include <chrono>
#include <random>
#include <tuple>
#include <utility>
#include <fstream>
#include <complex>

const long INF = (1l << 30);
const long LINF = (1l << 60);

//geometric library
//#include <complex>
typedef std::complex<double> Com;

//内積
double dot_product(const Com a, const Com b){
	return (conj(a)*b).real();
}

//外積
double cross_product(const Com a, const Com b){
	return (conj(a)*b).imag();
}

//点と直線の距離
double dist_dot_line(const Com st, const Com en, const Com dt){
    return std::abs(cross_product(dt-st, en-st) / std::abs(en-st));
}

//点と線分の距離
double dist_dot_seg(const Com st, const Com en, const Com dt){
	if(dot_product(en-st, dt-st) <= 0){
		return std::abs(dt-st);
	}else if(dot_product(st-en, dt-en) <= 0){
		return std::abs(dt-en);
	}else{
		return dist_dot_line(st, en, dt);
	}
}

//線分の交差判定
//平行・接触は含まない(接触を含みたいときはdist_seg==0を使う)
bool seg_crossing(const Com st1, const Com en1, const Com st2, const Com en2){
	double cross1 = cross_product(en1-st1, st2-st1) * cross_product(en1-st1, en2-st1);
	double cross2 = cross_product(en2-st2, st1-st2) * cross_product(en2-st2, en1-st2);
	return (cross1 < 0) && (cross2 < 0);
}

//線分と線分の距離
double dist_seg(const Com st1, const Com en1, const Com st2, const Com en2){
	if(seg_crossing(st1, en1, st2, en2)){
		return 0;
	}
	return std::min(std::min(dist_dot_seg(st1, en1, st2), dist_dot_seg(st1, en1, en2)), std::min(dist_dot_seg(st2, en2, st1), dist_dot_seg(st2, en2, en1)));
}

//線分と線分の垂直判定
bool is_vertical(const Com st1, const Com en1, const Com st2, const Com en2){
    if(dot_product(en1-st1, en2-st2) == 0){
        return true;
    }else{
        return false;
    }
}

//平行判定
bool is_parallel(const Com st1, const Com en1, const Com st2, const Com en2){
    if(cross_product(en1-st1, en2-st2) == 0){
        return true;
    }else{
        return false;
    }
}

//直線・線分の交点
Com cross_point(const Com st1, const Com en1, const Com st2, const Com en2){
    /* 線分の時はコメントを外した方が良さそう
    if(dist_seg(st1, en1, st2, en2) > 0 || is_parallel(st1, en1, st2, en2)){
        printf("Error! cross_point invalid input\n");
        std::exit(EXIT_FAILURE);
    }
    //*/
    double den = (real(st1)-real(en1)) * (imag(en2)-imag(st2)) - (real(en2)-real(st2)) * (imag(st1)-imag(en1));
    double mol = (real(en2)-real(en1)) * (imag(en2)-imag(st2)) - (real(en2)-real(st2)) * (imag(en2)-imag(en1));
    double s = mol/den;
    return st1 * s + en1 * (1-s);
}


void solve(){
    double x[4], y[4];
    Com p[4];
    for(int i = 0; i < 4; i++){
        scanf("%lf%lf", &x[i], &y[i]);
        p[i] = Com(x[i], y[i]);
    }
    /*
    if(seg_crossing(p[0], p[1], p[2], p[3])){
        printf("crossing!\n");
    }
    //*/
    printf("%.10lf\n", dist_seg(p[0], p[1], p[2], p[3]));
}

long q;
int main(){
    scanf("%ld", &q);
    for(int i = 0; i < q; i++){
        solve();
    }
}