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

Difficulty: UNKNOWN_DIFFICULTY

Starter code:

Solutions:
def dot(a, b):
	return a.real * b.real + a.imag * b.imag

def cross(a, b):
	return a.real * b.imag - a.imag * b.real

def ccw(p0, p1, p2):
	a = p1 - p0
	b = p2 - p0
	if cross(a, b) > 0:
		return 1
	elif cross(a, b) < 0:
		return -1
	elif dot(a, b) < 0:
		return 2
	elif abs(a) < abs(b):
		return -2
	else:
		return 0

def get_distanceLP(p0, p1, p2):
	return abs(cross(p1 - p0, p2 - p0) / abs(p1 - p0))

def get_distanceSP(p0, p1, p2):
	if dot(p1 - p0, p2 - p0) < 0:
		return abs(p2 - p0)
	if dot(p0 - p1, p2 - p1) < 0:
		return abs(p2 - p1)
	return get_distanceLP(p0, p1, p2)

def get_distance(a, b, c, d):
	if intersect(a, b, c, d):
		return 0
	return min(min(get_distanceSP(a, b, c), get_distanceSP(a, b, d)), min(get_distanceSP(c, d, a), get_distanceSP(c, d, b)))

def intersect(a, b, c, d):
	return ccw(a, b, c) * ccw(a, b, d) <= 0 and ccw(c, d, a) * ccw(c, d, b) <= 0
n = int(input())
for i in range(n):
	(x0, y0, x1, y1, x2, y2, x3, y3) = map(int, input().split())
	p0 = complex(x0, y0)
	p1 = complex(x1, y1)
	p2 = complex(x2, y2)
	p3 = complex(x3, y3)
	print(get_distance(p0, p1, p2, p3))


import math

def dot(ux, uy, vx, vy):
	return ux * vx + uy * vy

def cross(ux, uy, vx, vy):
	return ux * vy - uy * vx

def dist_to_segment(x, y, ax, ay, bx, by):
	if dot(x - ax, y - ay, bx - ax, by - ay) < 0:
		return math.hypot(x - ax, y - ay)
	if dot(x - bx, y - by, ax - bx, ay - by) < 0:
		return math.hypot(x - bx, y - by)
	c = abs(cross(bx - ax, by - ay, x - ax, y - ay))
	return c / math.hypot(bx - ax, by - ay)
q = int(input())
for _ in range(q):
	(x0, y0, x1, y1, x2, y2, x3, y3) = map(int, input().split())
	c1 = cross(x1 - x0, y1 - y0, x2 - x0, y2 - y0)
	c2 = cross(x1 - x0, y1 - y0, x3 - x0, y3 - y0)
	c3 = cross(x3 - x2, y3 - y2, x0 - x2, y0 - y2)
	c4 = cross(x3 - x2, y3 - y2, x1 - x2, y1 - y2)
	if c1 * c2 < 0 and c3 * c4 < 0:
		d = 0.0
	else:
		d = dist_to_segment(x2, y2, x0, y0, x1, y1)
		d = min(d, dist_to_segment(x3, y3, x0, y0, x1, y1))
		d = min(d, dist_to_segment(x0, y0, x2, y2, x3, y3))
		d = min(d, dist_to_segment(x1, y1, x2, y2, x3, y3))
	print('{:.10f}'.format(d))


import sys
EPS = 1e-09

class Segment(object):
	__slots__ = ('source', 'target')

	def __init__(self, source, target):
		self.source = complex(source)
		self.target = complex(target)

def cross(a, b):
	return a.real * b.imag - a.imag * b.real

def dot(a, b):
	return a.real * b.real + a.imag * b.imag

def get_distance_lp(l, p):
	return abs(cross(l.target - l.source, p - l.source) / abs(l.target - l.source))

def get_distance_sp(s, p):
	if dot(s.target - s.source, p - s.source) < 0:
		return abs(p - s.source)
	elif dot(s.source - s.target, p - s.target) < 0:
		return abs(p - s.target)
	else:
		return get_distance_lp(s, p)

def check_ccw(p0, p1, p2):
	(a, b) = (p1 - p0, p2 - p0)
	if cross(a, b) > EPS:
		flag = 1
	elif cross(a, b) < -1 * EPS:
		flag = -1
	elif dot(a, b) < -1 * EPS:
		flag = 2
	elif abs(a) < abs(b):
		flag = -2
	else:
		flag = 0
	return flag

def check_intersection(p0, p1, p2, p3):
	intersected = check_ccw(p0, p1, p2) * check_ccw(p0, p1, p3) <= 0 and check_ccw(p2, p3, p0) * check_ccw(p2, p3, p1) <= 0
	return intersected

def calc_distance(_lines):
	for line in _lines:
		line_axis = tuple(map(int, line))
		(p0, p1, p2, p3) = (x + y * 1j for (x, y) in zip(line_axis[::2], line_axis[1::2]))
		(s1, s2) = (Segment(p0, p1), Segment(p2, p3))
		intersected = check_intersection(s1.source, s1.target, s2.source, s2.target)
		if intersected:
			distance = 0
		else:
			distance = min(min(get_distance_sp(s1, s2.source), get_distance_sp(s1, s2.target)), min(get_distance_sp(s2, s1.source), get_distance_sp(s2, s1.target)))
		print('{ans:.10f}'.format(ans=distance))
	return None
_input = sys.stdin.readlines()
questions = int(_input[0])
lines = map(lambda x: x.split(), _input[1:])
calc_distance(lines)


import math

class Point:

	def __init__(self, x, y):
		self.x = x
		self.y = y

	def __add__(self, other):
		return Point(self.x + other.x, self.y + other.y)

	def __sub__(self, other):
		return Point(self.x - other.x, self.y - other.y)

	def __mul__(self, other):
		return Point(self.x * other, self.y * other)

	def __floordiv__(self, other):
		return Point(self.x / other, self.y / other)

	def __repr__(self):
		return str(self.x) + ' ' + str(self.y)

class Vector(Point):
	pass

class Line:

	def __init__(self, p1, p2):
		self.p1 = p1
		self.p2 = p2

class Segment(Line):
	pass

def points_to_vector(p1, p2):
	x = p1.x - p2.x
	y = p1.y - p2.y
	return Vector(x, y)

def vector(p):
	return Vector(p.x, p.y)

def dot(v1, v2):
	return v1.x * v2.x + v1.y * v2.y

def cross(v1, v2):
	return v1.x * v2.y - v1.y * v2.x

def norm(v):
	return v.x ** 2 + v.y ** 2

def distance(v):
	return math.sqrt(norm(v))

def project(s, p):
	base = points_to_vector(s.p1, s.p2)
	hypo = points_to_vector(p, s.p1)
	r = dot(hypo, base) / norm(base)
	return s.p1 + base * r

def reflect(s, p):
	return p + (project(s, p) - p) * 2

def get_distance(s1, s2):
	if intersect_s(s1, s2):
		return 0
	d1 = get_distance_sp(s1, s2.p1)
	d2 = get_distance_sp(s1, s2.p2)
	d3 = get_distance_sp(s2, s1.p1)
	d4 = get_distance_sp(s2, s1.p2)
	return min(d1, min(d2, min(d3, d4)))

def get_distance_pp(p1, p2):
	return distance(p1 - p2)

def get_distance_lp(l, p):
	return abs(cross(l.p2 - l.p1, p - l.p1) / distance(l.p2 - l.p1))

def get_distance_sp(s, p):
	if dot(s.p2 - s.p1, p - s.p1) < 0:
		return distance(p - s.p1)
	elif dot(s.p1 - s.p2, p - s.p2) < 0:
		return distance(p - s.p2)
	else:
		return get_distance_lp(s, p)

def ccw(p0, p1, p2):
	EPS = 1e-10
	COUNTER_CLOCKWISE = 1
	CLOCKWISE = -1
	ONLINE_BACK = 2
	ONLINE_FRONT = -2
	ON_SEGMENT = 0
	v1 = p1 - p0
	v2 = p2 - p0
	if cross(v1, v2) > EPS:
		return COUNTER_CLOCKWISE
	elif cross(v1, v2) < -EPS:
		return CLOCKWISE
	elif dot(v1, v2) < -EPS:
		return ONLINE_BACK
	elif norm(v1) < norm(v2):
		return ONLINE_FRONT
	else:
		return ON_SEGMENT

def intersect_p(p1, p2, p3, p4):
	return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0

def intersect_s(s1, s2):
	return intersect_p(s1.p1, s1.p2, s2.p1, s2.p2)
import sys
q = int(input())
for i in range(q):
	temp = list(map(int, input().split()))
	points = []
	for j in range(0, 8, 2):
		points.append(Point(temp[j], temp[j + 1]))
	s1 = Segment(points[0], points[1])
	s2 = Segment(points[2], points[3])
	print(get_distance(s1, s2))


import math
from typing import Union

class Point(object):
	__slots__ = ['x', 'y']

	def __init__(self, x, y):
		self.x = x
		self.y = y

	def __add__(self, other):
		return Point(self.x + other.x, self.y + other.y)

	def __sub__(self, other):
		return Point(self.x - other.x, self.y - other.y)

	def __mul__(self, other: Union[int, float]):
		return Point(self.x * other, self.y * other)

	def norm(self):
		return pow(self.x, 2) + pow(self.y, 2)

	def abs(self):
		return math.sqrt(self.norm())

	def __repr__(self):
		return f'({self.x},{self.y})'

class Vector(Point):
	__slots__ = ['x', 'y', 'pt1', 'pt2']

	def __init__(self, pt1: Point, pt2: Point):
		super().__init__(pt2.x - pt1.x, pt2.y - pt1.y)
		self.pt1 = pt1
		self.pt2 = pt2

	def dot(self, other):
		return self.x * other.x + self.y * other.y

	def cross(self, other):
		return self.x * other.y - self.y * other.x

	def __repr__(self):
		return f'{self.pt1},{self.pt2}'

class Segment(Vector):
	__slots__ = ['x', 'y', 'pt1', 'pt2']

	def __init__(self, pt1: Point, pt2: Point):
		super().__init__(pt1, pt2)

	def projection(self, pt: Point) -> Point:
		t = self.dot(Vector(self.pt1, pt)) / self.norm()
		return self.pt1 + self * t

	def reflection(self, pt: Point) -> Point:
		return self.projection(pt) * 2 - pt

	def is_intersected_with(self, other) -> bool:
		if self.point_geometry(other.pt1) * self.point_geometry(other.pt2) <= 0 and other.point_geometry(self.pt1) * other.point_geometry(self.pt2) <= 0:
			return True
		else:
			return False

	def point_geometry(self, pt: Point) -> int:
		vec_pt1_to_pt = Vector(self.pt1, pt)
		cross = self.cross(vec_pt1_to_pt)
		if cross > 0:
			return -1
		elif cross < 0:
			return 1
		else:
			dot = self.dot(vec_pt1_to_pt)
			if dot < 0:
				return -2
			elif self.abs() < vec_pt1_to_pt.abs():
				return 2
			else:
				return 0

	def cross_point(self, other) -> Point:
		d1 = abs(self.cross(Vector(self.pt1, other.pt1)))
		d2 = abs(self.cross(Vector(self.pt1, other.pt2)))
		t = d1 / (d1 + d2)
		return other.pt1 + other * t

	def distance_to_point(self, pt: Point) -> Union[int, float]:
		vec_pt1_to_pt = Vector(self.pt1, pt)
		if self.dot(vec_pt1_to_pt) <= 0:
			return vec_pt1_to_pt.abs()
		vec_pt2_to_pt = Vector(self.pt2, pt)
		if Vector.dot(self * -1, vec_pt2_to_pt) <= 0:
			return vec_pt2_to_pt.abs()
		return (self.projection(pt) - pt).abs()

	def segment_distance(self, other) -> Union[int, float]:
		if self.is_intersected_with(other):
			return 0.0
		else:
			return min(self.distance_to_point(other.pt1), self.distance_to_point(other.pt2), other.distance_to_point(self.pt1), other.distance_to_point(self.pt2))

	def __repr__(self):
		return f'{self.pt1},{self.pt2}'

def main():
	num_query = int(input())
	for i in range(num_query):
		(p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y) = map(int, input().split())
		seg_1 = Segment(Point(p0_x, p0_y), Point(p1_x, p1_y))
		seg_2 = Segment(Point(p2_x, p2_y), Point(p3_x, p3_y))
		print(f'{seg_1.segment_distance(seg_2):.10f}')
	return
main()


from typing import List, Tuple
from math import sqrt
EPS = 1e-10

def float_equal(x: float, y: float) -> bool:
	return abs(x - y) < EPS

class Point:

	def __init__(self, x: float=0.0, y: float=0.0) -> None:
		self.x = x
		self.y = y

	def __repr__(self) -> str:
		return 'Point({}, {})'.format(self.x, self.y)

	def __eq__(self, other: object) -> bool:
		if not isinstance(other, Point):
			return NotImplemented
		return float_equal(self.x, other.x) and float_equal(self.y, other.y)

	def __add__(self, other: 'Point') -> 'Point':
		return Point(self.x + other.x, self.y + other.y)

	def __sub__(self, other: 'Point') -> 'Point':
		return Point(self.x - other.x, self.y - other.y)

	def __mul__(self, k: float) -> 'Point':
		return Point(self.x * k, self.y * k)

	def __rmul__(self, k: float) -> 'Point':
		return self * k

	def __truediv__(self, k: float) -> 'Point':
		return Point(self.x / k, self.y / k)

	def __lt__(self, other: 'Point') -> bool:
		return self.y < other.y if abs(self.x - other.x) < EPS else self.x < other.x

	def norm(self):
		return self.x * self.x + self.y * self.y

	def abs(self):
		return sqrt(self.norm())

	def dot(self, other: 'Point') -> float:
		return self.x * other.x + self.y * other.y

	def cross(self, other: 'Point') -> float:
		return self.x * other.y - self.y * other.x

	def is_orthogonal(self, other: 'Point') -> bool:
		return float_equal(self.dot(other), 0.0)

	def is_parallel(self, other: 'Point') -> bool:
		return float_equal(self.cross(other), 0.0)

	def distance(self, other: 'Point') -> float:
		return Segment(self, other).vector().abs()

	def in_side_of(self, seg: 'Segment') -> bool:
		return seg.vector().dot(Segment(seg.p1, self).vector()) >= 0

	def in_width_of(self, seg: 'Segment') -> bool:
		return self.in_side_of(seg) and self.in_side_of(seg.reverse())

	def distance_to_segment(self, seg: 'Segment') -> float:
		if self.in_width_of(seg):
			return self.distance(seg.projection(self))
		else:
			return min(self.distance(seg.p1), self.distance(seg.p2))
Vector = Point

class Segment:

	def __init__(self, p1: Point=None, p2: Point=None) -> None:
		self.p1: Point = Point() if p1 is None else p1
		self.p2: Point = Point() if p2 is None else p2

	def __repr__(self) -> str:
		return 'Segment({}, {})'.format(self.p1, self.p2)

	def __eq__(self, other: object) -> bool:
		if not isinstance(other, Segment):
			return NotImplemented
		return self.p1 == other.p1 and self.p2 == other.p2

	def vector(self) -> Vector:
		return self.p2 - self.p1

	def reverse(self) -> 'Segment':
		return Segment(self.p2, self.p1)

	def is_orthogonal(self, other: 'Segment') -> bool:
		return self.vector().is_orthogonal(other.vector())

	def is_parallel(self, other: 'Segment') -> bool:
		return self.vector().is_parallel(other.vector())

	def projection(self, p: Point) -> Point:
		v = self.vector()
		vp = p - self.p1
		return v.dot(vp) / v.norm() * v + self.p1

	def reflection(self, p: Point) -> Point:
		x = self.projection(p)
		return p + 2 * (x - p)

	def intersect_ratio(self, other: 'Segment') -> Tuple[float, float]:
		a = self.vector()
		b = other.vector()
		c = self.p1 - other.p1
		s = b.cross(c) / a.cross(b)
		t = a.cross(c) / a.cross(b)
		return (s, t)

	def intersects(self, other: 'Segment') -> bool:
		(s, t) = self.intersect_ratio(other)
		return 0 <= s <= 1 and 0 <= t <= 1

	def intersection(self, other: 'Segment') -> Point:
		(s, _) = self.intersect_ratio(other)
		return self.p1 + s * self.vector()

	def distance_with_segment(self, other: 'Segment') -> float:
		if not self.is_parallel(other) and self.intersects(other):
			return 0
		else:
			return min(self.p1.distance_to_segment(other), self.p2.distance_to_segment(other), other.p1.distance_to_segment(self), other.p2.distance_to_segment(self))
Line = Segment

class Circle:

	def __init__(self, c: Point=None, r: float=0.0) -> None:
		self.c: Point = Point() if c is None else c
		self.r: float = r

	def __eq__(self, other: object) -> bool:
		if not isinstance(other, Circle):
			return NotImplemented
		return self.c == other.c and self.r == other.r

	def __repr__(self) -> str:
		return 'Circle({}, {})'.format(self.c, self.r)

