#include <cstdio>
#include <algorithm>
#include <cassert>
#include <queue>
#include <cstring>
using namespace std;

struct Board {
	char state[4][8];
	Board(){}
};

bool operator< (const Board& lhs, const Board& rhs) {
	return memcmp(&lhs.state, &rhs.state, sizeof(lhs.state)) < 0;
}


typedef pair<int, Board> heap_t;
typedef unsigned long long hash_t;
//typedef Board key_t;
#define key_t Board
typedef int value_t;

struct HashMap {
	static const int TABLE_SIZE = 1<<18;
	hash_t hashes[TABLE_SIZE];
	value_t values[TABLE_SIZE];

	HashMap()
	{
		memset(hashes, ~0, sizeof(hashes));
	}

	void clear() {
		memset(hashes, ~0, sizeof(hashes));
	}

	inline hash_t hasher(const key_t &x) const {
		hash_t ret = 0;
		for (int i = 0; i < 4; ++i) {
			//ret = ret * 1000007ULL + ((hash_t*)x.state[i])[0];
			for (int j = 0; j < 8; ++j) {
				ret = ret * 10000007ULL + hash_t(x.state[i][j] + 1);
			}
		}
		if (ret == ~0ULL) {
			ret = 538;
		}
		return ret;
	}

	void set (const key_t &x, const value_t &v) {
		const hash_t hash = hasher(x);
		int sub = hash % TABLE_SIZE;
		
		for (;hashes[sub] != hash && ~hashes[sub]; sub = (sub + 1 == TABLE_SIZE ? 0 : sub + 1)) ;
		hashes[sub] = hash;
		values[sub] = v;
	}

	value_t get (const key_t &x) const {
		const hash_t hash = hasher(x);
		int sub = hash % TABLE_SIZE;
		
		for (;hashes[sub] != hash && ~hashes[sub]; sub = (sub + 1 == TABLE_SIZE ? 0 : sub + 1)) ;
		return values[sub];
	}


	bool containKey(const key_t &x) const {
		const hash_t hash = hasher(x);
		int sub = hash % TABLE_SIZE;
		
		for (;hashes[sub] != hash && ~hashes[sub]; sub = (sub + 1 == TABLE_SIZE ? 0 : sub + 1)) ;
		return hashes[sub] == hash;
	}
};



int board[4][8];

void init() {
	memset(board, 0, sizeof(board));
	for (int i = 0; i < 4; ++i) {
		for (int j = 0; j < 7; ++j) {
			scanf("%d", board[i]+j+1);
		}
	}
}

int estimateBoard(const Board& x) {
	int ans = 0;
	for (int i = 0; i < 4; ++i) {
		for (int j = 0; j < 8; ++j) if (x.state[i][j] != -1) {
			if (!((x.state[i][j]>>3) == i && (x.state[i][j]&7) == j)) {
				++ans;
			}
		}
	}
	return ans ? 1 : 0;
}



int solve() {
	static HashMap estimate;
	estimate.clear();
	queue<heap_t> que;
	//initHeap();

	Board start;
	memset(&start.state, ~0, 4*8);
	for (int i = 0; i < 4; ++i) {
		for (int j = 1; j < 8; ++j) {
			if (board[i][j]) {
				start.state[i][j] = ((board[i][j]/10 - 1)<<3) | (board[i][j]%10 - 1);
			}
			if ((start.state[i][j]&7) == 0) {
				swap(start.state[start.state[i][j]>>3][0], start.state[i][j]);
			}
		}
	}
	estimate.set(start, estimateBoard(start));
	que.push(make_pair(estimate.get(start), start));


	for (;!que.empty();) {
		int dist = que.front().first;
		Board cur = que.front().second;
		que.pop();

		int esti = estimate.get(cur);
		if (esti == 0) {
			return dist;
		}
		dist -= esti;

		for (int i = 0; i < 4; ++i) {
			for (int j = 1; j < 8; ++j) if (cur.state[i][j] == -1) {
				char left = cur.state[i][j-1] + 1;
				for (int ii = 0; ii < 4; ++ii) {
					for (int jj = 1; jj < 8; ++jj) if (cur.state[ii][jj] == left) {
						swap(cur.state[ii][jj], cur.state[i][j]);
						if (!estimate.containKey(cur)) {
							const int add = estimateBoard(cur);
							estimate.set(cur, add);
							int nd = dist + 1 + add;
							que.push(make_pair(nd, cur));
						}
						swap(cur.state[ii][jj], cur.state[i][j]);
					}
				}
			}
		}
	}

	return -1;
}

int main() {
	int T; scanf("%d", &T);
	for (int _ = 0; _ < T; ++_) {
		init();
		printf("%d\n", solve());
	}
	return 0;
}

Measured memory_bytes: 4232