#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

bool dfs (const int shapes[][6], int config[][6], vector<bool>& used, vector<int>& mapping, int chosen, int depth);

int main() {
	
	int T;
	cin >> T;
	for (int i=1; i<=T; i++) {
		int shapes[7][6]; //holds the pieces in clockwise order!
		for (int k=0; k<7; k++) {
			//each shapes[i] holds some permutation of [1,2,3,4,5,6]
			for (int pos=0; pos<6; pos++) {
				cin >> shapes[k][pos];
			}
		}

		//DFS specific states: 
		int configs[7][6];
		vector<bool> used(7, false); //shape i has been used in our arrangement
		vector<int> mapping;

		for (int k=0; k<7; k++) {
			int chosen = k;
			used[chosen] = true;
			mapping.push_back(chosen);

			//initialize FIRST config (manually check => indexing slightly differs)
			int j;
			for (j=0; j<6 && shapes[chosen][j]!=1; j++) {
				//j finds first occuring 1, make this "start"
			}
			for (int x=0; x<6; x++)
				configs[0][x] = shapes[chosen][(j+x)%6]; //circular check
			//rotate NEXT config to match
			for (int next=0; next<7; next++) {
				if (!used[next]) {
					int p;
					for (p=0; p<6 && shapes[next][p]!=1; p++); //p is first occuring 1
					//the "matched" 1 goes at base!
					for (int m=0; m<6; m++)
						configs[1][(3+m)%6] = shapes[next][(p+m)%6];

					if (dfs(shapes, configs, used, mapping, next, 1)) { //first call is special
						cout << "Case " << i << ": ";
						for (int shape: mapping)
							cout << shape << " ";
						cout << endl;
						goto testcase;
					}
				}
			}
			/*cout << "Tried Config: ";
			for (int shapenum: mapping)
				cout << shapenum << " ";
			cout << endl;*/
			used[chosen] = false;
			mapping.pop_back();
		}
		cout << "Case " << i << ": No solution" << endl;
	testcase: ;
	}	
}


bool dfs (const int shapes[][6], int config[][6], vector<bool>& used, vector<int>& mapping, int chosen, int depth) {
	used[chosen] = true;
	mapping.push_back(chosen);	
	//check config:	
	if (config[depth][(depth+2)%6] != config[0][(depth+5)%6]) {
		//Config NOT OK: Conflicts with 0!
		used[chosen] = false;

		/*cout << "Tried Config: ";
		for (int shapenum: mapping)
			cout << shapenum << " ";
		cout << endl;*/
		mapping.pop_back();
		return false;
	}
	if (depth==6 && config[depth][1]!=config[1][4]) {
		//Config NOT OK: additional check with 1 on last run
		used[chosen] = false;

		/*cout << "Tried Config: ";
		for (int shapenum: mapping)
			cout << shapenum << " ";
		cout << endl;*/
		mapping.pop_back();
		return false;
	}
	
	if (depth == 6) return true;

	//rotate a NEXT config and match
	for (int next=0; next<7; next++) {
		if (!used[next]) {
			int p;
			for (p=0; p<6 && shapes[next][p]!=config[depth][(depth+1)%6]; p++); //finds first occuring
			for (int m=0; m<6; m++)
				config[depth+1][(((depth+1)+3)+m)%6] = shapes[next][(p+m)%6];
			if (dfs(shapes, config, used, mapping, next, depth+1))
				return true;
		}
	}
	used[chosen] = false;
	/*cout << "Tried Config: ";
		for (int shapenum: mapping)
			cout << shapenum << " ";
		cout << endl;*/
	mapping.pop_back();
	return false;
}