def main() -> None:
	n = int(input())
	for _ in range(n):
		(x1, y1, x2, y2, x3, y3, x4, y4) = [int(x) for x in input().split()]
		s1 = Segment(Point(x1, y1), Point(x2, y2))
		s2 = Segment(Point(x3, y3), Point(x4, y4))
		print(s1.distance_with_segment(s2))
main()


import sys
from collections import namedtuple
from itertools import starmap
readline = sys.stdin.readline
EPS = 1e-09

class Segment(namedtuple('Point', ('fi', 'se'))):
	__slots__ = ()

def cross(a, b):
	return a.real * b.imag - a.imag * b.real

def dot(a, b):
	return a.real * b.real + a.imag * b.imag

def norm(base):
	return abs(base) ** 2

def project(s, p2):
	base = s.fi - s.se
	r = dot(p2 - s.fi, base) / norm(base)
	return s.fi + base * r

def reflect(s, p):
	return p + (project(s, p) - p) * 2.0

def ccw(p1, p2, p3):
	a = p2 - p1
	b = p3 - p1
	if cross(a, b) > EPS:
		return 1
	if cross(a, b) < -EPS:
		return -1
	if dot(a, b) < -EPS:
		return 2
	if norm(a) < norm(b):
		return -2
	return 0

def intersect4(p1, p2, p3, p4):
	return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0

def intersect2(s1, s2):
	return intersect4(s1.fi, s1.se, s2.fi, s2.se)

def getDistance(a, b):
	return abs(a - b)

def getDistanceLP(l, p):
	return abs(cross(l.se - l.fi, p - l.fi) / abs(l.se - l.fi))

def getDistanceSP(s, p):
	if dot(s.se - s.fi, p - s.fi) < 0.0:
		return abs(p - s.fi)
	if dot(s.fi - s.se, p - s.se) < 0.0:
		return abs(p - s.se)
	return getDistanceLP(s, p)

def getDistances(s1, s2):
	if intersect2(s1, s2):
		return 0.0
	return min(getDistanceSP(s1, s2.fi), getDistanceSP(s1, s2.se), getDistanceSP(s2, s1.fi), getDistanceSP(s2, s1.se))
n = int(readline())
for _ in [0] * n:
	(p0, p1, p2, p3) = starmap(complex, zip(*[map(int, input().split())] * 2))
	s1 = Segment(p0, p1)
	s2 = Segment(p2, p3)
	print('{0:.10f}'.format(getDistances(s1, s2)))


from collections import defaultdict, deque
import sys, heapq, bisect, math, itertools, string, queue
sys.setrecursionlimit(10 ** 8)
INF = float('inf')
mod = 10 ** 9 + 7
eps = 10 ** (-7)

def inp():
	return int(input())

def inpl():
	return list(map(int, input().split()))

def inpl_str():
	return list(input().split())

def sgn(a):
	if a < -eps:
		return -1
	if a > eps:
		return 1
	return 0

class Point:

	def __init__(self, x, y):
		self.x = x
		self.y = y
		pass

	def tolist(self):
		return [self.x, self.y]

	def __add__(self, p):
		return Point(self.x + p.x, self.y + p.y)

	def __iadd__(self, p):
		return self + p

	def __sub__(self, p):
		return Point(self.x - p.x, self.y - p.y)

	def __isub__(self, p):
		return self - p

	def __truediv__(self, n):
		return Point(self.x / n, self.y / n)

	def __itruediv__(self, n):
		return self / n

	def __mul__(self, n):
		return Point(self.x * n, self.y * n)

	def __imul__(self, n):
		return self * n

	def __lt__(self, other):
		tmp = sgn(self.x - other.x)
		if tmp != 0:
			return tmp < 0
		else:
			return sgn(self.y - other.y) < 0

	def __eq__(self, other):
		return sgn(self.x - other.x) == 0 and sgn(self.y - other.y) == 0

	def abs(self):
		return math.sqrt(self.x ** 2 + self.y ** 2)

	def dot(self, p):
		return self.x * p.x + self.y * p.y

	def det(self, p):
		return self.x * p.y - self.y * p.x

	def arg(self, p):
		return math.atan2(y, x)

def iSP(a, b, c):
	tmp = sgn((b - a).det(c - a))
	if tmp > 0:
		return 1
	elif tmp < 0:
		return -1
	else:
		if sgn((b - a).dot(c - a)) < 0:
			return -2
		if sgn((a - b).dot(c - b)) < 0:
			return 2
		return 0

def isToleranceLine(a, b, c, d):
	if sgn((b - a).det(c - d)) != 0:
		return 1
	elif sgn((b - a).det(c - a)) != 0:
		return 0
	else:
		return -1

def isToleranceSegline(a, b, c, d):
	return sgn(iSP(a, b, c) * iSP(a, b, d)) <= 0 and sgn(iSP(c, d, a) * iSP(c, d, b)) <= 0

def Intersection(a, b, c, d):
	tmp1 = (b - a) * (c - a).det(d - c)
	tmp2 = (b - a).det(d - c)
	return a + tmp1 / tmp2

def DistanceLineToPoint(a, b, c):
	return abs((c - a).det(b - a) / (b - a).abs())

def DistanceSeglineToPoint(a, b, c):
	if sgn((b - a).dot(c - a)) < 0:
		return (c - a).abs()
	if sgn((a - b).dot(c - b)) < 0:
		return (c - b).abs()
	return DistanceLineToPoint(a, b, c)

def Vfoot(a, b, c):
	d = c + Point((b - a).y, -(b - a).x)
	return Intersection(a, b, c, d)

def PolygonArea(Plist):
	Plist = ConvexHull(Plist)
	L = len(Plist)
	S = 0
	for i in range(L):
		tmpS = Plist[i - 1].det(Plist[i]) / 2
		S += tmpS
	return S

def PolygonG(Plist):
	Plist = ConvexHull(Plist)
	L = len(Plist)
	S = 0
	G = Point(0, 0)
	for i in range(L):
		tmpS = Plist[i - 1].det(Plist[i]) / 2
		S += tmpS
		G += (Plist[i - 1] + Plist[i]) / 3 * tmpS
	return G / S

def ConvexHull(Plist):
	Plist.sort()
	L = len(Plist)
	qu = deque([])
	quL = 0
	for p in Plist:
		while quL >= 2 and iSP(qu[quL - 2], qu[quL - 1], p) == 1:
			qu.pop()
			quL -= 1
		qu.append(p)
		quL += 1
	qd = deque([])
	qdL = 0
	for p in Plist:
		while qdL >= 2 and iSP(qd[qdL - 2], qd[qdL - 1], p) == -1:
			qd.pop()
			qdL -= 1
		qd.append(p)
		qdL += 1
	qd.pop()
	qu.popleft()
	hidari = list(qd) + list(reversed(qu))
	return hidari
N = int(input())
for _ in range(N):
	(x0, y0, x1, y1, x2, y2, x3, y3) = inpl()
	p0 = Point(x0, y0)
	p1 = Point(x1, y1)
	p2 = Point(x2, y2)
	p3 = Point(x3, y3)
	if isToleranceSegline(p0, p1, p2, p3):
		print(0)
	else:
		print(min(DistanceSeglineToPoint(p0, p1, p2), DistanceSeglineToPoint(p0, p1, p3), DistanceSeglineToPoint(p2, p3, p0), DistanceSeglineToPoint(p2, p3, p1)))


import sys
from collections import namedtuple
from itertools import starmap
readline = sys.stdin.readline
EPS = 1e-09

class Segment(object):
	__slots__ = ('fi', 'se')

	def __init__(self, fi, se):
		self.fi = fi
		self.se = se

def cross(a, b):
	return a.real * b.imag - a.imag * b.real

def dot(a, b):
	return a.real * b.real + a.imag * b.imag

def norm(base):
	return abs(base) ** 2

def project(s, p2):
	base = s.fi - s.se
	r = dot(p2 - s.fi, base) / norm(base)
	return s.fi + base * r

def reflect(s, p):
	return p + (project(s, p) - p) * 2.0

def ccw(p1, p2, p3):
	a = p2 - p1
	b = p3 - p1
	if cross(a, b) > EPS:
		return 1
	if cross(a, b) < -EPS:
		return -1
	if dot(a, b) < -EPS:
		return 2
	if norm(a) < norm(b):
		return -2
	return 0

def intersect4(p1, p2, p3, p4):
	return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0

def intersect2(s1, s2):
	return intersect4(s1.fi, s1.se, s2.fi, s2.se)

def getDistance(a, b):
	return abs(a - b)

def getDistanceLP(l, p):
	return abs(cross(l.se - l.fi, p - l.fi) / abs(l.se - l.fi))

def getDistanceSP(s, p):
	if dot(s.se - s.fi, p - s.fi) < 0.0:
		return abs(p - s.fi)
	if dot(s.fi - s.se, p - s.se) < 0.0:
		return abs(p - s.se)
	return getDistanceLP(s, p)

def getDistances(s1, s2):
	if intersect2(s1, s2):
		return 0.0
	return min(getDistanceSP(s1, s2.fi), getDistanceSP(s1, s2.se), getDistanceSP(s2, s1.fi), getDistanceSP(s2, s1.se))
n = int(readline())
for _ in [0] * n:
	(p0, p1, p2, p3) = starmap(complex, zip(*[map(int, input().split())] * 2))
	s1 = Segment(p0, p1)
	s2 = Segment(p2, p3)
	print('{0:.10f}'.format(getDistances(s1, s2)))


from math import sqrt

def cross(P0, P1, P2):
	(x0, y0) = P0
	(x1, y1) = P1
	(x2, y2) = P2
	x1 -= x0
	x2 -= x0
	y1 -= y0
	y2 -= y0
	return x1 * y2 - x2 * y1

def dot(P0, P1, P2):
	(x0, y0) = P0
	(x1, y1) = P1
	(x2, y2) = P2
	x1 -= x0
	x2 -= x0
	y1 -= y0
	y2 -= y0
	return x1 * x2 + y1 * y2

def dist2(P0, P1):
	(x0, y0) = P0
	(x1, y1) = P1
	return (x1 - x0) ** 2 + (y1 - y0) ** 2

def collision_ll(S0, S1, T0, T1):
	return cross(S0, S1, T0) * cross(S0, S1, T1) < 0 and cross(T0, T1, S0) * cross(T0, T1, S1) < 0

def dist_lp(S, E, P):
	dd = dist2(S, E)
	if 0 <= dot(S, E, P) <= dd:
		return abs(cross(S, E, P)) / sqrt(dd)
	return sqrt(min(dist2(S, P), dist2(E, P)))

def dist_ll(S0, S1, T0, T1):
	if collision_ll(S0, S1, T0, T1):
		return 0
	return min(dist_lp(S0, S1, T0), dist_lp(S0, S1, T1), dist_lp(T0, T1, S0), dist_lp(T0, T1, S1))
n = int(input())
for i in range(n):
	(x0, y0, x1, y1, X0, Y0, X1, Y1) = map(int, input().split())
	print('%.010f' % dist_ll((x0, y0), (x1, y1), (X0, Y0), (X1, Y1)))


import array
from fractions import Fraction
import math
import os
import sys

def main():
	Q = read_int()
	for _ in range(Q):
		(x0, y0, x1, y1, x2, y2, x3, y3) = read_ints()
		print(solve(Vec(x0, y0), Vec(x1, y1), Vec(x2, y2), Vec(x3, y3)))

def pairwise_min2(a, b, c):
	return min(b.abs2(), c.abs2(), (b - a).abs2(), (c - a).abs2())

def calc3(a, b, c):
	c_ab = a.cross(b)
	c_ac = a.cross(c)
	if c_ab == 0 and c_ac == 0:
		s = Fraction(a.dot(b), a.abs2())
		t = Fraction(a.dot(c), a.abs2())
		if s < 0 and t < 0:
			return (max(s, t) * a).abs2()
		if s > 1 and t > 1:
			return ((min(s, t) - 1) * a).abs2()
		return 0
	cb = c - b
	c_acb = a.cross(cb)
	if c_acb != 0:
		u = Fraction(b.cross(cb), c_acb)
		v = Fraction(b.cross(a), c_acb)
		if 0 <= u <= 1 and 0 <= v <= 1:
			return 0
	d_cba = cb.dot(a)
	if d_cba == 0:
		s = Fraction(b.dot(a), a.abs2())
		if 0 <= s <= 1:
			sa = s * a
			return min((b - sa).abs2(), (c - sa).abs2())
		return pairwise_min2(a, b, c)
	d_ba = b.dot(a)
	d_ca = c.dot(a)
	a2 = a.abs2()
	s = Fraction(d_ba, a2)
	t = Fraction(d_ca, a2)
	p = Fraction(-d_ba, d_cba)
	q = Fraction(a2 - d_ba, d_cba)
	dists = [pairwise_min2(a, b, c)]
	if 0 <= s <= 1:
		dists.append((b - s * a).abs2())
	if 0 <= t <= 1:
		dists.append((c - t * a).abs2())
	if 0 <= p <= 1:
		dists.append((b + p * cb).abs2())
	if 0 <= q <= 1:
		dists.append((b + q * cb - a).abs2())
	return min(dists)

def solve(u, v, w, x):
	return math.sqrt(min(calc3(v - u, w - u, x - u), calc3(x - w, u - w, v - w)))

class Vec(object):

	def __init__(self, x, y):
		self.x = x
		self.y = y
		super().__init__()

	def __add__(self, other):
		return Vec(self.x + other.x, self.y + other.y)

	def __sub__(self, other):
		return Vec(self.x - other.x, self.y - other.y)

	def __mul__(self, scalar):
		return Vec(self.x * scalar, self.y * scalar)

	def __rmul__(self, scalar):
		return Vec(self.x * scalar, self.y * scalar)

	def __truediv__(self, scalar):
		return Vec(self.x / scalar, self.y / scalar)

	def __iadd__(self, other):
		self.x += other.x
		self.y += other.y
		return self

	def __isub__(self, other):
		self.x -= other.x
		self.y -= other.y
		return self

	def __imul__(self, scalar):
		self.x *= scalar
		self.y *= scalar
		return self

	def __idiv__(self, scalar):
		self.x /= scalar
		self.y /= scalar
		return self

	def __neg__(self):
		return Vec(-self.x, -self.y)

	def dot(self, other):
		return self.x * other.x + self.y * other.y

	def cross(self, other):
		return self.x * other.y - self.y * other.x

	def abs2(self):
		return self.x * self.x + self.y * self.y

	def __abs__(self):
		return math.sqrt(float(self.abs2()))

	def __str__(self):
		return '({}, {})'.format(self.x, self.y)
DEBUG = 'DEBUG' in os.environ

def inp():
	return sys.stdin.readline().rstrip()

def read_int():
	return int(inp())

def read_ints():
	return [int(e) for e in inp().split()]

def dprint(*value, sep=' ', end='\n'):
	if DEBUG:
		print(*value, sep=sep, end=end)
main()


import cmath
import os
import sys
if os.getenv('LOCAL'):
	sys.stdin = open('_in.txt', 'r')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
IINF = 10 ** 18
MOD = 10 ** 9 + 7
PI = cmath.pi
TAU = cmath.pi * 2
EPS = 1e-08

class Point:

	def __init__(self, c: complex):
		self.c = c

	@property
	def x(self):
		return self.c.real

	@property
	def y(self):
		return self.c.imag

	@staticmethod
	def from_rect(x: float, y: float):
		return Point(complex(x, y))

	@staticmethod
	def from_polar(r: float, phi: float):
		return Point(cmath.rect(r, phi))

	def __add__(self, p):
		return Point(self.c + p.c)

	def __iadd__(self, p):
		self.c += p.c
		return self

	def __sub__(self, p):
		return Point(self.c - p.c)

	def __isub__(self, p):
		self.c -= p.c
		return self

	def __mul__(self, f: float):
		return Point(self.c * f)

	def __imul__(self, f: float):
		self.c *= f
		return self

	def __truediv__(self, f: float):
		return Point(self.c / f)

	def __itruediv__(self, f: float):
		self.c /= f
		return self

	def __repr__(self):
		return '({}, {})'.format(round(self.x, 10), round(self.y, 10))

	def __neg__(self):
		return Point(-self.c)

	def __eq__(self, p):
		return abs(self.c - p.c) < EPS

	def __abs__(self):
		return abs(self.c)

	def dot(self, p):
		return self.x * p.x + self.y * p.y

	def det(self, p):
		return self.x * p.y - self.y * p.x

	def dist(self, p):
		return abs(self.c - p.c)

	def r(self):
		return abs(self.c)

	def phase(self):
		return cmath.phase(self.c)

	def angle(self, p, q):
		return (cmath.phase(q.c - self.c) - cmath.phase(p.c - self.c)) % TAU

	def area(self, p, q):
		return abs((p - self).det(q - self) / 2)

	def projection_point(self, p, q, allow_outer=False):
		diff_q = q - p
		r = (self - p).dot(diff_q) / abs(diff_q)
		phase = diff_q.phase()
		ret = Point.from_polar(r, phase) + p
		if allow_outer or (p - ret).dot(q - ret) < EPS:
			return ret
		return None

	def reflection_point(self, p, q):
		r = abs(self - p)
		angle = p.angle(q, self)
		angle = (q - p).phase() - angle
		return Point.from_polar(r, angle) + p

	def on_segment(self, p, q, allow_side=True):
		if not allow_side and (self == p or self == q):
			return False
		return abs((p - self).det(q - self)) < EPS and (p - self).dot(q - self) < EPS

