// Arup Guha
// 10/11/2016
// Solution to 2016 NAQ problem L: Unusual Darts

import java.util.*;

public class unusualdarts {

	public static pt[] alice;
	public static double probBob;
	public static int[] bestperm;
	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);
		int numCases = stdin.nextInt();

		// Process each case.
		for (int loop=0; loop<numCases; loop++) {

			// Get input.
			alice = new pt[7];
			for (int i=0; i<7; i++) {
				double x = stdin.nextDouble();
				double y = stdin.nextDouble();
				alice[i] = new pt(x,y);
			}
			probBob = stdin.nextDouble();

			// Set up recursion.
			boolean[] used = new boolean[7];
			int[] perm = new int[7];
			bestperm = new int[7];
			go(used, perm, 0);

			// Output result.
			for (int i=0; i<6; i++)
				System.out.print((bestperm[i]+1)+" ");
			System.out.println(bestperm[6]+1);
		}
	}

	public static boolean go(boolean[] used, int[] perm, int k) {

		// Filled in a permutation, evaluate it.
		if (k == used.length) {
			
			// Not a simple polygon.
			if (!simple(perm)) return false;
			
			// Area/4 is Bob's chance of landing a dart in poly, just cube this...
			if ( Math.abs(Math.pow(area(perm)/4.0, 3) - probBob) < 1e-5)  {
				for (int i=0; i<perm.length; i++)
					bestperm[i] = perm[i];
				return true;
			}
			return false;
		}

		// Try filling slot k.
		for (int i=0; i<used.length; i++) {
			if (!used[i]) {
				used[i] = true;
				perm[k] = i;
				boolean res = go(used, perm, k+1);
				if (res) return true;
				used[i] = false;
			}
		}

		return false;
	}

	public static double area(int[] perm) {
		double res = 0;
		int n = perm.length;
		for (int i=0; i<n; i++)
			res += (alice[perm[i]].x*alice[perm[(i+1)%n]].y - alice[perm[i]].y*alice[perm[(i+1)%n]].x);
		return Math.abs(res/2.0);
	}

	public static boolean simple(int[] perm) {

		// Create the line segments.
		int n = perm.length;
		seg[] lines = new seg[n-1];
		for (int i=0; i<n-1; i++)
			lines[i] = new seg(alice[perm[i]], alice[perm[i+1]]);

		// See if previous ones intersect the current one...
		for (int i=2; i<lines.length; i++)
			for (int j=0; j<i-1; j++)
				if (lines[i].intersect(lines[j]))
					return false;

		// Now check with last segment.
		seg last = new seg(alice[perm[n-1]], alice[perm[0]]);
		for (int i=1; i<lines.length-1; i++)
			if (last.intersect(lines[i]))
				return false;

		return true;
	}
}

class pt {

	public double x;
	public double y;

	public pt(double myx, double myy) {
		x = myx;
		y = myy;
	}

	public pt getVector(pt other) {
		return new pt(other.x-x, other.y-y);
	}

	public double crossMag(pt other) {
		return x*other.y - other.x*y;
	}
}

class seg {

	final public static double EPSILON = 1e-9;
	public pt start;
	public pt end;
	public pt dir;

	public seg(pt s, pt e) {
		start = s;
		end = e;
		dir = start.getVector(end);
	}

	// Returns true iff other intersects this.
	public boolean intersect(seg other) {

		// Denominator for system of equations set up for line intersection.
		double den = det(dir.x, -other.dir.x, dir.y, -other.dir.y);

		// Parallel lines case.
		if (Math.abs(den) < 1e-9) {

			// Check for case where lines are NOT coincidental.
			pt vect = start.getVector(other.start);
			if (vect.crossMag(dir) != 0) return false;

			// Coincidental lines, so we must see if the segments overlap at all.
			double lambda1 = getLambda(other.start);
			double lambda2 = getLambda(other.end);
			return !((lambda1 > 1 && lambda2 > 1) || (lambda1 < 0 && lambda2 < 0));
		}

		// Typical case.
		double num1 = det(other.start.x-start.x, -other.dir.x, other.start.y-start.y, -other.dir.y);
		double num2 = det(dir.x, other.start.x-start.x, dir.y, other.start.y-start.y);

		// Segments intersect iff both lambda values are in between 0 and 1.
		return -EPSILON <= num1/den && num1/den <= 1+EPSILON && -EPSILON <= num2/den && num2/den <= 1+EPSILON;
	}

	public static double det(double a, double b, double c, double d) {
		return a*d - b*c;
	}

	// dest must be on this segment.
	public double getLambda(pt dest) {

		// Make sure we don't divide by 0.
		if (dir.x != 0)
			return 1.0*(dest.x - start.x)/dir.x;

		// Use only if dx is 0...we assume no directional vector is 0.
		else
			return 1.0*(dest.y - start.y)/dir.y;
	}
}