// Arup Guha
// 1/28/2020
// Token Game

import java.util.*;

public class tokengame {
	
	public static int[] DX = {-1,0,0,1};
	public static int[] DY = {0,-1,1,0};
	
	public static int[] start;
	public static int[] end;

	public static void main(String[] args) {
	
		Scanner stdin = new Scanner(System.in);
		int nC = stdin.nextInt();
		
		// Process each case.
		for (int loop=0; loop<nC; loop++) {
		
			start = new int[4];
			end = new int[4];
			
			// Read in starting and ending locations of tokens.
			for (int i=0; i<4; i++) {
			
				int sX = stdin.nextInt()-1;
				int sY = stdin.nextInt()-1;
				int eX = stdin.nextInt()-1;
				int eY = stdin.nextInt()-1;
				start[i] = 4*sX+sY;
				end[i] = 4*eX+eY;
			}
		
			// Ta da!
			System.out.println(go());
		}
	}
	
	public static int go() {
		
		// Figure out where we are starting from and where we want to go (stored as a single integer)
		int startMask = getMask(start);
		int endMask = getMask(end);
		
		// Set up BFS.
		int[] dist = new int[1<<16];
		Arrays.fill(dist, -1);
		dist[startMask] = 0;
		ArrayDeque<Integer> q = new ArrayDeque<Integer>();
		q.offer(startMask);
		
		// Run BFS.
		while (q.size() > 0) {
			
			// Get the next item out of the queue.
			int cur = q.pollFirst();
			
			// Ta da, we are done.
			if (cur == endMask) return dist[cur];
			
			// See all the board positions I can get to in 1 move.
			ArrayList<Integer> next = getNext(cur);
			
			// Enqueue all new states and mark their distance also.
			for (Integer x: next) {
				if (dist[x] == -1) {
					dist[x] = dist[cur]+1;
					q.offer(x);
				}
			}
			
		}
		
		// Never finished.
		return -1;
	}
	
	// Returns a list of all possible states we can move to from cur.
	public static ArrayList<Integer> getNext(int cur) {
		
		// Get where we are.
		int[] curLocs = getLocs(cur);
		
		// Store all possible next states here.
		ArrayList<Integer> res = new ArrayList<Integer>();
		
		// We try to move token i.
		for (int i=0; i<4; i++) {
			
			// We never move tokens who have arrived at their end spot.
			if (curLocs[i] == end[i]) continue;

			// Isolate current x,y by looking at either first two or last two bits.
			int curX = (curLocs[i]>>2);
			int curY = (curLocs[i]&3);
				
			// Try moving this token in all four directions.
			for (int dir=0; dir<4; dir++) {
				
				// Where we would go.
				int nX = curX + DX[dir];
				int nY = curY + DY[dir];
				int nCode = 4*nX+nY;
				
				// Can't go out of bounds.
				if (!inbounds(nX, nY)) continue;
				
				// Can't move onto another token, or to another token's ending spot.
				if (in(nCode, curLocs, i) || in(nCode, end, i)) continue;
				
				// We now form the new mask - take old mask, subtract out effect of old piece, add
				// in effect of new piece.
				int newMask = cur - (curLocs[i] << (4*i)) + (nCode << (4*i));
				
				// Add this to our list of potential new states.
				res.add(newMask);
			}
		}
		
		return res;
	}
	
	public static boolean in(int item, int[] arr, int except) {
		
		// Just see if anything in arr except arr[except] equals item.
		for (int i=0; i<arr.length; i++) {
			if (i == except) continue;
			if (item == arr[i]) return true;
		}
		
		// If we get here the answer is no.
		return false;
	}
	
	// Returns the four locations encoded by curMask.
	public static int[] getLocs(int curMask) {
		
		int[] res = new int[4];
		
		// Go through each location.
		for (int i=0; i<4; i++) {
			
			// Bitwise and with 15 to isolate last four bits.
			res[i] = (curMask & 15);
			
			// Get rid of the last four bits and move in the next four into place.
			curMask = curMask >> 4;
		}
		
		// Ta da!
		return res;
	}
	
	public static boolean inbounds(int x, int y) {
		return x >=0 && x < 4 && y >= 0 && y < 4;
	}
	
	public static int getMask(int[] locs) {
		int res = 0;
		for (int i=0; i<4; i++)
			res += (locs[i]<<(4*i));
		return res;
	}

}