class Line:

	def __init__(self, a: float, b: float, c: float):
		self.a = a
		self.b = b
		self.c = c

	@staticmethod
	def from_gradient(grad: float, intercept: float):
		return Line(grad, -1, intercept)

	@staticmethod
	def from_segment(p1, p2):
		a = p2.y - p1.y
		b = p1.x - p2.x
		c = p2.y * (p2.x - p1.x) - p2.x * (p2.y - p1.y)
		return Line(a, b, c)

	@property
	def gradient(self):
		return INF if self.b == 0 else -self.a / self.b

	@property
	def intercept(self):
		return INF if self.b == 0 else -self.c / self.b

	def is_parallel_to(self, l):
		return abs(Point.from_rect(self.a, self.b).det(Point.from_rect(l.a, l.b))) < EPS

	def is_orthogonal_to(self, l):
		return abs(Point.from_rect(self.a, self.b).dot(Point.from_rect(l.a, l.b))) < EPS

	def intersection_point(self, l):
		(a1, b1, c1) = (self.a, self.b, self.c)
		(a2, b2, c2) = (l.a, l.b, l.c)
		det = a1 * b2 - a2 * b1
		if abs(det) < EPS:
			return None
		x = (b1 * c2 - b2 * c1) / det
		y = (a2 * c1 - a1 * c2) / det
		return Point.from_rect(x, y)

class Segment:

	def __init__(self, p1, p2):
		self.p1 = p1
		self.p2 = p2

	def norm(self):
		return abs(self.p1 - self.p2)

	def intersects_with(self, s, allow_side=True):
		l1 = Line.from_segment(self.p1, self.p2)
		l2 = Line.from_segment(s.p1, s.p2)
		if l1.is_parallel_to(l2):
			return s.p1.on_segment(self.p1, self.p2, allow_side) or s.p2.on_segment(self.p1, self.p2, allow_side) or self.p1.on_segment(s.p1, s.p2, allow_side) or self.p2.on_segment(s.p1, s.p2, allow_side)
		else:
			p = l1.intersection_point(l2)
			return p.on_segment(self.p1, self.p2, allow_side) and p.on_segment(s.p1, s.p2, allow_side)

	def closest_point(self, p):
		d = (p - self.p1).dot(self.p2 - self.p1) / self.norm()
		if d < EPS:
			return self.p1
		if -EPS < d - self.norm():
			return self.p2
		return Point.from_polar(d, (self.p2 - self.p1).phase()) + self.p1

	def dist(self, p):
		return abs(p - self.closest_point(p))

	def dist_segment(self, s):
		if self.intersects_with(s):
			return 0.0
		return min(self.dist(s.p1), self.dist(s.p2), s.dist(self.p1), s.dist(self.p2))
Q = int(sys.stdin.buffer.readline())
ROWS = [list(map(int, sys.stdin.buffer.readline().split())) for _ in range(Q)]
for (x0, y0, x1, y1, x2, y2, x3, y3) in ROWS:
	s1 = Segment(Point.from_rect(x0, y0), Point.from_rect(x1, y1))
	s2 = Segment(Point.from_rect(x2, y2), Point.from_rect(x3, y3))
	print(s1.dist_segment(s2))


import math
EPS = 1e-10

def equals(a, b):
	return abs(a - b) < EPS

class Point:

	def __init__(self, x=0, y=0):
		self.x = x
		self.y = y

	def __add__(self, p):
		return Point(self.x + p.x, self.y + p.y)

	def __sub__(self, p):
		return Point(self.x - p.x, self.y - p.y)

	def __mul__(self, a):
		return Point(self.x * a, self.y * a)

	def __rmul__(self, a):
		return self * a

	def __truediv__(self, a):
		return Point(self.x / a, self.y / a)

	def norm(self):
		return self.x * self.x + self.y * self.y

	def abs(self):
		return math.sqrt(self.norm())

	def __lt__(self, p):
		if self.x != p.x:
			return self.x < p.x
		else:
			return self.y < p.y

	def __eq__(self, p):
		return equals(self.x, p.x) and equals(self.y, p.y)

class Segment:

	def __init__(self, p1, p2):
		self.p1 = p1
		self.p2 = p2

def dot(a, b):
	return a.x * b.x + a.y * b.y

def cross(a, b):
	return a.x * b.y - a.y * b.x

def ccw(p0, p1, p2):
	COUNTER_CLOCKWISE = 1
	CLOCKWISE = -1
	ONLINE_BACK = 2
	ONLINE_FRONT = -2
	ON_SEGMENT = 0
	a = p1 - p0
	b = p2 - p0
	if cross(a, b) > EPS:
		return COUNTER_CLOCKWISE
	if cross(a, b) < -EPS:
		return CLOCKWISE
	if dot(a, b) < -EPS:
		return ONLINE_BACK
	if a.norm() < b.norm():
		return ONLINE_FRONT
	return ON_SEGMENT

def intersect(s1, s2):
	p1 = s1.p1
	p2 = s1.p2
	p3 = s2.p1
	p4 = s2.p2
	return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0

def getDistanceLP(l, p):
	v = l.p2 - l.p1
	return abs(cross(v, p - l.p1) / v.abs())

def getDistanceSP(s, p):
	if dot(s.p2 - s.p1, p - s.p1) < 0:
		v = p - s.p1
		return v.abs()
	if dot(s.p1 - s.p2, p - s.p2) < 0:
		v = p - s.p2
		return v.abs()
	return getDistanceLP(s, p)

def getDistance(s1, s2):
	if intersect(s1, s2):
		return 0
	return min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2), getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2))
q = int(input())
ans = []
for i in range(q):
	(x0, y0, x1, y1, x2, y2, x3, y3) = [int(v) for v in input().split()]
	s1 = Segment(Point(x0, y0), Point(x1, y1))
	s2 = Segment(Point(x2, y2), Point(x3, y3))
	ans.append(getDistance(s1, s2))
for v in ans:
	print('{0:.10f}'.format(v))


from functools import singledispatch
import math
EPS = 1e-10
COUNTER_CLOCKWISE = 1
CLOCKWISE = -1
ONLINE_BACK = 2
ONLINE_FRONT = -2
ON_SEGMENT = 0

class Segment:

	def __init__(self, p1, p2):
		self.p1 = p1
		self.p2 = p2

class Point:

	def __init__(self, x, y):
		self.x = x
		self.y = y

	def __add__(self, point):
		return Point(self.x + point.x, self.y + point.y)

	def __sub__(self, point):
		return Point(self.x - point.x, self.y - point.y)

	def __mul__(self, a):
		return Point(a * self.x, a * self.y)

	def __truediv__(self, a):
		return Point(self.x / a, self.y / a)

	def __abs__(self):
		return math.sqrt(self.norm())

	def norm(self):
		return self.x ** 2 + self.y ** 2

	def __eq__(self, point):
		return abs(self.x - point.x) < EPS and abs(self.y - point.y) < EPS

def dot(a, b):
	return a.x * b.x + a.y * b.y

def cross(a, b):
	return a.x * b.y - a.y * b.x

def isOrthogonal(a, b):
	return dot(a, b) == 0

def isParallel(a, b):
	return cross(a, b) == 0

def project(s, p):
	base = s.p2 - s.p1
	r = dot(p - s.p1, base) / base.norm()
	return s.p1 + base * r

def reflect(s, p):
	return p + (project(s, p) - p) * 2

@singledispatch
def get_distance(a, b):
	return abs(a - b)

def get_distance_lp(l, p):
	return abs(cross(l.p2 - l.p1, p - l.p1) / abs(l.p2 - l.p1))

def get_distance_sp(s, p):
	if dot(s.p2 - s.p1, p - s.p1) < 0:
		return abs(p - s.p1)
	if dot(s.p1 - s.p2, p - s.p2) < 0:
		return abs(p - s.p2)
	return get_distance_lp(s, p)

@get_distance.register(Segment)
def _(s1, s2):
	if intersect(s1, s2):
		return 0
	return min([get_distance_sp(s1, s2.p1), get_distance_sp(s1, s2.p2), get_distance_sp(s2, s1.p1), get_distance_sp(s2, s1.p2)])

def ccw(p0, p1, p2):
	a = p1 - p0
	b = p2 - p0
	if cross(a, b) > EPS:
		return COUNTER_CLOCKWISE
	if cross(a, b) < -EPS:
		return CLOCKWISE
	if dot(a, b) < -EPS:
		return ONLINE_BACK
	if a.norm() < b.norm():
		return ONLINE_FRONT
	return ON_SEGMENT

@singledispatch
def intersect(p1, p2, p3, p4):
	return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0

@intersect.register(Segment)
def _(s1, s2):
	return intersect(s1.p1, s1.p2, s2.p1, s2.p2)
from sys import stdin
input = stdin.readline
q = int(input())
for _ in range(q):
	(x0, y0, x1, y1, x2, y2, x3, y3) = map(int, input().split())
	p0 = Point(x0, y0)
	p1 = Point(x1, y1)
	p2 = Point(x2, y2)
	p3 = Point(x3, y3)
	s1 = Segment(p0, p1)
	s2 = Segment(p2, p3)
	print(get_distance(s1, s2))


from math import sqrt
q = int(input())

class Segment:
	pass

def dot(a, b):
	return sum([i * j for (i, j) in zip(a, b)])

def sub(a, b):
	return [a[0] - b[0], a[1] - b[1]]

def cross(a, b):
	return a[0] * b[1] - a[1] * b[0]

def norm(a):
	return sqrt(a[0] ** 2 + a[1] ** 2)

def ccw(a, b, c):
	x = sub(b, a)
	y = sub(c, a)
	if cross(x, y) > 0:
		return 1
	if cross(x, y) < 0:
		return -1
	if dot(x, y) < 0:
		return 2
	if norm(x) < norm(y):
		return -2
	return 0

def intersect(p1, p2, p3, p4):
	return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0

def getDistLP(s, p):
	return abs(cross(sub(s.r, s.l), sub(p, s.l))) / norm(sub(s.r, s.l))

def getDistSP(s, p):
	if dot(sub(s.r, s.l), sub(p, s.l)) < 0:
		return norm(sub(p, s.l))
	if dot(sub(s.l, s.r), sub(p, s.r)) < 0:
		return norm(sub(p, s.r))
	return getDistLP(s, p)

def getDist(s1, s2):
	if intersect(s1.l, s1.r, s2.l, s2.r):
		return 0
	return min(getDistSP(s1, s2.l), getDistSP(s1, s2.r), getDistSP(s2, s1.l), getDistSP(s2, s1.r))
for i in range(q):
	(xp0, yp0, xp1, yp1, xp2, yp2, xp3, yp3) = map(int, input().split())
	s1 = Segment()
	s2 = Segment()
	s1.l = [xp0, yp0]
	s1.r = [xp1, yp1]
	s2.l = [xp2, yp2]
	s2.r = [xp3, yp3]
	print(getDist(s1, s2))


import math

def cross(a, b):
	return a.real * b.imag - a.imag * b.real

def dot(a, b):
	return a.real * b.real + a.imag * b.imag

def norm2(a, b):
	return (b.real - a.real) ** 2 + (b.imag - a.imag) ** 2

def is_intersect(p0, p1, p2, p3):
	ta = cross(p1 - p0, p2 - p0)
	tb = cross(p1 - p0, p3 - p0)
	tc = cross(p3 - p2, p0 - p2)
	td = cross(p3 - p2, p1 - p2)
	if ta * tb < 0 and tc * td < 0:
		return True
	else:
		return False

def distance_option(p0, p1, p2):
	nn = norm2(p0, p1)
	if 0 <= dot(p1 - p0, p2 - p0) <= nn:
		return abs(cross(p1 - p0, p2 - p0)) / math.sqrt(nn)
	else:
		return math.sqrt(min(norm2(p0, p2), norm2(p1, p2)))

def distance(p0, p1, p2, p3):
	if is_intersect(p0, p1, p2, p3):
		return 0
	else:
		return min(distance_option(p0, p1, p2), distance_option(p0, p1, p3), distance_option(p2, p3, p0), distance_option(p2, p3, p1))
q = int(input())
for _ in [0] * q:
	x_y = map(int, input().split())
	(p0, p1, p2, p3) = [x + y * 1j for (x, y) in zip(*[x_y] * 2)]
	print('{:.10f}'.format(distance(p0, p1, p2, p3)))


import sys
from collections import namedtuple
from itertools import starmap
readline = sys.stdin.readline
Segment = namedtuple('Segment', ('fi', 'se'))
EPS = 1e-09

def cross(a, b):
	return a.real * b.imag - a.imag * b.real

def dot(a, b):
	return a.real * b.real + a.imag * b.imag

def norm(base):
	return abs(base) ** 2

def project(s, p2):
	base = s.fi - s.se
	r = dot(p2 - s.fi, base) / norm(base)
	return s.fi + base * r

def reflect(s, p):
	return p + (project(s, p) - p) * 2.0

def ccw(p1, p2, p3):
	a = p2 - p1
	b = p3 - p1
	if cross(a, b) > EPS:
		return 1
	if cross(a, b) < -EPS:
		return -1
	if dot(a, b) < -EPS:
		return 2
	if norm(a) < norm(b):
		return -2
	return 0

def intersect4(p1, p2, p3, p4):
	return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0

def intersect2(s1, s2):
	return intersect4(s1.fi, s1.se, s2.fi, s2.se)

def getDistance(a, b):
	return abs(a - b)

def getDistanceLP(l, p):
	return abs(cross(l.se - l.fi, p - l.fi) / abs(l.se - l.fi))

def getDistanceSP(s, p):
	if dot(s.se - s.fi, p - s.fi) < 0.0:
		return abs(p - s.fi)
	if dot(s.fi - s.se, p - s.se) < 0.0:
		return abs(p - s.se)
	return getDistanceLP(s, p)

def getDistances(s1, s2):
	if intersect2(s1, s2):
		return 0.0
	return min(getDistanceSP(s1, s2.fi), getDistanceSP(s1, s2.se), getDistanceSP(s2, s1.fi), getDistanceSP(s2, s1.se))
n = int(readline())
for _ in [0] * n:
	(p0, p1, p2, p3) = starmap(complex, zip(*[map(int, input().split())] * 2))
	s1 = Segment(p0, p1)
	s2 = Segment(p2, p3)
	print('{0:.10f}'.format(getDistances(s1, s2)))


class Point:

	def __init__(self, x, y):
		self.x = x
		self.y = y

	def __sub__(self, p):
		x_sub = self.x - p.x
		y_sub = self.y - p.y
		return Point(x_sub, y_sub)

class Vector:

	def __init__(self, p):
		self.x = p.x
		self.y = p.y
		self.norm = (p.x ** 2 + p.y ** 2) ** 0.5

def cross(v1, v2):
	return v1.x * v2.y - v1.y * v2.x

def dot(v1, v2):
	return v1.x * v2.x + v1.y * v2.y

def ccw(p0, p1, p2):
	a = Vector(p1 - p0)
	b = Vector(p2 - p0)
	cross_ab = cross(a, b)
	if cross_ab > 0:
		return 1
	elif cross_ab < 0:
		return -1
	elif dot(a, b) < 0:
		return 1
	elif a.norm < b.norm:
		return -1
	else:
		return 0

def intersect(p1, p2, p3, p4):
	if ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0:
		return True
	else:
		return False

def getDistanceSP(sp1, sp2, p):
	a = Vector(sp2 - sp1)
	b = Vector(p - sp1)
	if dot(a, b) < 0:
		return b.norm
	c = Vector(sp1 - sp2)
	d = Vector(p - sp2)
	if dot(c, d) < 0:
		return d.norm
	return abs(cross(a, b) / a.norm)

def getDistance(p1, p2, p3, p4):
	if intersect(p1, p2, p3, p4):
		print('0.00000000')
	else:
		d = min(getDistanceSP(p1, p2, p3), getDistanceSP(p1, p2, p4), getDistanceSP(p3, p4, p1), getDistanceSP(p3, p4, p2))
		print('{0:.10f}'.format(d))
