package main

import (
	"bufio"
	"fmt"
	"math"
	"math/cmplx"
	"os"
	"strconv"
)

func getScanner(fp *os.File) *bufio.Scanner {
	scanner := bufio.NewScanner(fp)
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1000005), 1000005)
	return scanner
}
func getNextString(scanner *bufio.Scanner) string {
	scanner.Scan()
	return scanner.Text()
}
func getNextInt(scanner *bufio.Scanner) int {
	i, _ := strconv.Atoi(getNextString(scanner))
	return i
}
func getNextInt64(scanner *bufio.Scanner) int64 {
	i, _ := strconv.ParseInt(getNextString(scanner), 10, 64)
	return i
}
func getNextUint64(scanner *bufio.Scanner) uint64 {
	i, _ := strconv.ParseUint(getNextString(scanner), 10, 64)
	return i
}
func getNextFloat64(scanner *bufio.Scanner) float64 {
	i, _ := strconv.ParseFloat(getNextString(scanner), 64)
	return i
}
func main() {
	fp := os.Stdin
	wfp := os.Stdout
	cnt := 0
	if os.Getenv("MASPY") == "ますピ" {
		fp, _ = os.Open(os.Getenv("BEET_THE_HARMONY_OF_PERFECT"))
		cnt = 2
	}
	if os.Getenv("MASPYPY") == "ますピッピ" {
		wfp, _ = os.Create(os.Getenv("NGTKANA_IS_GENIUS10"))
	}
	scanner := getScanner(fp)
	writer := bufio.NewWriter(wfp)
	solve(scanner, writer)
	for i := 0; i < cnt; i++ {
		fmt.Fprintln(writer, "-----------------------------------")
		solve(scanner, writer)
	}
	writer.Flush()
}
func solve(scanner *bufio.Scanner, writer *bufio.Writer) {
	q := getNextInt(scanner)
	for i := 0; i < q; i++ {
		xx := make([]float64, 4)
		yy := make([]float64, 4)
		for j := 0; j < 4; j++ {
			xx[j] = getNextFloat64(scanner)
			yy[j] = getNextFloat64(scanner)
		}
		ss := makeGrid(4, 4)
		for j := 0; j < 4; j++ {
			for k := 0; k < 4; k++ {
				ss[j][k] = complex(xx[k]-xx[j], yy[k]-yy[j])
			}
		}

		if compare(imag(ss[0][2]/ss[0][1])*imag(ss[0][3]/ss[0][1]), 0) == -1 && compare(imag(ss[2][0]/ss[2][3])*imag(ss[2][1]/ss[2][3]), 0) == -1 {
			fmt.Fprintln(writer, fmt.Sprintf("%.10f", 0.0))
			continue
		}

		ans := math.MaxFloat64
		_, th := cmplx.Polar(ss[0][1])
		s1 := rotate(ss[0][1], -th)
		s2 := rotate(ss[0][2], -th)
		s3 := rotate(ss[0][3], -th)
		if compare(real(s2), 0) == -1 {
			ans = math.Min(ans, cmplx.Abs(s2))
		} else if compare(real(s2), real(s1)) == 1 {
			ans = math.Min(ans, cmplx.Abs(s2-s1))
		} else {
			ans = math.Min(ans, math.Abs(imag(s2)))
		}
		if compare(real(s3), 0) == -1 {
			ans = math.Min(ans, cmplx.Abs(s3))
		} else if compare(real(s3), real(s1)) == 1 {
			ans = math.Min(ans, cmplx.Abs(s3-s1))
		} else {
			ans = math.Min(ans, math.Abs(imag(s3)))
		}
		_, th = cmplx.Polar(ss[2][3])
		s1 = rotate(ss[2][3], -th)
		s2 = rotate(ss[2][0], -th)
		s3 = rotate(ss[2][1], -th)
		if compare(real(s2), 0) == -1 {
			ans = math.Min(ans, cmplx.Abs(s2))
		} else if compare(real(s2), real(s1)) == 1 {
			ans = math.Min(ans, cmplx.Abs(s2-s1))
		} else {
			ans = math.Min(ans, math.Abs(imag(s2)))
		}
		if compare(real(s3), 0) == -1 {
			ans = math.Min(ans, cmplx.Abs(s3))
		} else if compare(real(s3), real(s1)) == 1 {
			ans = math.Min(ans, cmplx.Abs(s3-s1))
		} else {
			ans = math.Min(ans, math.Abs(imag(s3)))
		}
		fmt.Fprintln(writer, fmt.Sprintf("%.10f", ans))
	}
}
func makeGrid(h, w int) [][]complex128 {
	index := make([][]complex128, h, h)
	data := make([]complex128, h*w, h*w)
	for i := 0; i < h; i++ {
		index[i] = data[i*w : (i+1)*w]
	}
	return index
}
func compare(a, b float64) int {
	eps := 1e-10
	if a-b > eps {
		return 1
	}
	if b-a > eps {
		return -1
	}
	return 0
}
func rotate(v complex128, theta float64) complex128 {
	r, th := cmplx.Polar(v)
	th += theta
	return cmplx.Rect(r, th)
}
func degToRad(deg float64) float64 {
	return deg * math.Pi / 180.0
}
func radTodeg(rad float64) float64 {
	return rad * 180.0 / math.Pi
}



Measured memory_bytes: 1688