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:
#pragma GCC optimize(3,"Ofast","inline")
#pragma GCC target("avx")
#include <bits/stdc++.h>
using namespace std;
template<class t> inline t read(t &x){
    char c=getchar();bool f=0;x=0;
    while(!isdigit(c)) f|=c=='-',c=getchar();
    while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
    if(f) x=-x;return x;
}
template<class t> inline void write(t x){
    if(x<0) putchar('-'),write(-x);
    else{if(x>9) write(x/10);putchar('0'+x%10);}
}


const double eps=1e-9;
const double pi=acos(-1);

struct point{
	double x,y;
	inline void read(){
		scanf("%lf%lf",&x,&y);
	}
	inline bool operator < (const point &nt) const {
		if(y==nt.y) return x<nt.x;
		return y<nt.y;
	}
	inline point operator + (const point &nt) const {
		return (point){x+nt.x,y+nt.y};
	}
	inline point operator - (const point &nt) const {
		return (point){x-nt.x,y-nt.y};
	}
	inline point operator * (const double &nt) const {
		return (point){x*nt,y*nt};
	}
	inline double length(){
		return sqrt(x*x+y*y);
	}
};

double distance(point x,point y){ //距离 
	return sqrt((y.x-x.x)*(y.x-x.x)+(y.y-x.y)*(y.y-x.y));
}

struct segment{
	point x,y;
	inline void read(){
		x.read();y.read();
	}
	inline double length(){ //线段长度 
		return distance(x,y);
	}
};

struct line{
	point x,y;
	inline void read(){
		x.read();y.read();
	}
};

segment linetoseg(line x){
	return (segment){x.x,x.y};
}

line segtoline(segment x){
	return (line){x.x,x.y};
}

double DJ(point x,point y){ //点积 
	return x.x*y.x+x.y*y.y;
}

double CJ(point x,point y){ //叉积 
	return x.x*y.y-x.y*y.x;
}

point trpoint(segment x){ //将有向线段转成向量点 
	return x.y-x.x;
}

point trpoint(line x){ //将直线转成向量点 
	return x.y-x.x;
}

double prolen(point x,segment a){ //点在有向线段上的投影长度 
	return DJ(trpoint((segment){a.x,x}),trpoint(a))/a.length();
}

point propoint(point x,segment a){ //点在直线(线段)上的投影点 
	return a.x+trpoint(a)*(prolen(x,a)/a.length());
}

point refpoint(point x,segment a){ //点对于直线(线段)的对称点 
	return x+(propoint(x,a)-x)*2;
}

bool orthline(line x,line y){ //两条直线是否垂直 
	return DJ(trpoint(x),trpoint(y))==0;
}

bool paraline(line x,line y){ //两条直线是否平行 
	return CJ(trpoint(x),trpoint(y))==0;
}

bool interseg(segment x,segment y){ //两条线段是否相交 
	return min(x.x.x,x.y.x)<=max(y.x.x,y.y.x)&&min(y.x.x,y.y.x)<=max(x.x.x,x.y.x)&&min(x.x.y,x.y.y)<=max(y.x.y,y.y.y)&&min(y.x.y,y.y.y)<=max(x.x.y,x.y.y)&&CJ(y.x-x.x,y.y-x.x)*CJ(y.x-x.y,y.y-x.y)<=0&&CJ(x.x-y.x,x.y-y.x)*CJ(x.x-y.y,x.y-y.y)<=0;
}

double dispointline(point x,line y){ //点到直线的距离 
	return distance(x,propoint(x,linetoseg(y)));
}

point crossline(line x,line y){ //两条直线的交点 
	double a=dispointline(x.x,y),b=dispointline(x.y,y);
	return x.x+(x.y-x.x)*(a/(a+b));
}

bool onseg(point x,segment y){
	return abs(distance(x,y.x)+distance(x,y.y)-y.length())<=eps;
}

double dispointseg(point x,segment y){
	if(onseg(propoint(x,y),y)) return dispointline(x,segtoline(y));
	return min(distance(x,y.x),distance(x,y.y));
}

void doit(){
	segment a,b;
	a.read();
	b.read();
	double res;
	if(interseg(a,b)) res=0;
	else res=min(min(dispointseg(a.x,b),dispointseg(a.y,b)),min(dispointseg(b.x,a),dispointseg(b.y,a)));
	printf("%.10lf\n",res);
}

signed main(){
	int t;
	read(t);
	while(t--) doit();
}