import sys
file_input = sys.stdin
sq = file_input.readline()
for line in file_input:
	(x_p0, y_p0, x_p1, y_p1, x_p2, y_p2, x_p3, y_p3) = map(int, line.split())
	p0 = Point(x_p0, y_p0)
	p1 = Point(x_p1, y_p1)
	p2 = Point(x_p2, y_p2)
	p3 = Point(x_p3, y_p3)
	getDistance(p0, p1, p2, p3)


import math

class Vector2:

	def __init__(self, x, y):
		self.x = x
		self.y = y

	def __add__(self, v):
		return Vector2(self.x + v.x, self.y + v.y)

	def __sub__(self, v):
		return Vector2(self.x - v.x, self.y - v.y)

	def __mul__(self, v):
		return Vector2(self.x * v, self.y * v)

	def __truediv__(self, v):
		return Vector2(self.x / v, self.y / v)

	def __abs__(self):
		return math.sqrt(float(self.x * self.x + self.y * self.y))

	def dot(self, v):
		return self.x * v.x + self.y * v.y

	def cross(self, v):
		return self.x * v.y - self.y * v.x

	def norm(self):
		d = abs(self)
		return Vector2(self.x / d, self.y / d)

def distanceLP(v1, v2, p):
	return abs((v2 - v1).cross(p - v1)) / abs(v2 - v1)

def distanceSP(v1, v2, p):
	if (v2 - v1).dot(p - v1) < 0.0:
		return abs(p - v1)
	if (v1 - v2).dot(p - v2) < 0.0:
		return abs(p - v2)
	return distanceLP(v1, v2, p)

def intersect(p1, p2, p3, p4):
	t1 = (p1.x - p2.x) * (p3.y - p1.y) + (p1.y - p2.y) * (p1.x - p3.x)
	t2 = (p1.x - p2.x) * (p4.y - p1.y) + (p1.y - p2.y) * (p1.x - p4.x)
	t3 = (p3.x - p4.x) * (p1.y - p3.y) + (p3.y - p4.y) * (p3.x - p1.x)
	t4 = (p3.x - p4.x) * (p2.y - p3.y) + (p3.y - p4.y) * (p3.x - p2.x)
	return t1 * t2 < 0.0 and t3 * t4 < 0.0

def distance(a1, a2, b1, b2):
	if intersect(a1, a2, b1, b2):
		return 0.0
	return min([min([distanceSP(a1, a2, b1), distanceSP(a1, a2, b2)]), min([distanceSP(b1, b2, a1), distanceSP(b1, b2, a2)])])
q = int(input())
for i in range(q):
	(x0, y0, x1, y1, x2, y2, x3, y3) = map(int, input().split())
	p0 = Vector2(x0, y0)
	p1 = Vector2(x1, y1)
	p2 = Vector2(x2, y2)
	p3 = Vector2(x3, y3)
	s1 = p1 - p0
	s2 = p3 - p2
	print(f'{distance(p0, p1, p2, p3):.10f}')


from math import pi, cos, sin, atan2
EPS = 10 ** (-9)

def eq(value1, value2):
	return abs(value1 - value2) <= EPS

class Point:

	def __init__(self, x, y):
		self.x = x
		self.y = y
		self.arg = atan2(y, x)

	def __str__(self):
		return '{0:.8f} {1:.8f}'.format(self.x, self.y)

	def __add__(self, other):
		return Point(self.x + other.x, self.y + other.y)

	def __sub__(self, other):
		return Point(self.x - other.x, self.y - other.y)

	def __mul__(self, scal):
		return Point(self.x * scal, self.y * scal)

	def __truediv__(self, scal):
		return Point(self.x / scal, self.y / scal)

	def __eq__(self, other):
		return eq(self.x, other.x) and eq(self.y, other.y)

	def __abs__(self):
		return (self.x ** 2 + self.y ** 2) ** 0.5

def Rotation(vec: Point, rad):
	return Point(vec.x * cos(rad) - vec.y * sin(rad), vec.x * sin(rad) + vec.y * cos(rad))

class Circle:

	def __init__(self, p, r):
		self.p = p
		self.r = r

class Line:

	def __init__(self, a, b):
		self.a = a
		self.b = b
		self.arg = (a - b).arg % pi

	def __str__(self):
		return '[({0}, {1}) - ({2}, {3})]'.format(self.a.x, self.a.y, self.b.x, self.b.y)

	def par(self, point):
		return Line(point, point + (self.a - self.b))

	def tan(self, point):
		return Line(point, point + Rotation(self.a - self.b, pi / 2))

class Segment(Line):

	def __init__(self, a, b):
		super().__init__(a, b)

def cross(vec1: Point, vec2: Point):
	return vec1.x * vec2.y - vec1.y * vec2.x

def dot(vec1: Point, vec2: Point):
	return vec1.x * vec2.x + vec1.y * vec2.y

def ccw(a, b, c):
	if cross(b - a, c - a) > EPS:
		return +1
	if cross(b - a, c - a) < -EPS:
		return -1
	if dot(c - a, b - a) < -EPS:
		return +2
	if abs(b - a) < abs(c - a):
		return -2
	return 0

def projection(l, p):
	t = dot(l.b - l.a, p - l.a) / abs(l.a - l.b) ** 2
	return l.a + (l.b - l.a) * t

def reflection(l, p):
	return p + (projection(l, p) - p) * 2

def isPararell(l1, l2):
	return eq(cross(l1.a - l1.b, l2.a - l2.b), 0)

def isVertical(l1, l2):
	return eq(dot(l1.a - l1.b, l2.a - l2.b), 0)

def isIntersect_lp(l, p):
	return abs(ccw(l.a, l.b, p)) != 1

def isIntersect_ll(l1, l2):
	return not isPararell(l1, l2) or isIntersect_lp(l1, l2.a)

def isIntersect_sp(s, p):
	return ccw(s.a, s.b, p) == 0

def isIntersect_ss(s1, s2):
	return ccw(s1.a, s1.b, s2.a) * ccw(s1.a, s1.b, s2.b) <= 0 and ccw(s2.a, s2.b, s1.a) * ccw(s2.a, s2.b, s1.b) <= 0

def isIntersect_ls(l, s):
	return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS

def isIntersect_cp(c, p):
	return abs(abs(c.p - p) - c.r) < EPS

def isIntersect_cl(c, l):
	return distance_lp(l, c.p) <= c.r + EPS

def isIntersect_cs(c, s):
	pass

def isIntersect_cc(c1, c2):
	pass

def distance_pp(p1, p2):
	return abs(p1 - p2)

def distance_lp(l, p):
	return abs(projection(l, p) - p)

def distance_ll(l1, l2):
	return 0 if isIntersect_ll(l1, l2) else distance_lp(l1, l2.a)

def distance_sp(s, p):
	r = projection(s, p)
	if isIntersect_sp(s, r):
		return abs(r - p)
	return min(abs(s.a - p), abs(s.b - p))

def distance_ss(s1, s2):
	if isIntersect_ss(s1, s2):
		return 0
	return min([distance_sp(s1, s2.a), distance_sp(s1, s2.b), distance_sp(s2, s1.a), distance_sp(s2, s1.b)])

def distance_ls(l, s):
	if isIntersect_ls(l, s):
		return 0
	return min(distance_lp(l, s.a), distance_lp(l, s.b))

def crosspoint_ll(l1, l2):
	A = cross(l1.b - l1.a, l2.b - l2.a)
	B = cross(l1.b - l1.a, l1.b - l2.a)
	if eq(abs(A), 0) and eq(abs(B), 0):
		return l2.a
	return l2.a + (l2.b - l2.a) * B / A

def crosspoint_ss(s1, s2):
	return crosspoint_ll(s1, s2)

def crosspoint_lc(l, c):
	if eq(distance_lp(l, c.p), c.r):
		return [c.p]
	p = projection(l, c.p)
	e = (l.b - l.a) / abs(l.b - l.a)
	dis = (c.r ** 2 - abs(p - c.p) ** 2) ** 0.5
	return [p + e * dis, p - e * dis]

def crosspoint_sc(s, c):
	pass

def crosspoint_cc(c1, c2):
	d = abs(c1.p - c2.p)
	if not abs(c1.r - c2.r) <= d <= c1.r + c2.r:
		return []
	mid_p = (c2.p * (c1.r ** 2 - c2.r ** 2 + d ** 2) + c1.p * (c2.r ** 2 - c1.r ** 2 + d ** 2)) / (2 * d ** 2)
	tanvec = Rotation(c1.p - c2.p, pi / 2)
	return crosspoint_lc(Line(mid_p, mid_p + tanvec), c1)

def tangent_cp(c, p):
	return crosspoint_cc(c, Circle(p, (abs(p - c.p) ** 2 - c.r ** 2) ** 0.5))
import sys
input = sys.stdin.readline

def verify_1A():
	(p1x, p1y, p2x, p2y) = map(int, input().split())
	l = Line(Point(p1x, p1y), Point(p2x, p2y))
	Q = int(input())
	Query = [list(map(int, input().split())) for _ in range(Q)]
	for (px, py) in Query:
		p = Point(px, py)
		print(projection(l, p))

def verify_1B():
	(p1x, p1y, p2x, p2y) = map(int, input().split())
	l = Line(Point(p1x, p1y), Point(p2x, p2y))
	Q = int(input())
	Query = [list(map(int, input().split())) for _ in range(Q)]
	for (px, py) in Query:
		p = Point(px, py)
		print(reflection(l, p))

def verify_1C():
	(p1x, p1y, p2x, p2y) = map(int, input().split())
	p1 = Point(p1x, p1y)
	p2 = Point(p2x, p2y)
	Q = int(input())
	Query = [list(map(int, input().split())) for _ in range(Q)]
	for (px, py) in Query:
		p = Point(px, py)
		result = ccw(p1, p2, p)
		if result == 1:
			print('COUNTER_CLOCKWISE')
		elif result == -1:
			print('CLOCKWISE')
		elif result == 2:
			print('ONLINE_BACK')
		elif result == -2:
			print('ONLINE_FRONT')
		else:
			print('ON_SEGMENT')

def verify_2A():
	Q = int(input())
	Query = [list(map(int, input().split())) for _ in range(Q)]
	for (p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) in Query:
		l1 = Line(Point(p0x, p0y), Point(p1x, p1y))
		l2 = Line(Point(p2x, p2y), Point(p3x, p3y))
		if isPararell(l1, l2):
			print(2)
		elif isVertical(l1, l2):
			print(1)
		else:
			print(0)

def verify_2B():
	Q = int(input())
	Query = [list(map(int, input().split())) for _ in range(Q)]
	for (p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) in Query:
		s1 = Segment(Point(p0x, p0y), Point(p1x, p1y))
		s2 = Segment(Point(p2x, p2y), Point(p3x, p3y))
		if isIntersect_ss(s1, s2):
			print(1)
		else:
			print(0)

def verify_2C():
	Q = int(input())
	Query = [list(map(int, input().split())) for _ in range(Q)]
	for (p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) in Query:
		s1 = Segment(Point(p0x, p0y), Point(p1x, p1y))
		s2 = Segment(Point(p2x, p2y), Point(p3x, p3y))
		print(crosspoint_ss(s1, s2))

def verify_2D():
	Q = int(input())
	Query = [list(map(int, input().split())) for _ in range(Q)]
	for (p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) in Query:
		s1 = Segment(Point(p0x, p0y), Point(p1x, p1y))
		s2 = Segment(Point(p2x, p2y), Point(p3x, p3y))
		print('{:.8f}'.format(distance_ss(s1, s2)))
verify_2D()


EPS = 10 ** (-9)

def is_equal(a, b):
	return abs(a - b) < EPS

def norm(v, i=2):
	import math
	ret = 0
	n = len(v)
	for j in range(n):
		ret += abs(v[j]) ** i
	return math.pow(ret, 1 / i)

class Vector(list):

	def __add__(self, other):
		n = len(self)
		ret = [0] * n
		for i in range(n):
			ret[i] = super().__getitem__(i) + other.__getitem__(i)
		return self.__class__(ret)

	def __radd__(self, other):
		n = len(self)
		ret = [0] * n
		for i in range(n):
			ret[i] = other.__getitem__(i) + super().__getitem__(i)
		return self.__class__(ret)

	def __iadd__(self, other):
		n = len(self)
		for i in range(n):
			self[i] += other.__getitem__(i)
		return self

	def __sub__(self, others):
		n = len(self)
		ret = [0] * n
		for i in range(n):
			ret[i] = super().__getitem__(i) - others.__getitem__(i)
		return self.__class__(ret)

	def __iadd__(self, other):
		n = len(self)
		for i in range(n):
			self[i] -= other.__getitem__(i)
		return self

	def __rsub__(self, others):
		n = len(self)
		ret = [0] * n
		for i in range(n):
			ret[i] = others.__getitem__(i) - super().__getitem__(i)
		return self.__class__(ret)

	def __mul__(self, other):
		n = len(self)
		if isinstance(other, list):
			ret = 0
			for i in range(n):
				ret += super().__getitem__(i) * other.__getitem__(i)
			return ret
		else:
			ret = [0] * n
			for i in range(n):
				ret[i] = super().__getitem__(i) * other
			return self.__class__(ret)

	def __rmul__(self, other):
		n = len(self)
		if isinstance(other, list):
			ret = 0
			for i in range(n):
				ret += super().__getitem__(i) * other.__getitem__(i)
			return ret
		else:
			ret = [0] * n
			for i in range(n):
				ret[i] = super().__getitem__(i) * other
			return self.__class__(ret)

	def __truediv__(self, other):
		n = len(self)
		ret = [0] * n
		for i in range(n):
			ret[i] = super().__getitem__(i) / other
		return self.__class__(ret)

	def norm(self, i):
		return norm(self, i)

	def __pow__(self, other):
		n = len(self)
		ret = [0] * 3
		x = self[:]
		y = other[:]
		if n == 2:
			x.append(0)
			y.append(0)
		if n == 2 or n == 3:
			for i in range(3):
				(ret[0], ret[1], ret[2]) = (x[1] * y[2] - x[2] * y[1], x[2] * y[0] - x[0] * y[2], x[0] * y[1] - x[1] * y[0])
			ret = Vector(ret)
			if n == 2:
				return ret
			else:
				return ret

class Segment:

	def __init__(self, v1, v2):
		self.v1 = v1
		self.v2 = v2

	def length(self):
		return norm(self.v1 - self.v2)

	def get_unit_vec(self):
		dist = norm(self.v2 - self.v1)
		if dist != 0:
			return (self.v2 - self.v1) / dist
		else:
			return False

	def projection(self, vector):
		unit_vec = self.get_unit_vec()
		t = unit_vec * (vector - self.v1)
		return self.v1 + t * unit_vec

	def is_vertical(self, other):
		return is_equal(0, self.get_unit_vec() * other.get_unit_vec())

	def is_horizontal(self, other):
		return is_equal(0, self.get_unit_vec() ** other.get_unit_vec())

	def reflection(self, vector):
		projection = self.projection(vector)
		v = projection - vector
		return projection + vector

	def include(self, vector):
		proj = self.projection(vector)
		if not is_equal(norm(proj - vector), 0):
			return False
		else:
			n = len(self.v1)
			f = True
			for i in range(n):
				f &= self.v1[i] <= vector[i] <= self.v2[i] or self.v2[i] <= vector[i] <= self.v1[i]
			return f

	def distance(self, other):
		if isinstance(other, Vector):
			proj = self.projection(other)
			if self.include(proj):
				return norm(proj - other)
			else:
				ret = []
				ret.append(norm(self.v1 - other))
				ret.append(norm(self.v2 - other))
				return min(ret)

	def ccw(self, vector):
		direction = self.v2 - self.v1
		v = vector - self.v1
		if self.include(vector):
			return 0
		else:
			cross = direction ** v
			if cross[2] <= 0:
				return 1
			else:
				return -1

	def intersect(self, segment):
		ccw12 = self.ccw(segment.v1)
		ccw13 = self.ccw(segment.v2)
		ccw20 = segment.ccw(self.v1)
		ccw21 = segment.ccw(self.v2)
		if ccw12 * ccw13 * ccw20 * ccw21 == 0:
			return True
		elif ccw12 * ccw13 < 0 and ccw20 * ccw21 < 0:
			return True
		else:
			return False

class Line(Segment):

	def include(self, vector):
		proj = self.projection(vector)
		return is_equal(norm(proj - vector), 0)
q = int(input())
ps = [[[0] for _ in range(4)] for _ in range(q)]
for i in range(q):
	tmp = list(map(int, input().split()))
	for j in range(4):
		ps[i][j] = Vector(tmp[2 * j:2 * (j + 1)])
for i in range(q):
	ans = []
	(p0, p1, p2, p3) = ps[i]
	S1 = Segment(p0, p1)
	S2 = Segment(p2, p3)
	if S1.intersect(S2):
		ans.append(0)
	else:
		ans.append(S1.distance(p2))
		ans.append(S1.distance(p3))
		ans.append(S2.distance(p0))
		ans.append(S2.distance(p1))
	print(min(ans))


