// Arup Guha
// 8/3/2013
// Solution to 2012 East Central North America Regional Problem I: Town Square
import java.util.*;

public class i {

	public static pt[] statues;
	public static int minIndex;
	public static int maxIndex;
	public static int midIndex;

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);
		int numCases = stdin.nextInt();

		// Go through each case.
		for (int loop=1; loop<=numCases; loop++) {

			// Read in statues and sort by x.
			statues = new pt[4];
			for (int i=0; i<4; i++) {
				int x = stdin.nextInt();
				int y = stdin.nextInt();
				statues[i] = new pt(x,y);
			}
			Arrays.sort(statues);

			// Get rid of this case.
			if (threeCollinear())
				System.out.println("Case "+loop+": no solution");
			else {

				// Find the point diametrically opposite statues[0].
				getOppositeIndex();

				// Output solution.
				if (midIndex == -1)
					System.out.println("Case "+loop+": no solution");
				else {
					double ans = solve();
					if (ans > 0)
						System.out.printf("Case %d: %.2f\n", loop, ans);
					else
						System.out.println("Case "+loop+": no solution");
				}
			}
		}
	}

	// Brute force check of collinearity.
	public static boolean threeCollinear() {

		for (int i=0; i<4; i++)
			for (int j=i+1; j<4; j++)
				for (int k=j+1; k<4; k++)
					if (Math.abs(statues[i].refAngle(statues[j]) - statues[i].refAngle(statues[k])) < .00001)
						return true;
		return false;
	}


	// Allows us to determine which pairs of vertices are opposite one another. statues[0] has the minimum x value.
	// statues[midIndex] will be diametrically opposite statues[0], while statues[minIndex] will have a lower reference
	// angle from statues[0] than statues[maxIndex]. These last two will also be opposite corners of the quadrilateral.
	public static void getOppositeIndex() {

		double[] angles = new double[4];
		for (int i=1; i<4; i++)
			angles[i] = statues[0].refAngle(statues[i]);

		// This is annoying get min and max index.
		minIndex=1;
		maxIndex=1;
		for (int i=2; i<4; i++)
			if (angles[i] < angles[minIndex])
				minIndex = i;
		for (int i=2; i<4; i++)
			if (angles[i] > angles[maxIndex])
				maxIndex = i;

		// Extract out middle index.
		midIndex = 6 - minIndex - maxIndex;

		vect v1 = new vect(statues[midIndex], statues[minIndex]);
		vect v2 = new vect(statues[midIndex], statues[maxIndex]);
		vect v3 = new vect(statues[midIndex], statues[0]);
		double sumAngles = v1.getAngle(v2) + v2.getAngle(v3) + v3.getAngle(v1);

		// Tests to see if the middle point is inside the triangle formed by pts 0, minIndex and maxIndex.
		if (sumAngles >= 2*Math.PI-1e-10)
			midIndex = -1;
	}

	// Necessary to properly sort angles.
	public static double map(double angle) {
		if (angle < 0) angle += 2*Math.PI;
		return angle;
	}

 	public static double solve() {

		// Diagonal distances.
		double d1 = statues[0].dist(statues[midIndex]);
		double d2 = statues[maxIndex].dist(statues[minIndex]);

		// Angles from statues[0] where s1 and s2 achieve their maximum value. Both functions, for s1 and s2
		// have one max in the domain.
		double s1max = getHeading(0, midIndex) + Math.PI/2;
		double s2max = getHeading(minIndex, maxIndex);

		// Bounding of the angle from statues[0] of the supposed square since this line can't cross over other vertices. Bounded by
		// the points at minIndex and maxIndex, as well as the bounding of the top and bottom points.
		double minAngle = max(getHeading(minIndex, midIndex), getHeading(0, maxIndex), Math.PI/2+getHeading(maxIndex, midIndex), Math.PI/2+getHeading(0, minIndex) ) + 1e-10;
		double maxAngle = min(map(getHeading(minIndex, 0)), map(getHeading(midIndex, maxIndex)), map(getHeading(0, maxIndex)) + Math.PI/2, map(getHeading(minIndex, midIndex)) + Math.PI/2) - 1e-10;

		// Weird special case...if these are so close, pts must be collinear in any solution, which isn't allowed.
		if (minAngle > maxAngle) return -1;

		// Make a list of all special points.
		ArrayList<Double> pts = new ArrayList<Double>();
		pts.add(minAngle);
		pts.add(maxAngle);
		if (s1max >= minAngle && s1max <= maxAngle)
			pts.add(s1max);
		if (s2max >= minAngle && s2max <= maxAngle)
			pts.add(s2max);
		Collections.sort(pts);

		// If there's a solution, we can binary search in these gaps.
		double best = -1;
		for (int i=0; i<pts.size()-1; i++) {
			double temp = binSearch(pts.get(i), pts.get(i+1));
			if (temp > best)
				best = temp;
		}
		return best;

 	}

	// Does a binary search of angles in between low and high from statues[0] for the line of the square through that statue.
 	public static double binSearch(double low, double high) {

		// Calculate which side is longer at both angles low and high.
		double start = getDist(statues[0], low, statues[midIndex]) - getDist(statues[minIndex], low+Math.PI/2, statues[maxIndex]);
		double end = getDist(statues[0], high, statues[midIndex]) - getDist(statues[minIndex], high+Math.PI/2, statues[maxIndex]);

		// This means there's no solution in this interval.
		if (start > 0 && end > 0) return -1;
		if (start < 0 && end < 0) return -1;

		// Typical binary searhc.
		while (high - low > 1e-11) {

			// Try these distances.
			double mid = (low+high)/2;
			double s1 = getDist(statues[0], mid, statues[midIndex]);
			double s2 = getDist(statues[minIndex], mid+Math.PI/2, statues[maxIndex]);

			// Here is how we reassign low or high...
			if ((start < 0 && s1 < s2) || (start > 0 && s1 > s2))
				low = mid;
			else
				high = mid;
		}

		double best = -1;
		double s1 = getDist(statues[0], (low+high)/2, statues[midIndex]);
		double s2 = getDist(statues[minIndex], (low+high)/2+Math.PI/2, statues[maxIndex]);

		// Double check our result to make sure it works.
		if (Math.abs(s1-s2) < .000000001 && s1+10 > best)
			best = s1+10;

		return best;
 	}

 	// Returns the distance from the line defined by start and angle from other.
 	public static double getDist(pt start, double angle, pt other) {
 		vect dir = new vect(Math.cos(angle), Math.sin(angle));
		vect toOther = new vect(start, other);
		double vectangle = dir.getAngle(toOther);
		return start.dist(other)*Math.sin(vectangle);
 	}

	// Returns the heading from statue i to statue j.
 	public static double getHeading(int i, int j) {
 		return statues[i].refAngle(statues[j]);
 	}

	// Returns the min of these four values.
 	public static double min(double a, double b, double c, double d) {
 		if (a < b && a < c && a < d) return a;
 		if (b < c && b < d) return b;
 		if (c < d) return c;
 		return d;
 	}

	// Returns the max of these four values.
  	public static double max(double a, double b, double c, double d) {
 		if (a > b && a > c && a > d) return a;
 		if (b > c && b > d) return b;
 		if (c > d) return c;
 		return d;
 	}
}

// A simple point class
class pt implements Comparable<pt> {

	public double x;
	public double y;

	public pt(double myx, double myy) {
		x = myx;
		y = myy;
	}

	public int compareTo(pt other) {
		if (this.x < other.x-1e-10) return -1;
		else if (this.x > other.x+1e-10) return 1;
		else if (this.y < other.y-1e-10) return -1;
		else if (this.y > other.y+1e-10) return 1;
		return 0;
	}

	public double refAngle(pt dest) {
		return Math.atan2(dest.y-this.y, dest.x-this.x);
	}

	public double dist(pt other) {
		return Math.sqrt(Math.pow(other.x-this.x,2) + Math.pow(other.y-this.y,2));
	}
}

// A simple vector class
class vect {

	public double x;
	public double y;

	public vect(pt start, pt end) {
		x = end.x - start.x;
		y = end.y - start.y;
	}

	public vect(double myx, double myy) {
		x = myx;
		y = myy;
	}

	public double getAngle(vect other) {
		return Math.acos((this.x*other.x + this.y*other.y)/this.mag()/other.mag());
	}

	public double mag() {
		return Math.sqrt(x*x+y*y);
	}
}