from typing import List, Tuple
from math import sqrt
EPS = 1e-10

def float_equal(x: float, y: float) -> bool:
	return abs(x - y) < EPS

class Point:

	def __init__(self, x: float=0.0, y: float=0.0) -> None:
		self.x = x
		self.y = y

	def __repr__(self) -> str:
		return 'Point({}, {})'.format(self.x, self.y)

	def __eq__(self, other: object) -> bool:
		if not isinstance(other, Point):
			return NotImplemented
		return float_equal(self.x, other.x) and float_equal(self.y, other.y)

	def __add__(self, other: 'Point') -> 'Point':
		return Point(self.x + other.x, self.y + other.y)

	def __sub__(self, other: 'Point') -> 'Point':
		return Point(self.x - other.x, self.y - other.y)

	def __mul__(self, k: float) -> 'Point':
		return Point(self.x * k, self.y * k)

	def __rmul__(self, k: float) -> 'Point':
		return self * k

	def __truediv__(self, k: float) -> 'Point':
		return Point(self.x / k, self.y / k)

	def __lt__(self, other: 'Point') -> bool:
		return self.y < other.y if abs(self.x - other.x) < EPS else self.x < other.x

	def norm(self):
		return self.x * self.x + self.y * self.y

	def abs(self):
		return sqrt(self.norm())

	def dot(self, other: 'Point') -> float:
		return self.x * other.x + self.y * other.y

	def cross(self, other: 'Point') -> float:
		return self.x * other.y - self.y * other.x

	def is_orthogonal(self, other: 'Point') -> bool:
		return float_equal(self.dot(other), 0.0)

	def is_parallel(self, other: 'Point') -> bool:
		return float_equal(self.cross(other), 0.0)

	def distance(self, other: 'Point') -> float:
		return (self - other).abs()

	def in_side_of(self, seg: 'Segment') -> bool:
		return seg.vector().dot(Segment(seg.p1, self).vector()) >= 0

	def in_width_of(self, seg: 'Segment') -> bool:
		return self.in_side_of(seg) and self.in_side_of(seg.reverse())

	def distance_to_line(self, seg: 'Segment') -> float:
		return abs((self - seg.p1).cross(seg.vector())) / seg.length()

	def distance_to_segment(self, seg: 'Segment') -> float:
		if not self.in_side_of(seg):
			return self.distance(seg.p1)
		if not self.in_side_of(seg.reverse()):
			return self.distance(seg.p2)
		else:
			return self.distance_to_line(seg)
Vector = Point

class Segment:

	def __init__(self, p1: Point=None, p2: Point=None) -> None:
		self.p1: Point = Point() if p1 is None else p1
		self.p2: Point = Point() if p2 is None else p2

	def __repr__(self) -> str:
		return 'Segment({}, {})'.format(self.p1, self.p2)

	def __eq__(self, other: object) -> bool:
		if not isinstance(other, Segment):
			return NotImplemented
		return self.p1 == other.p1 and self.p2 == other.p2

	def vector(self) -> Vector:
		return self.p2 - self.p1

	def reverse(self) -> 'Segment':
		return Segment(self.p2, self.p1)

	def length(self) -> float:
		return self.p1.distance(self.p2)

	def is_orthogonal(self, other: 'Segment') -> bool:
		return self.vector().is_orthogonal(other.vector())

	def is_parallel(self, other: 'Segment') -> bool:
		return self.vector().is_parallel(other.vector())

	def projection(self, p: Point) -> Point:
		v = self.vector()
		vp = p - self.p1
		return v.dot(vp) / v.norm() * v + self.p1

	def reflection(self, p: Point) -> Point:
		x = self.projection(p)
		return p + 2 * (x - p)

	def intersect_ratio(self, other: 'Segment') -> Tuple[float, float]:
		a = self.vector()
		b = other.vector()
		c = self.p1 - other.p1
		s = b.cross(c) / a.cross(b)
		t = a.cross(c) / a.cross(b)
		return (s, t)

	def intersects(self, other: 'Segment') -> bool:
		(s, t) = self.intersect_ratio(other)
		return 0 <= s <= 1 and 0 <= t <= 1

	def intersection(self, other: 'Segment') -> Point:
		(s, _) = self.intersect_ratio(other)
		return self.p1 + s * self.vector()

	def distance_with_segment(self, other: 'Segment') -> float:
		if not self.is_parallel(other) and self.intersects(other):
			return 0
		else:
			return min(self.p1.distance_to_segment(other), self.p2.distance_to_segment(other), other.p1.distance_to_segment(self), other.p2.distance_to_segment(self))
Line = Segment

class Circle:

	def __init__(self, c: Point=None, r: float=0.0) -> None:
		self.c: Point = Point() if c is None else c
		self.r: float = r

	def __eq__(self, other: object) -> bool:
		if not isinstance(other, Circle):
			return NotImplemented
		return self.c == other.c and self.r == other.r

	def __repr__(self) -> str:
		return 'Circle({}, {})'.format(self.c, self.r)

def main() -> None:
	n = int(input())
	for _ in range(n):
		(x1, y1, x2, y2, x3, y3, x4, y4) = [int(x) for x in input().split()]
		s1 = Segment(Point(x1, y1), Point(x2, y2))
		s2 = Segment(Point(x3, y3), Point(x4, y4))
		print(s1.distance_with_segment(s2))
main()


import sys
from sys import stdin
input = stdin.readline

class Point(object):
	epsilon = 1e-10

	def __init__(self, x=0.0, y=0.0):
		if isinstance(x, tuple):
			self.x = x[0]
			self.y = x[1]
		else:
			self.x = x
			self.y = y

	def __add__(self, other):
		return Point(self.x + other.x, self.y + other.y)

	def __sub__(self, other):
		return Point(self.x - other.x, self.y - other.y)

	def __mul__(self, other):
		return Point(other * self.x, other * self.y)

	def __truediv__(self, other):
		return Point(other / self.x, other / self.y)

	def __lt__(self, other):
		if self.x == other.x:
			return self.y < other.y
		else:
			return self.x < other.x

	def __eq__(self, other):
		from math import fabs
		if fabs(self.x - other.x) < Point.epsilon and fabs(self.y - other.y) < Point.epsilon:
			return True
		else:
			return False

	def norm(self):
		return self.x * self.x + self.y * self.y

	def __abs__(self):
		from math import sqrt
		return sqrt(self.norm())

	def ccw(self, p0, p1):
		a = Vector(p1 - p0)
		b = Vector(self - p0)
		if Vector.cross(a, b) > Point.epsilon:
			return 1
		elif Vector.cross(a, b) < -Point.epsilon:
			return -1
		elif Vector.dot(a, b) < -Point.epsilon:
			return 2
		elif a.norm() < b.norm():
			return -2
		else:
			return 0

	def project(self, s):
		base = Vector(s.p2 - s.p1)
		a = Vector(self - s.p1)
		r = Vector.dot(a, base)
		r /= base.norm()
		return s.p1 + base * r

	def reflect(self, s):
		proj = self.project(s)
		return self + (proj - self) * 2

	def distance(self, s):
		if Vector.dot(s.p2 - s.p1, self - s.p1) < 0.0:
			return abs(self - s.p1)
		if Vector.dot(s.p1 - s.p2, self - s.p2) < 0.0:
			return abs(self - s.p2)
		return abs(Vector.cross(s.p2 - s.p1, self - s.p1) / abs(s.p2 - s.p1))

class Vector(Point):

	def __init__(self, x=0.0, y=0.0):
		if isinstance(x, tuple):
			self.x = x[0]
			self.y = x[1]
		elif isinstance(x, Point):
			self.x = x.x
			self.y = x.y
		else:
			self.x = x
			self.y = y

	def __add__(self, other):
		return Vector(self.x + other.x, self.y + other.y)

	def __sub__(self, other):
		return Vector(self.x - other.x, self.y - other.y)

	def __mul__(self, other):
		return Vector(other * self.x, other * self.y)

	def __truediv__(self, other):
		return Vector(other / self.x, other / self.y)

	@classmethod
	def dot(cls, a, b):
		return a.x * b.x + a.y * b.y

	@classmethod
	def cross(cls, a, b):
		return a.x * b.y - a.y * b.x

	@classmethod
	def is_orthogonal(cls, a, b):
		return Vector.dot(a, b) == 0.0

	@classmethod
	def is_parallel(cls, a, b):
		return Vector.cross(a, b) == 0.0

class Segment(object):

	def __init__(self, p1=Point(), p2=Point()):
		if isinstance(p1, Point):
			self.p1 = p1
			self.p2 = p2
		elif isinstance(p1, tuple):
			self.p1 = Point(p1[0], p1[1])
			self.p2 = Point(p2[0], p2[1])

	def intersect(self, s):
		ans1 = s.p1.ccw(self.p1, self.p2) * s.p2.ccw(self.p1, self.p2)
		ans2 = self.p1.ccw(s.p1, s.p2) * self.p2.ccw(s.p1, s.p2)
		return ans1 <= 0 and ans2 <= 0

	def cross_point(self, s):
		base = s.p2 - s.p1
		d1 = abs(Vector.cross(base, self.p1 - s.p1))
		d2 = abs(Vector.cross(base, self.p2 - s.p1))
		t = d1 / (d1 + d2)
		return self.p1 + (self.p2 - self.p1) * t

	def distance(self, s):
		if self.intersect(s):
			return 0.0
		d1 = s.p1.distance(self)
		d2 = s.p2.distance(self)
		d3 = self.p1.distance(s)
		d4 = self.p2.distance(s)
		return min(d1, d2, d3, d4)

	@classmethod
	def is_orthogonal(cls, s1, s2):
		a = Vector(s1.p2 - s1.p1)
		b = Vector(s2.p2 - s2.p1)
		return Vector.is_orthogonal(a, b)

	@classmethod
	def is_parallel(cls, s1, s2):
		a = Vector(s1.p2 - s1.p1)
		b = Vector(s2.p2 - s2.p1)
		return Vector.is_parallel(a, b)

class Line(Segment):
	pass

class Cirle(object):

	def __init__(self, c=Point(), r=0.0):
		self.c = c
		self.r = r

def main(args):
	q = int(input())
	for _ in range(q):
		(x_p0, y_p0, x_p1, y_p1, x_p2, y_p2, x_p3, y_p3) = map(int, input().split())
		p0 = Point(x_p0, y_p0)
		p1 = Point(x_p1, y_p1)
		p2 = Point(x_p2, y_p2)
		p3 = Point(x_p3, y_p3)
		s1 = Segment(p0, p1)
		s2 = Segment(p2, p3)
		result = s1.distance(s2)
		print('{:.10f}'.format(result))
main(sys.argv[1:])


import sys
from itertools import starmap
readline = sys.stdin.readline
EPS = 1e-09

class Segment(object):
	__slots__ = ('fi', 'se')

	def __init__(self, fi, se):
		self.fi = fi
		self.se = se

def cross(a, b):
	return a.real * b.imag - a.imag * b.real

def dot(a, b):
	return a.real * b.real + a.imag * b.imag

def norm(base):
	return abs(base) ** 2

def project(s, p2):
	base = s.fi - s.se
	r = dot(p2 - s.fi, base) / norm(base)
	return s.fi + base * r

def reflect(s, p):
	return p + (project(s, p) - p) * 2.0

def ccw(p1, p2, p3):
	a = p2 - p1
	b = p3 - p1
	if cross(a, b) > EPS:
		return 1
	if cross(a, b) < -EPS:
		return -1
	if dot(a, b) < -EPS:
		return 2
	if norm(a) < norm(b):
		return -2
	return 0

def intersect4(p1, p2, p3, p4):
	return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0

def intersect2(s1, s2):
	return intersect4(s1.fi, s1.se, s2.fi, s2.se)

def getDistance(a, b):
	return abs(a - b)

def getDistanceLP(l, p):
	return abs(cross(l.se - l.fi, p - l.fi) / abs(l.se - l.fi))

def getDistanceSP(s, p):
	if dot(s.se - s.fi, p - s.fi) < 0.0:
		return abs(p - s.fi)
	if dot(s.fi - s.se, p - s.se) < 0.0:
		return abs(p - s.se)
	return getDistanceLP(s, p)

def getDistances(s1, s2):
	if intersect2(s1, s2):
		return 0.0
	return min(min(getDistanceSP(s1, s2.fi), getDistanceSP(s1, s2.se)), min(getDistanceSP(s2, s1.fi), getDistanceSP(s2, s1.se)))
n = int(readline())
for _ in [0] * n:
	li = tuple(map(int, readline().split()))
	(p0, p1, p2, p3) = (x + y * 1j for (x, y) in zip(li[::2], li[1::2]))
	s1 = Segment(p0, p1)
	s2 = Segment(p2, p3)
	print('{0:.10f}'.format(getDistances(s1, s2)))


EPS = 0.0001

def PointSegmentDistance(point, begin, end):
	(point, begin, end) = (point - begin, 0, end - begin)
	point = point / end * abs(end)
	end = abs(end)
	if -EPS <= point.real <= abs(end):
		return abs(point.imag)
	else:
		return min(abs(point), abs(point - end))

def OuterProduct(one, two):
	tmp = one.conjugate() * two
	return tmp.imag

def InnerProduct(one, two):
	tmp = one.conjugate() * two
	return tmp.real

def IsOnSegment(point, begin, end):
	if abs(OuterProduct(begin - point, end - point)) <= EPS and InnerProduct(begin - point, end - point) <= EPS:
		return True
	else:
		return False

def CCW(p, q, r):
	(one, two) = (q - p, r - q)
	if OuterProduct(one, two) > -EPS:
		return True
	else:
		return False

def Intersect_SS(b1, e1, b2, e2):
	if IsOnSegment(b1, b2, e2) or IsOnSegment(e1, b2, e2) or IsOnSegment(b2, b1, e1) or IsOnSegment(e2, b1, e1):
		return True
	elif CCW(b1, e1, b2) != CCW(b1, e1, e2) and CCW(b2, e2, b1) != CCW(b2, e2, e1):
		return True
	else:
		return False

def SegmentSegmentDistance(a, b, c, d):
	if Intersect_SS(a, b, c, d):
		return 0
	else:
		return min(PointSegmentDistance(a, c, d), PointSegmentDistance(b, c, d), PointSegmentDistance(c, a, b), PointSegmentDistance(d, a, b))
n = int(input())
for _ in range(n):
	pp = list(map(int, input().split()))
	p = [complex(pp[i], pp[i + 1]) for i in range(0, 8, 2)]
	print(SegmentSegmentDistance(p[0], p[1], p[2], p[3]))


import collections
import math

class Vector2(collections.namedtuple('Vector2', ['x', 'y'])):

	def __add__(self, other):
		return Vector2(self.x + other.x, self.y + other.y)

	def __sub__(self, other):
		return Vector2(self.x - other.x, self.y - other.y)

	def __mul__(self, scalar):
		return Vector2(self.x * scalar, self.y * scalar)

	def __neg__(self):
		return Vector2(-self.x, -self.y)

	def __pos__(self):
		return Vector2(+self.x, +self.y)

	def __abs__(self):
		return math.sqrt(float(self.x * self.x + self.y * self.y))

	def dot(self, other):
		return self.x * other.x + self.y * other.y

	def cross(self, other):
		return self.x * other.y - self.y * other.x

def getDistanceSP(segment, point):
	p = point
	(p1, p2) = segment
	if (p2 - p1).dot(p - p1) < 0:
		return abs(p - p1)
	if (p1 - p2).dot(p - p2) < 0:
		return abs(p - p2)
	return abs((p2 - p1).cross(p - p1)) / abs(p2 - p1)

def getDistance(s1, s2):
	(a, b) = s1
	(c, d) = s2
	if intersect(s1, s2):
		return 0
	return min(getDistanceSP(s1, c), getDistanceSP(s1, d), getDistanceSP(s2, a), getDistanceSP(s2, b))

def ccw(p0, p1, p2):
	a = p1 - p0
	b = p2 - p0
	if a.cross(b) > 0:
		return 1
	elif a.cross(b) < 0:
		return -1
	elif a.dot(b) < 0:
		return 2
	elif abs(a) < abs(b):
		return -2
	else:
		return 0

def intersect(s1, s2):
	(a, b) = s1
	(c, d) = s2
	return ccw(a, b, c) * ccw(a, b, d) <= 0 and ccw(c, d, a) * ccw(c, d, b) <= 0
n = int(input())
for _ in range(n):
	l = list(map(int, input().split()))
	s1 = [Vector2(l[0], l[1]), Vector2(l[2], l[3])]
	s2 = [Vector2(l[4], l[5]), Vector2(l[6], l[7])]
	print(getDistance(s1, s2))


def cross(c1, c2):
	return c1.real * c2.imag - c1.imag * c2.real

def dot(c1, c2):
	return c1.real * c2.real + c1.imag * c2.imag

def ccw(p0, p1, p2):
	a = p1 - p0
	b = p2 - p0
	cross_ab = cross(a, b)
	if cross_ab > 0:
		return 1
	elif cross_ab < 0:
		return -1
	elif dot(a, b) < 0:
		return 1
	elif abs(a) < abs(b):
		return -1
	else:
		return 0

def intersect(p1, p2, p3, p4):
	if ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0:
		return True
	else:
		return False

def get_distance_sp(sp1, sp2, p):
	a = sp2 - sp1
	b = p - sp1
	if dot(a, b) < 0:
		return abs(b)
	c = sp1 - sp2
	d = p - sp2
	if dot(c, d) < 0:
		return abs(d)
	return abs(cross(a, b)) / abs(a)

def print_distance(p1, p2, p3, p4):
	if intersect(p1, p2, p3, p4):
		print('0.0000000000')
	else:
		d = min(get_distance_sp(p1, p2, p3), get_distance_sp(p1, p2, p4), get_distance_sp(p3, p4, p1), get_distance_sp(p3, p4, p2))
		print('{0:.10f}'.format(d))
import sys
file_input = sys.stdin
sq = file_input.readline()
for line in file_input:
	(x_p0, y_p0, x_p1, y_p1, x_p2, y_p2, x_p3, y_p3) = map(int, line.split())
	p0 = x_p0 + y_p0 * 1j
	p1 = x_p1 + y_p1 * 1j
	p2 = x_p2 + y_p2 * 1j
	p3 = x_p3 + y_p3 * 1j
	print_distance(p0, p1, p2, p3)


import sys
from itertools import starmap
readline = sys.stdin.readline
EPS = 1e-09

class Segment(object):
	__slots__ = ('fi', 'se')

	def __init__(self, fi, se):
		self.fi = fi
		self.se = se

def cross(a, b):
	return a.real * b.imag - a.imag * b.real

def dot(a, b):
	return a.real * b.real + a.imag * b.imag

def norm(base):
	return abs(base) ** 2

def project(s, p2):
	base = s.fi - s.se
	r = dot(p2 - s.fi, base) / norm(base)
	return s.fi + base * r

def reflect(s, p):
	return p + (project(s, p) - p) * 2.0

def ccw(p1, p2, p3):
	a = p2 - p1
	b = p3 - p1
	if cross(a, b) > EPS:
		return 1
	if cross(a, b) < -EPS:
		return -1
	if dot(a, b) < -EPS:
		return 2
	if norm(a) < norm(b):
		return -2
	return 0

def intersect4(p1, p2, p3, p4):
	return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0

def intersect2(s1, s2):
	return intersect4(s1.fi, s1.se, s2.fi, s2.se)

def getDistance(a, b):
	return abs(a - b)

def getDistanceLP(l, p):
	return abs(cross(l.se - l.fi, p - l.fi) / abs(l.se - l.fi))

def getDistanceSP(s, p):
	if dot(s.se - s.fi, p - s.fi) < 0.0:
		return abs(p - s.fi)
	if dot(s.fi - s.se, p - s.se) < 0.0:
		return abs(p - s.se)
	return getDistanceLP(s, p)

def getDistances(s1, s2):
	if intersect2(s1, s2):
		return 0.0
	return min(getDistanceSP(s1, s2.fi), getDistanceSP(s1, s2.se), getDistanceSP(s2, s1.fi), getDistanceSP(s2, s1.se))
n = int(readline())
for _ in [0] * n:
	li = tuple(map(int, readline().split()))
	(p0, p1, p2, p3) = (x + y * 1j for (x, y) in zip(li[::2], li[1::2]))
	s1 = Segment(p0, p1)
	s2 = Segment(p2, p3)
	print('{0:.10f}'.format(getDistances(s1, s2)))


from itertools import starmap

def cross(a: complex, b: complex) -> float:
	return float(a.real * b.imag - a.imag * b.real)

def is_intersected(p0: complex, p1: complex, p2: complex, p3: complex) -> bool:
	(max_x1, min_x1) = (p0.real, p1.real) if p0.real > p1.real else (p1.real, p0.real)
	(max_x2, min_x2) = (p2.real, p3.real) if p2.real > p3.real else (p3.real, p2.real)
	if max_x1 < min_x2 or max_x2 < min_x1:
		return False
	(max_y1, min_y1) = (p0.imag, p1.imag) if p0.imag > p1.imag else (p1.imag, p0.imag)
	(max_y2, min_y2) = (p2.imag, p3.imag) if p2.imag > p3.imag else (p3.imag, p2.imag)
	if max_y1 < min_y2 or max_y2 < min_y1:
		return False
	return cross(p1 - p0, p2 - p0) * cross(p1 - p0, p3 - p0) < 1e-06 and cross(p3 - p2, p0 - p2) * cross(p3 - p2, p1 - p2) < 1e-06

def point_to_segment(p0: complex, p1: complex, p2: complex) -> float:
	prod = (p1 - p0).conjugate() * (p2 - p0)
	if prod.real <= 1e-06:
		return abs(p2 - p0)
	l = abs(p1 - p0)
	d = prod.real / l
	if d >= l:
		return abs(p2 - p1)
	return abs(prod.imag) / l
q = int(input())
for _ in range(q):
	(x_p0, y_p0, x_p1, y_p1, x_p2, y_p2, x_p3, y_p3) = map(lambda x: int(x), input().split())
	p0 = complex(x_p0, y_p0)
	p1 = complex(x_p1, y_p1)
	p2 = complex(x_p2, y_p2)
	p3 = complex(x_p3, y_p3)
	if is_intersected(p0, p1, p2, p3):
		print(0)
		continue
	ans = min(starmap(point_to_segment, ((p0, p1, p2), (p0, p1, p3), (p2, p3, p0), (p2, p3, p1))))
	print(ans)


EPS = 1e-10
COUNTER_CLOCKWISE = 1
CLOCKWISE = -1
ONLINE_BACK = 2
ONLINE_FRONT = -2
ON_SEGMENT = 0

class Point:
	global EPS

	def __init__(self, x=0, y=0):
		self.x = x
		self.y = y

	def __add__(a, b):
		s = a.x + b.x
		t = a.y + b.y
		return Point(s, t)

	def __sub__(a, b):
		s = a.x - b.x
		t = a.y - b.y
		return Point(s, t)

	def __mul__(self, a):
		s = a * self.x
		t = a * self.y
		return Point(s, t)

	def __truediv__(self, a):
		s = self.x / a
		t = self.y / a
		return Point(s, t)

	def norm(self):
		return self.x * self.x + self.y * self.y

	def abs(self):
		return self.norm() ** 0.5

	def __eq__(self, other):
		return abs(self.x - other.y) < self.EPS and abs(self.y - other.y) < self.EPS

	def dot(self, b):
		return self.x * b.x + self.y * b.y

	def cross(self, b):
		return self.x * b.y - self.y * b.x

class Segment:

	def __init__(self, p1, p2):
		self.p1 = p1
		self.p2 = p2

def project(s, p):
	base = s.p2 - s.p1
	hypo = p - s.p1
	r = hypo.dot(base) / base.norm()
	return s.p1 + base * r

def reflecton(s, p):
	return p + (project(s, p) - p) * 2

def getDistance(a, b):
	return (a - b).abs()

def getDistanceLP(l, p):
	return abs((l.p2 - l.p1).cross(p - l.p1)) / (l.p2 - l.p1).abs()

def getDistanceSP(s, p):
	if (s.p2 - s.p1).dot(p - s.p1) < 0:
		return (p - s.p1).abs()
	elif (s.p1 - s.p2).dot(p - s.p2) < 0:
		return (p - s.p2).abs()
	return getDistanceLP(s, p)

def getDistanceSS(s1, s2):
	if intersectS(s1, s2):
		return 0
	return min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2), getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2))

def ccw(p0, p1, p2):
	a = p1 - p0
	b = p2 - p0
	if a.cross(b) > 0:
		return COUNTER_CLOCKWISE
	elif a.cross(b) < 0:
		return CLOCKWISE
	elif a.dot(b) < 0:
		return ONLINE_BACK
	elif a.abs() < b.abs():
		return ONLINE_FRONT
	else:
		return ON_SEGMENT

def intersect(p1, p2, p3, p4):
	return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0

def intersectS(s1, s2):
	return intersect(s1.p1, s1.p2, s2.p1, s2.p2)
n = int(input())
for i in range(n):
	nums = list(map(int, input().split()))
	s1 = Segment(Point(nums[0], nums[1]), Point(nums[2], nums[3]))
	s2 = Segment(Point(nums[4], nums[5]), Point(nums[6], nums[7]))
	print(getDistanceSS(s1, s2))


import sys
sys.setrecursionlimit(10 ** 9)

def input():
	return sys.stdin.readline().strip()

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST():
	return list(map(int, input().split()))
INF = float('inf')

class Geometry:
	EPS = 10 ** (-9)

	def add(self, a, b):
		(x1, y1) = a
		(x2, y2) = b
		return (x1 + x2, y1 + y2)

	def sub(self, a, b):
		(x1, y1) = a
		(x2, y2) = b
		return (x1 - x2, y1 - y2)

	def mul(self, a, b):
		(x1, y1) = a
		if not isinstance(b, tuple):
			return (x1 * b, y1 * b)
		(x2, y2) = b
		return (x1 * x2, y1 * y2)

	def abs(self, a):
		from math import hypot
		(x1, y1) = a
		return hypot(x1, y1)

	def norm(self, a):
		(x, y) = a
		return x ** 2 + y ** 2

	def dot(self, a, b):
		(x1, y1) = a
		(x2, y2) = b
		return x1 * x2 + y1 * y2

	def cross(self, a, b):
		(x1, y1) = a
		(x2, y2) = b
		return x1 * y2 - y1 * x2

	def project(self, seg, p):
		(p1, p2) = seg
		base = self.sub(p2, p1)
		r = self.dot(self.sub(p, p1), base) / self.norm(base)
		return self.add(p1, self.mul(base, r))

	def reflect(self, seg, p):
		return self.add(p, self.mul(self.sub(self.project(seg, p), p), 2))

	def ccw(self, p0, p1, p2):
		a = self.sub(p1, p0)
		b = self.sub(p2, p0)
		if self.cross(a, b) > self.EPS:
			return 1
		if self.cross(a, b) < -self.EPS:
			return -1
		if self.dot(a, b) < -self.EPS:
			return 2
		if self.norm(a) < self.norm(b):
			return -2
		return 0

	def intersect(self, seg1, seg2):
		(p1, p2) = seg1
		(p3, p4) = seg2
		return self.ccw(p1, p2, p3) * self.ccw(p1, p2, p4) <= 0 and self.ccw(p3, p4, p1) * self.ccw(p3, p4, p2) <= 0

	def get_distance_LP(self, line, p):
		(p1, p2) = line
		return abs(self.cross(self.sub(p2, p1), self.sub(p, p1)) / self.abs(self.sub(p2, p1)))

	def get_distance_SP(self, seg, p):
		(p1, p2) = seg
		if self.dot(self.sub(p2, p1), self.sub(p, p1)) < 0:
			return self.abs(self.sub(p, p1))
		if self.dot(self.sub(p1, p2), self.sub(p, p2)) < 0:
			return self.abs(self.sub(p, p2))
		return self.get_distance_LP(seg, p)

	def get_distance_SS(self, seg1, seg2):
		(p1, p2) = seg1
		(p3, p4) = seg2
		if self.intersect(seg1, seg2):
			return 0
		return min(self.get_distance_SP(seg1, p3), self.get_distance_SP(seg1, p4), self.get_distance_SP(seg2, p1), self.get_distance_SP(seg2, p2))
gm = Geometry()
for _ in range(INT()):
	(x1, y1, x2, y2, x3, y3, x4, y4) = MAP()
	seg1 = ((x1, y1), (x2, y2))
	seg2 = ((x3, y3), (x4, y4))
	print(gm.get_distance_SS(seg1, seg2))


import sys

class Line:

	def __init__(self, p1, p2):
		if p1[1] < p2[1]:
			self.s = p2
			self.e = p1
		elif p1[1] > p2[1]:
			self.s = p1
			self.e = p2
		elif p1[0] < p2[0]:
			self.s = p1
			self.e = p2
		else:
			self.s = p2
			self.e = p1

def cross(a, b):
	return a[0] * b[1] - a[1] * b[0]

def dot(a, b):
	return a[0] * b[0] + a[1] * b[1]

def dif(a, b):
	return [x - y for (x, y) in zip(a, b)]

def dist(a, b):
	return ((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2) ** 0.5

def isec(l, m):
	a = dif(l.e, l.s)
	b = dif(m.e, l.s)
	c = dif(m.s, l.s)
	d = dif(m.e, m.s)
	e = dif(l.e, m.s)
	f = dif(l.s, m.s)
	g = lambda a, b: cross(a, b) == 0 and dot(a, b) > 0 and (dot(b, b) < dot(a, a))
	if g(a, b) or g(a, c) or g(d, e) or g(d, f):
		return True
	elif l.s == m.e or l.s == m.s or l.e == m.e or (l.e == m.s):
		return True
	elif cross(a, b) * cross(a, c) >= 0 or cross(d, e) * cross(d, f) >= 0:
		return False
	else:
		return True

def plus(a, b):
	return [x + y for (x, y) in zip(a, b)]

def projection(a, b):
	return [x * dot(a, b) / dot(a, a) for x in a]

def proj(A, B, C, D):
	AB = dif(B, A)
	AC = dif(C, A)
	AD = dif(D, A)
	CD = dif(D, C)
	CA = dif(A, C)
	CB = dif(B, C)
	_A = plus(projection(CD, CA), C)
	_B = plus(projection(CD, CB), C)
	_C = plus(projection(AB, AC), A)
	_D = plus(projection(AB, AD), A)
	return [_A, _B, _C, _D]

def Order(a, b):
	crs = cross(a, b)
	if abs(crs) < 1e-10:
		crs = 0.0
	if crs > 0:
		return 'COUNTER_CLOCKWISE'
	elif crs < 0:
		return 'CLOCKWISE'
	elif dot(a, b) < 0:
		return 'ONLINE_BACK'
	elif dot(a, a) < dot(b, b):
		return 'ONLINE_FRONT'
	else:
		return 'ON_SEGMENT'
q = int(input())
for i in range(q):
	(a, b, c, d, e, f, g, h) = [int(i) for i in input().split()]
	A = [a, b]
	B = [c, d]
	C = [e, f]
	D = [g, h]
	l = Line(A, B)
	m = Line(C, D)
	if isec(l, m):
		print(0.0)
		continue
	(_A, _B, _C, _D) = proj(A, B, C, D)
	AB = dif(B, A)
	CD = dif(D, C)
	A_C = dif(_C, A)
	A_D = dif(_D, A)
	C_A = dif(_A, C)
	C_B = dif(_B, C)
	DIST = [dist(A, C), dist(A, D), dist(B, C), dist(B, D), dist(_A, A), dist(_B, B), dist(_C, C), dist(_D, D)]
	fun = lambda x: x != 'ON_SEGMENT'
	if fun(Order(CD, C_A)):
		DIST[4] = sys.maxsize
	if fun(Order(CD, C_B)):
		DIST[5] = sys.maxsize
	if fun(Order(AB, A_C)):
		DIST[6] = sys.maxsize
	if fun(Order(AB, A_D)):
		DIST[7] = sys.maxsize
	print(min(DIST))


import sys
from sys import stdin
input = stdin.readline

class Point(object):
	epsilon = 1e-10

	def __init__(self, x=0.0, y=0.0):
		if isinstance(x, tuple):
			self.x = x[0]
			self.y = x[1]
		else:
			self.x = x
			self.y = y

	def __add__(self, other):
		return Point(self.x + other.x, self.y + other.y)

	def __sub__(self, other):
		return Point(self.x - other.x, self.y - other.y)

	def __mul__(self, other):
		return Point(other * self.x, other * self.y)

	def __truediv__(self, other):
		return Point(other / self.x, other / self.y)

	def __lt__(self, other):
		if self.x == other.x:
			return self.y < other.y
		else:
			return self.x < other.x

	def __eq__(self, other):
		from math import fabs
		if fabs(self.x - other.x) < Point.epsilon and fabs(self.y - other.y) < Point.epsilon:
			return True
		else:
			return False

	def norm(self):
		return self.x * self.x + self.y * self.y

	def abs(self):
		from math import sqrt
		return sqrt(self.norm())

	def ccw(self, p0, p1):
		a = Vector(p1 - p0)
		b = Vector(self - p0)
		if Vector.cross(a, b) > Point.epsilon:
			return 1
		elif Vector.cross(a, b) < -Point.epsilon:
			return -1
		elif Vector.dot(a, b) < -Point.epsilon:
			return 2
		elif a.norm() < b.norm():
			return -2
		else:
			return 0

	def project(self, s):
		base = Vector(s.p2 - s.p1)
		a = Vector(self - s.p1)
		r = Vector.dot(a, base)
		r /= base.norm()
		return s.p1 + base * r

	def reflect(self, s):
		proj = self.project(s)
		return self + (proj - self) * 2

	def distance(self, s):
		if Vector.dot(s.p2 - s.p1, self - s.p1) < 0.0:
			return (self - s.p1).abs()
		if Vector.dot(s.p1 - s.p2, self - s.p2) < 0.0:
			return (self - s.p2).abs()
		return abs(Vector.cross(s.p2 - s.p1, self - s.p1) / (s.p2 - s.p1).abs())

class Vector(Point):

	def __init__(self, x=0.0, y=0.0):
		if isinstance(x, tuple):
			self.x = x[0]
			self.y = x[1]
		elif isinstance(x, Point):
			self.x = x.x
			self.y = x.y
		else:
			self.x = x
			self.y = y

	def __add__(self, other):
		return Vector(self.x + other.x, self.y + other.y)

	def __sub__(self, other):
		return Vector(self.x - other.x, self.y - other.y)

	def __mul__(self, other):
		return Vector(other * self.x, other * self.y)

	def __truediv__(self, other):
		return Vector(other / self.x, other / self.y)

	@classmethod
	def dot(cls, a, b):
		return a.x * b.x + a.y * b.y

	@classmethod
	def cross(cls, a, b):
		return a.x * b.y - a.y * b.x

	@classmethod
	def is_orthogonal(cls, a, b):
		return Vector.dot(a, b) == 0.0

	@classmethod
	def is_parallel(cls, a, b):
		return Vector.cross(a, b) == 0.0

class Segment(object):

	def __init__(self, p1=Point(), p2=Point()):
		if isinstance(p1, Point):
			self.p1 = p1
			self.p2 = p2
		elif isinstance(p1, tuple):
			self.p1 = Point(p1[0], p1[1])
			self.p2 = Point(p2[0], p2[1])

	def intersect(self, s):
		ans1 = s.p1.ccw(self.p1, self.p2) * s.p2.ccw(self.p1, self.p2)
		ans2 = self.p1.ccw(s.p1, s.p2) * self.p2.ccw(s.p1, s.p2)
		return ans1 <= 0 and ans2 <= 0

	def cross_point(self, s):
		base = s.p2 - s.p1
		d1 = abs(Vector.cross(base, self.p1 - s.p1))
		d2 = abs(Vector.cross(base, self.p2 - s.p1))
		t = d1 / (d1 + d2)
		return self.p1 + (self.p2 - self.p1) * t

	def distance(self, s):
		if self.intersect(s):
			return 0.0
		d1 = s.p1.distance(self)
		d2 = s.p2.distance(self)
		d3 = self.p1.distance(s)
		d4 = self.p2.distance(s)
		return min(d1, d2, d3, d4)

	@classmethod
	def is_orthogonal(cls, s1, s2):
		a = Vector(s1.p2 - s1.p1)
		b = Vector(s2.p2 - s2.p1)
		return Vector.is_orthogonal(a, b)

	@classmethod
	def is_parallel(cls, s1, s2):
		a = Vector(s1.p2 - s1.p1)
		b = Vector(s2.p2 - s2.p1)
		return Vector.is_parallel(a, b)

class Line(Segment):
	pass

class Cirle(object):

	def __init__(self, c=Point(), r=0.0):
		self.c = c
		self.r = r

def main(args):
	q = int(input())
	for _ in range(q):
		(x_p0, y_p0, x_p1, y_p1, x_p2, y_p2, x_p3, y_p3) = map(int, input().split())
		p0 = Point(x_p0, y_p0)
		p1 = Point(x_p1, y_p1)
		p2 = Point(x_p2, y_p2)
		p3 = Point(x_p3, y_p3)
		s1 = Segment(p0, p1)
		s2 = Segment(p2, p3)
		result = s1.distance(s2)
		print('{:.10f}'.format(result))
main(sys.argv[1:])


def cross(c1, c2):
	return c1.real * c2.imag - c1.imag * c2.real

def dot(c1, c2):
	return c1.real * c2.real + c1.imag * c2.imag

def ccw(p0, p1, p2):
	a = p1 - p0
	b = p2 - p0
	cross_ab = cross(a, b)
	if cross_ab > 0:
		return 1
	elif cross_ab < 0:
		return -1
	elif dot(a, b) < 0:
		return 1
	elif abs(a) < abs(b):
		return -1
	else:
		return 0

def intersect(p1, p2, p3, p4):
	if ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0:
		return True
	else:
		return False

def get_distance_sp(sp1, sp2, p):
	a = sp2 - sp1
	b = p - sp1
	if dot(a, b) < 0:
		return abs(b)
	c = sp1 - sp2
	d = p - sp2
	if dot(c, d) < 0:
		return abs(d)
	return abs(cross(a, b)) / abs(a)

def print_distance(p1, p2, p3, p4):
	if intersect(p1, p2, p3, p4):
		print('0.0000000000')
	else:
		d = min(get_distance_sp(p1, p2, p3), get_distance_sp(p1, p2, p4), get_distance_sp(p3, p4, p1), get_distance_sp(p3, p4, p2))
		print('{0:.10f}'.format(d))
n = int(input())
for line in range(n):
	(x_p0, y_p0, x_p1, y_p1, x_p2, y_p2, x_p3, y_p3) = map(int, input().split())
	p0 = x_p0 + y_p0 * 1j
	p1 = x_p1 + y_p1 * 1j
	p2 = x_p2 + y_p2 * 1j
	p3 = x_p3 + y_p3 * 1j
	print_distance(p0, p1, p2, p3)


import sys
from collections import namedtuple
from itertools import starmap
readline = sys.stdin.readline
EPS = 1e-09

class Segment(object):
	__slots__ = ('fi', 'se')

	def __init__(self, fi, se):
		self.fi = fi
		self.se = se

def cross(a, b):
	return a.real * b.imag - a.imag * b.real

def dot(a, b):
	return a.real * b.real + a.imag * b.imag

def norm(base):
	return abs(base) ** 2

def project(s, p2):
	base = s.fi - s.se
	r = dot(p2 - s.fi, base) / norm(base)
	return s.fi + base * r

def reflect(s, p):
	return p + (project(s, p) - p) * 2.0

def ccw(p1, p2, p3):
	a = p2 - p1
	b = p3 - p1
	if cross(a, b) > EPS:
		return 1
	if cross(a, b) < -EPS:
		return -1
	if dot(a, b) < -EPS:
		return 2
	if norm(a) < norm(b):
		return -2
	return 0

def intersect4(p1, p2, p3, p4):
	return ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 and ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0

def intersect2(s1, s2):
	return intersect4(s1.fi, s1.se, s2.fi, s2.se)

def getDistance(a, b):
	return abs(a - b)

def getDistanceLP(l, p):
	return abs(cross(l.se - l.fi, p - l.fi) / abs(l.se - l.fi))

def getDistanceSP(s, p):
	if dot(s.se - s.fi, p - s.fi) < 0.0:
		return abs(p - s.fi)
	if dot(s.fi - s.se, p - s.se) < 0.0:
		return abs(p - s.se)
	return getDistanceLP(s, p)

def getDistances(s1, s2):
	if intersect2(s1, s2):
		return 0.0
	return min(getDistanceSP(s1, s2.fi), getDistanceSP(s1, s2.se), getDistanceSP(s2, s1.fi), getDistanceSP(s2, s1.se))
n = int(readline())
for _ in [0] * n:
	li = tuple(map(int, readline().split()))
	(p0, p1, p2, p3) = (x + y * 1j for (x, y) in zip(li[::2], li[1::2]))
	s1 = Segment(p0, p1)
	s2 = Segment(p2, p3)
	print('{0:.10f}'.format(getDistances(s1, s2)))


from sys import stdin
readline = stdin.readline

def main():
	q = int(readline())
	for i in range(q):
		xy = map(int, readline().split())
		(p0, p1, p2, p3) = [x + y * 1j for (x, y) in zip(*[xy] * 2)]
		print('{:.10f}'.format(distance(p0, p1, p2, p3)))

def lt(a, b):
	if a.real != b.real:
		return a.real <= b.real
	return a.imag < b.imag
import itertools

def distance(p0, p1, p2, p3):
	if is_intersected_ls(p0, p1, p2, p3):
		return 0
	p = []
	for (i, j) in itertools.product([p0, p1], [p2, p3]):
		p.append(abs(i - j))
	for (i, j, k) in [(p0, p1, p2), (p0, p1, p3), (p2, p3, p0), (p2, p3, p1)]:
		tmp = intersection_of_perpendicular(i, j, k)
		if lt(i, tmp) and lt(tmp, j) or (lt(j, tmp) and lt(tmp, i)):
			p.append(abs(tmp - k))
	return min(p)

def intersection_of_perpendicular(p1, p2, p3):
	return p1 + (p2 - p1) * projecter(p2 - p1, p3 - p1)

def projecter(a, b):
	return dot(a, b) / dot(a, a)

def dot(a, b):
	return a.real * b.real + a.imag * b.imag

def is_intersected_ls(a1, a2, b1, b2):
	eps = 0
	if max(a1.real, a2.real) < min(b1.real, b2.real) or max(b1.real, b2.real) < min(a1.real, a2.real) or max(a1.imag, a2.imag) < min(b1.imag, b2.imag) or (max(b1.imag, b2.imag) < min(a1.imag, a2.imag)):
		return False
	return cross(a2 - a1, b1 - a1) * cross(a2 - a1, b2 - a1) <= eps and cross(b2 - b1, a1 - b1) * cross(b2 - b1, a2 - b1) <= eps

def intersection(p1, p2, p3, p4):
	a1 = p4 - p2
	b1 = p2 - p3
	b2 = p1 - p2
	s1 = cross(a1, b2) / 2
	s2 = cross(a1, b1) / 2
	c1 = p1 + (p3 - p1) * s1 / (s1 + s2)
	return c1

def cross(a, b):
	return a.real * b.imag - a.imag * b.real
main()


from math import sqrt

def cross(p0, p1, p2):
	(x0, y0) = p0
	(x1, y1) = p1
	(x2, y2) = p2
	x1 -= x0
	x2 -= x0
	y1 -= y0
	y2 -= y0
	return x1 * y2 - x2 * y1

def dot(p0, p1, p2):
	(x0, y0) = p0
	(x1, y1) = p1
	(x2, y2) = p2
	x1 -= x0
	x2 -= x0
	y1 -= y0
	y2 -= y0
	return x1 * x2 + y1 * y2

def dist2(p0, p1):
	(x0, y0) = p0
	(x1, y1) = p1
	return (x1 - x0) ** 2 + (y1 - y0) ** 2

def collision_ll(s0, s1, t0, t1):
	return cross(s0, s1, t0) * cross(s0, s1, t1) < 0 and cross(t0, t1, s0) * cross(t0, t1, s1) < 0

def dist_lp(S, E, P):
	dd = dist2(S, E)
	if 0 <= dot(S, E, P) <= dd:
		return abs(cross(S, E, P)) / sqrt(dd)
	return sqrt(min(dist2(S, P), dist2(E, P)))

def dist_ll(s0, s1, t0, t1):
	if collision_ll(s0, s1, t0, t1):
		return 0
	return min(dist_lp(s0, s1, t0), dist_lp(s0, s1, t1), dist_lp(t0, t1, s0), dist_lp(t0, t1, s1))
n = int(input())
for i in range(n):
	(x0, y0, x1, y1, X0, Y0, X1, Y1) = map(int, input().split())
	print('%.010f' % dist_ll((x0, y0), (x1, y1), (X0, Y0), (X1, Y1)))


import sys
from collections import namedtuple
EPS = 1e-09

def cross(a, b):
	return a.real * b.imag - a.imag * b.real

def dot(a, b):
	return a.real * b.real + a.imag * b.imag

def get_distance_lp(l, p):
	return abs(cross(l.target - l.source, p - l.source) / abs(l.target - l.source))

def get_distance_sp(s, p):
	if dot(s.target - s.source, p - s.source) < 0:
		return abs(p - s.source)
	elif dot(s.source - s.target, p - s.target) < 0:
		return abs(p - s.target)
	else:
		return get_distance_lp(s, p)

def check_ccw(p0, p1, p2):
	(a, b) = (p1 - p0, p2 - p0)
	if cross(a, b) > EPS:
		flag = 1
	elif cross(a, b) < -1 * EPS:
		flag = -1
	elif dot(a, b) < -1 * EPS:
		flag = 2
	elif abs(a) < abs(b):
		flag = -2
	else:
		flag = 0
	return flag

def check_intersection(p0, p1, p2, p3):
	intersected = check_ccw(p0, p1, p2) * check_ccw(p0, p1, p3) <= 0 and check_ccw(p2, p3, p0) * check_ccw(p2, p3, p1) <= 0
	return intersected

def solve(_segments):
	for segment in _segments:
		axis = tuple(map(int, segment))
		(p0, p1, p2, p3) = (x + y * 1j for (x, y) in zip(axis[::2], axis[1::2]))
		(s1, s2) = (Segment(p0, p1), Segment(p2, p3))
		intersected = check_intersection(s1.source, s1.target, s2.source, s2.target)
		if intersected:
			distance = 0
		else:
			distance = min(min(get_distance_sp(s1, s2.source), get_distance_sp(s1, s2.target)), min(get_distance_sp(s2, s1.source), get_distance_sp(s2, s1.target)))
		print('{ans:.10f}'.format(ans=distance))
	return None
_input = sys.stdin.readlines()
questions = int(_input[0])
segments = map(lambda x: x.split(), _input[1:])
Segment = namedtuple('Segment', ('source', 'target'))
solve(segments)


from sys import stdin
import math
EPS = 1e-10

class Vector:

	def __init__(self, x=None, y=None):
		self.x = x
		self.y = y

	def __add__(self, other):
		return Vector(self.x + other.x, self.y + other.y)

	def __sub__(self, other):
		return Vector(self.x - other.x, self.y - other.y)

	def __mul__(self, k):
		return Vector(self.x * k, self.y * k)

	def __gt__(self, other):
		return self.x > other.x and self.y > other.yb

	def __lt__(self, other):
		return self.x < other.x and self.y < other.yb

	def __eq__(self, other):
		return self.x == other.x and self.y == other.y

	def dot(self, other):
		return self.x * other.x + self.y * other.y

	def cross(self, other):
		return self.x * other.y - self.y * other.x

	def norm(self):
		return self.x * self.x + self.y * self.y

	def abs(self):
		return math.sqrt(self.norm())

class Point(Vector):

	def __init__(self, *args, **kargs):
		return super().__init__(*args, **kargs)

class Segment:

	def __init__(self, p1=Point(0, 0), p2=Point(1, 1)):
		self.p1 = p1
		self.p2 = p2

def ccw(p0, p1, p2):
	a = p1 - p0
	b = p2 - p0
	if a.cross(b) > EPS:
		return 1
	elif a.cross(b) < -EPS:
		return -1
	elif a.dot(b) < -EPS:
		return 2
	elif a.norm() < b.norm():
		return -2
	else:
		return 0

def intersect(*args, **kwargs):
	if len(args) == 2:
		(s1, s2) = args
		return ccw(s1.p1, s1.p2, s2.p1) * ccw(s1.p1, s1.p2, s2.p2) <= 0 and ccw(s2.p1, s2.p2, s1.p1) * ccw(s2.p1, s2.p2, s1.p2) <= 0
	elif len(args) == 4:
		(p0, p1, p2, p3) = args
		return ccw(p0, p1, p2) * ccw(p0, p1, p3) <= 0 and ccw(p2, p3, p0) * ccw(p2, p3, p1) <= 0
	else:
		raise ArgsError

def get_distance_lp(l, p):
	v1 = l.p1 - l.p2
	v2 = p - l.p1
	return abs(v1.cross(v2)) / v1.abs()

def get_distance_sp(s, p):
	v1 = s.p2 - s.p1
	v2 = p - s.p1
	v3 = s.p1 - s.p2
	v4 = p - s.p2
	if v1.dot(v2) < 0:
		return v2.abs()
	elif v3.dot(v4) < 0:
		return v4.abs()
	else:
		return get_distance_lp(s, p)

def get_distance(*args, **kwargs):
	if len(args) == 2:
		(p1, p2) = args
		v = p1 - p2
		return v.abs()
	elif len(kwargs) == 2:
		s1 = kwargs['s1']
		s2 = kwargs['s2']
		if intersect(s1, s2):
			return 0.0
		else:
			return min(min(get_distance_sp(s1, s2.p1), get_distance_sp(s1, s2.p2)), min(get_distance_sp(s2, s1.p1), get_distance_sp(s2, s1.p2)))
	else:
		raise ArgsError

def read_and_print_results(n):
	for _ in range(n):
		line = stdin.readline().strip().split()
		p0 = Vector(int(line[0]), int(line[1]))
		p1 = Vector(int(line[2]), int(line[3]))
		p2 = Vector(int(line[4]), int(line[5]))
		p3 = Vector(int(line[6]), int(line[7]))
		s1 = Segment(p0, p1)
		s2 = Segment(p2, p3)
		d = get_distance(s1=s1, s2=s2)
		print('{0:0.10f}'.format(d))
n = int(input())
read_and_print_results(n)


import math

class Vector:

	def __init__(self, x, y):
		self.x = x
		self.y = y

	def __add__(self, other):
		return Vector(self.x + other.x, self.y + other.y)

	def __sub__(self, other):
		return Vector(self.x - other.x, self.y - other.y)

	def __mul__(self, scalar):
		return Vector(self.x * scalar, self.y * scalar)

	def __rmul__(self, scalar):
		return Vector(self.x * scalar, self.y * scalar)

	def __repr__(self):
		return str([self.x, self.y])

	def norm_2(self):
		return dot(self, self)

	def norm(self):
		return math.sqrt(self.norm_2())

def v_sum(v1, v2):
	return Vector(v1.x + v2.x, v1.y + v2.y)

def scalar_multi(k, v):
	return Vector(k * v.x, k * v.y)

def v_diff(v1, v2):
	return v_sum(v1, scalar_multi(-1, v2))

def dot(vector1, vector2):
	return vector1.x * vector2.x + vector1.y * vector2.y

def cross(vector1, vector2):
	return vector1.x * vector2.y - vector1.y * vector2.x

def in_seg(p, s, t):
	x = p - s
	d = t - s
	if 0 <= dot(x, d) / d.norm_2() <= 1:
		return True
	else:
		return False

def is_crossed(p, q, s, t):
	a = q - p
	b = t - s
	v = s - p
	w = t - p
	x = p - s
	y = q - s
	if cross(a, v) * cross(a, w) <= 0 and cross(b, x) * cross(b, y) <= 0:
		if cross(a, v) == cross(a, w) == cross(b, x) == cross(b, y) == 0:
			if 0 <= dot(a, v) <= a.norm_2() or 0 <= dot(a, w) <= a.norm_2() or 0 <= dot(b, x) <= b.norm_2() or (0 <= dot(b, y) <= b.norm_2()):
				return True
			else:
				return False
		else:
			return True
	else:
		return False

def point_line_dist(p, s, t):
	x = p - s
	d = t - s
	return abs(cross(x, d)) / d.norm()

def calc(p1, p2, p3, p4):
	min_dists = []
	if in_seg(p1, p3, p4):
		min_dists.append(point_line_dist(p1, p3, p4))
	if in_seg(p2, p3, p4):
		min_dists.append(point_line_dist(p2, p3, p4))
	if in_seg(p3, p1, p2):
		min_dists.append(point_line_dist(p3, p1, p2))
	if in_seg(p4, p1, p2):
		min_dists.append(point_line_dist(p4, p1, p2))
	min_dists.append((p1 - p3).norm())
	min_dists.append((p1 - p4).norm())
	min_dists.append((p2 - p3).norm())
	min_dists.append((p2 - p4).norm())
	if is_crossed(p1, p2, p3, p4):
		min_dists.append(0)
	return min(min_dists)
q = int(input())
for i in range(q):
	(x1, y1, x2, y2, x3, y3, x4, y4) = map(float, input().split())
	p1 = Vector(x1, y1)
	p2 = Vector(x2, y2)
	p3 = Vector(x3, y3)
	p4 = Vector(x4, y4)
	print(calc(p1, p2, p3, p4))


import math

class Point:

	def __init__(self, x, y):
		self.x = x
		self.y = y

	def distance(self, pnt):
		return math.sqrt((self.x - pnt.x) ** 2 + (self.y - pnt.y) ** 2)

class Segment:

	def __init__(self, x1, y1, x2, y2):
		self.p1 = Point(x1, y1)
		self.p2 = Point(x2, y2)
		if self.p1.x == self.p2.x:
			self.a = float('inf')
			self.b = None
		else:
			self.a = (self.p1.y - self.p2.y) / (self.p1.x - self.p2.x)
			self.b = self.p1.y - self.a * self.p1.x

	def is_intersect(self, seg):
		a = (seg.p1.x - seg.p2.x) * (self.p1.y - seg.p1.y) + (seg.p1.y - seg.p2.y) * (seg.p1.x - self.p1.x)
		b = (seg.p1.x - seg.p2.x) * (self.p2.y - seg.p1.y) + (seg.p1.y - seg.p2.y) * (seg.p1.x - self.p2.x)
		c = (self.p1.x - self.p2.x) * (seg.p1.y - self.p1.y) + (self.p1.y - self.p2.y) * (self.p1.x - seg.p1.x)
		d = (self.p1.x - self.p2.x) * (seg.p2.y - self.p1.y) + (self.p1.y - self.p2.y) * (self.p1.x - seg.p2.x)
		e = (self.p1.x - seg.p1.x) * (self.p2.x - seg.p2.x)
		f = (self.p1.x - seg.p2.x) * (self.p2.x - seg.p1.x)
		g = (self.p1.y - seg.p1.y) * (self.p2.y - seg.p2.y)
		h = (self.p1.y - seg.p2.y) * (self.p2.y - seg.p1.y)
		return a * b <= 0 and c * d <= 0 and (e <= 0 or f <= 0) and (g <= 0 or h <= 0)

	def cross_point(self, seg):
		if self.is_intersect(seg) == False:
			return None
		if self.a == float('inf'):
			return (self.p1.x, seg.a * self.p1.x + seg.b)
		elif seg.a == float('inf'):
			return (seg.p1.x, self.a * seg.p1.x + self.b)
		else:
			x = -(self.b - seg.b) / (self.a - seg.a)
			y = seg.a * x + seg.b
			return (x, y)

	def distance_with_point(self, pnt):
		vec_a = Point(self.p2.x - self.p1.x, self.p2.y - self.p1.y)
		vec_b = Point(pnt.x - self.p1.x, pnt.y - self.p1.y)
		ip = vec_a.x * vec_b.x + vec_a.y * vec_b.y
		dist2 = (self.p1.x - self.p2.x) ** 2 + (self.p1.y - self.p2.y) ** 2
		if ip / dist2 <= 0:
			return pnt.distance(self.p1)
		elif ip / dist2 >= 1:
			return pnt.distance(self.p2)
		else:
			tmppnt = Point(self.p1.x + vec_a.x * (ip / dist2), self.p1.y + vec_a.y * (ip / dist2))
			return pnt.distance(tmppnt)

	def distance_with_segment(self, seg):
		if self.is_intersect(seg):
			return 0
		a = self.distance_with_point(seg.p1)
		b = self.distance_with_point(seg.p2)
		c = seg.distance_with_point(self.p1)
		d = seg.distance_with_point(self.p2)
		return min(a, b, c, d)
q = int(input())
for i in range(q):
	(x0, y0, x1, y1, x2, y2, x3, y3) = list(map(int, input().split(' ')))
	(line1, line2) = (Segment(x0, y0, x1, y1), Segment(x2, y2, x3, y3))
	dist = line1.distance_with_segment(line2)
	print('%.9f' % dist)


from typing import List, Tuple
from math import sqrt
EPS = 1e-10

def float_equal(x: float, y: float) -> bool:
	return abs(x - y) < EPS

class Point:

	def __init__(self, x: float=0.0, y: float=0.0) -> None:
		self.x = x
		self.y = y

	def __repr__(self) -> str:
		return 'Point({}, {})'.format(self.x, self.y)

	def __eq__(self, other: object) -> bool:
		if not isinstance(other, Point):
			return NotImplemented
		return float_equal(self.x, other.x) and float_equal(self.y, other.y)

	def __add__(self, other: 'Point') -> 'Point':
		return Point(self.x + other.x, self.y + other.y)

	def __sub__(self, other: 'Point') -> 'Point':
		return Point(self.x - other.x, self.y - other.y)

	def __mul__(self, k: float) -> 'Point':
		return Point(self.x * k, self.y * k)

	def __rmul__(self, k: float) -> 'Point':
		return self * k

	def __truediv__(self, k: float) -> 'Point':
		return Point(self.x / k, self.y / k)

	def __lt__(self, other: 'Point') -> bool:
		return self.y < other.y if abs(self.x - other.x) < EPS else self.x < other.x

	def norm(self):
		return self.x * self.x + self.y * self.y

	def abs(self):
		return sqrt(self.norm())

	def dot(self, other: 'Point') -> float:
		return self.x * other.x + self.y * other.y

	def cross(self, other: 'Point') -> float:
		return self.x * other.y - self.y * other.x

	def is_orthogonal(self, other: 'Point') -> bool:
		return float_equal(self.dot(other), 0.0)

	def is_parallel(self, other: 'Point') -> bool:
		return float_equal(self.cross(other), 0.0)

	def distance(self, other: 'Point') -> float:
		return (self - other).abs()

	def in_side_of(self, seg: 'Segment') -> bool:
		return seg.vector().dot(Segment(seg.p1, self).vector()) >= 0

	def in_width_of(self, seg: 'Segment') -> bool:
		return self.in_side_of(seg) and self.in_side_of(seg.reverse())

	def distance_to_segment(self, seg: 'Segment') -> float:
		if self.in_width_of(seg):
			return self.distance(seg.projection(self))
		else:
			return min(self.distance(seg.p1), self.distance(seg.p2))
Vector = Point

class Segment:

	def __init__(self, p1: Point=None, p2: Point=None) -> None:
		self.p1: Point = Point() if p1 is None else p1
		self.p2: Point = Point() if p2 is None else p2

	def __repr__(self) -> str:
		return 'Segment({}, {})'.format(self.p1, self.p2)

	def __eq__(self, other: object) -> bool:
		if not isinstance(other, Segment):
			return NotImplemented
		return self.p1 == other.p1 and self.p2 == other.p2

	def vector(self) -> Vector:
		return self.p2 - self.p1

	def reverse(self) -> 'Segment':
		return Segment(self.p2, self.p1)

	def is_orthogonal(self, other: 'Segment') -> bool:
		return self.vector().is_orthogonal(other.vector())

	def is_parallel(self, other: 'Segment') -> bool:
		return self.vector().is_parallel(other.vector())

	def projection(self, p: Point) -> Point:
		v = self.vector()
		vp = p - self.p1
		return v.dot(vp) / v.norm() * v + self.p1

	def reflection(self, p: Point) -> Point:
		x = self.projection(p)
		return p + 2 * (x - p)

	def intersect_ratio(self, other: 'Segment') -> Tuple[float, float]:
		a = self.vector()
		b = other.vector()
		c = self.p1 - other.p1
		s = b.cross(c) / a.cross(b)
		t = a.cross(c) / a.cross(b)
		return (s, t)

	def intersects(self, other: 'Segment') -> bool:
		(s, t) = self.intersect_ratio(other)
		return 0 <= s <= 1 and 0 <= t <= 1

	def intersection(self, other: 'Segment') -> Point:
		(s, _) = self.intersect_ratio(other)
		return self.p1 + s * self.vector()

	def distance_with_segment(self, other: 'Segment') -> float:
		if not self.is_parallel(other) and self.intersects(other):
			return 0
		else:
			return min(self.p1.distance_to_segment(other), self.p2.distance_to_segment(other), other.p1.distance_to_segment(self), other.p2.distance_to_segment(self))
Line = Segment

class Circle:

	def __init__(self, c: Point=None, r: float=0.0) -> None:
		self.c: Point = Point() if c is None else c
		self.r: float = r

	def __eq__(self, other: object) -> bool:
		if not isinstance(other, Circle):
			return NotImplemented
		return self.c == other.c and self.r == other.r

	def __repr__(self) -> str:
		return 'Circle({}, {})'.format(self.c, self.r)

def main() -> None:
	n = int(input())
	for _ in range(n):
		(x1, y1, x2, y2, x3, y3, x4, y4) = [int(x) for x in input().split()]
		s1 = Segment(Point(x1, y1), Point(x2, y2))
		s2 = Segment(Point(x3, y3), Point(x4, y4))
		print(s1.distance_with_segment(s2))
main()


from math import sqrt

class Segment:

	def __init__(self, p0, p1):
		self.end_points = (p0, p1)

	def another(self, p):
		if p == self.end_points[0]:
			return self.end_points[1]
		else:
			return self.end_points[0]

	def distance(self, other):

		def _distance(p, seg):
			p0 = seg._closest_point(p)
			p1 = seg.another(p0)
			(x, y) = p
			(x0, y0) = p0
			(x1, y1) = p1
			vp = (x - x0, y - y0)
			vseg = (x1 - x0, y1 - y0)
			if dot(vp, vseg) <= 0:
				return length(vp)
			else:
				(x, y) = vp
				return length(projection(vp, orthogonal(vseg)))
		if self.intersect(other):
			return 0.0
		dists = []
		for p0 in self.end_points:
			dists.append(_distance(p0, other))
		for p1 in other.end_points:
			dists.append(_distance(p1, self))
		return min(dists)

	def intersect(self, other):
		(p0, p1) = self.end_points
		(p2, p3) = other.end_points
		if convex(p0, p2, p1, p3):
			return True
		elif p0 in other or p1 in other or p2 in self or (p3 in self):
			return True
		return False

	def _closest_point(self, p):
		(p0, p1) = self.end_points
		(x, y) = p
		(x0, y0) = p0
		(x1, y1) = p1
		if length((x0 - x, y0 - y)) < length((x1 - x, y1 - y)):
			return p0
		else:
			return p1

	def __contains__(self, p):
		(p0, p1) = self.end_points
		(x0, y0) = p0
		(x1, y1) = p1
		(x, y) = p
		v = (x1 - x0, y1 - y0)
		v0 = (x - x0, y - y0)
		v1 = (x - x1, y - y1)
		if dot(orthogonal(v0), v1) == 0:
			if abs(length(v0) + length(v1) - length(v)) < 1e-10:
				return True
		return False

def dot(v1, v2):
	(x1, y1) = v1
	(x2, y2) = v2
	return x1 * x2 + y1 * y2

def orthogonal(v):
	(x, y) = v
	return (-y, x)

def length(v):
	(x, y) = v
	return sqrt(x ** 2 + y ** 2)

def projection(p, v):
	(x, y) = v
	r = dot(p, v) / dot(v, v)
	return (x * r, y * r)

def convex(p0, p1, p2, p3):
	ret = []
	for (pa, pb, pc) in zip([p0, p1, p2, p3], [p1, p2, p3, p0], [p2, p3, p0, p1]):
		(xa, ya) = pa
		(xb, yb) = pb
		(xc, yc) = pc
		v1 = (xb - xa, yb - ya)
		v2 = (xc - xb, yc - yb)
		ret.append(dot(orthogonal(v1), v2))
	return all([d > 0 for d in ret]) or all([d < 0 for d in ret])

def run():
	q = int(input())
	for _ in range(q):
		(x0, y0, x1, y1, x2, y2, x3, y3) = [int(i) for i in input().split()]
		s0 = Segment((x0, y0), (x1, y1))
		s1 = Segment((x2, y2), (x3, y3))
		print('{:.10f}'.format(s0.distance(s1)))
run()


from itertools import starmap

def cross(a, b):
	return a.real * b.imag - a.imag * b.real

def has_intersection(p0, p1, p2, p3):
	(max_x1, min_x1) = (p0.real, p1.real) if p0.real > p1.real else (p1.real, p0.real)
	(max_x2, min_x2) = (p2.real, p3.real) if p2.real > p3.real else (p3.real, p2.real)
	if max_x1 < min_x2 or max_x2 < min_x1:
		return False
	(max_y1, min_y1) = (p0.imag, p1.imag) if p0.imag > p1.imag else (p1.imag, p0.imag)
	(max_y2, min_y2) = (p2.imag, p3.imag) if p2.imag > p3.imag else (p3.imag, p2.imag)
	if max_y1 < min_y2 or max_y2 < min_y1:
		return False
	return cross(p1 - p0, p2 - p0) * cross(p1 - p0, p3 - p0) < 1e-06 and cross(p3 - p2, p0 - p2) * cross(p3 - p2, p1 - p2) < 1e-06

def point_to_segment(p0, p1, p2):
	prod = (p1 - p0).conjugate() * (p2 - p0)
	if prod.real <= 1e-06:
		return abs(p2 - p0)
	l = abs(p1 - p0)
	d = prod.real / l
	if d >= l:
		return abs(p2 - p1)
	return abs(prod.imag) / l
q = int(input())
while q:
	q -= 1
	(p0, p1, p2, p3) = starmap(complex, zip(*[map(int, input().split())] * 2))
	if has_intersection(p0, p1, p2, p3):
		print(0)
		continue
	print(min(starmap(point_to_segment, ((p0, p1, p2), (p0, p1, p3), (p2, p3, p0), (p2, p3, p1)))))