#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <cctype>
#include <tuple>
#include <array>
#include <climits>

// BEGIN CUT HERE
#ifdef _MSC_VER
#include <agents.h>
#endif
// END CUT HERE 

#define FOR(i, a, b) for(int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define MP make_pair
#define MT make_tuple

using namespace std;

typedef pair<int, int> P;
typedef long long ll;

struct Dice{
private:
	static const int _roll[4][6], _turn[2][6];
public:
	vector<int> value;
	//enum pos{ top, near, right, left, far, bottom };

	Dice(){
		value.resize(6);
		for (int i = 0; i < 6; ++i) value[i] = i;
	}
	Dice(initializer_list<int> il){
		value.resize(6, -1);
		int cnt = 0;
		for (auto &e : il){
			value[cnt++] = e;
			if (cnt >= 6) break;
		}
		for (int i = 0; i < 6; ++i) if (value[i] < 0) value[i] = 5 - value[5 - i];
	}

	int top()const{ return value[0]; }
	int near()const{ return value[1]; }
	int right()const{ return value[2]; }
	int left()const{ return value[3]; }
	int far()const{ return value[4]; }
	int bottom()const{ return value[5]; }

	void roll(int dir){ // N, E, W, S
		vector<int> nxt(6);
		for (int i = 0; i < 6; ++i){
			nxt[i] = value[_roll[dir][i]];
		}
		value = nxt;
	}

	void turn(int dir){ // L, R
		vector<int> nxt(6);
		for (int i = 0; i < 6; ++i){
			nxt[i] = value[_turn[dir][i]];
		}
		value = nxt;
	}

	int &operator[](int i){
		return value[i];
	}
	bool operator < (const Dice &rhs) const{
		return value < rhs.value;
	}
};

ostream& operator<<(ostream& os, const Dice &d){
	os << '{';
	for (int i = 0; i < (int)d.value.size(); ++i) os << (i ? ", " : "") << d.value[i];
	os << '}';
	return os;
}


const int Dice::_roll[4][6] = {
	{ 1, 5, 2, 3, 0, 4 }, // North
	{ 3, 1, 0, 5, 4, 2 }, // East
	{ 2, 1, 5, 0, 4, 3 }, // West
	{ 4, 0, 2, 3, 5, 1 }, // South
};

const int Dice::_turn[2][6] = {
	{ 0, 3, 1, 4, 2, 5 }, // Left
	{ 0, 2, 4, 1, 3, 5 }, // Right
};

set<Dice> valid_set;

void make_valid_set(){
	rep(k, 3) rep(i, 4){
		Dice d;
		rep(j, k) d.roll(i);
		rep(j, 4){
			d.turn(0);
			valid_set.insert(d);
		}
	}
}

map<vector<int>, vector<vector<int>>> m;

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);

	make_valid_set();

	vector<vector<Dice>> top(6), left(6);
	vector<vector<vector<Dice>>> left_top(6, vector<vector<Dice>>(6));
	for (auto d : valid_set){
		top[d.top()].push_back(d);
		left[d.left()].push_back(d);
		left_top[d.left()][d.top()].push_back(d);
	}

	for (auto &d0 : valid_set){
		/*
		0 1 2
		3 x x
		4 x x
		*/
		for (auto &d1 : left[d0.left()]){
			for (auto &d2 : left[d0.left()]){
				for (auto &d3 : top[d0.top()]){
					for (auto &d4 : top[d0.top()]){
						// 5-8
						if (left_top[d3.left()][d1.top()].empty()) continue;
						auto &d5 = left_top[d3.left()][d1.top()][0];
						if (left_top[d3.left()][d2.top()].empty()) continue;
						auto &d6 = left_top[d3.left()][d2.top()][0];
						if (left_top[d4.left()][d1.top()].empty()) continue;
						auto &d7 = left_top[d4.left()][d1.top()][0];
						if (left_top[d4.left()][d2.top()].empty()) continue;
						auto &d8 = left_top[d4.left()][d2.top()][0];

						vector<int> tmp = { d0.near(), d1.near(), d2.near(), d3.near(), d4.near(), d5.near(), d6.near(), d7.near(), d8.near() };
						auto &con = m[tmp];
						con.push_back({ d2.top(), d1.top(), d0.top(), d0.left(), d3.left(), d4.left() });
					}
				}
			}
		}
	}

	int n;
	cin >> n;
	while (n--){
		vector<vector<int>> tl(3, vector<int>(6));
		rep(i, 6) rep(j, 3) cin >> tl[2 - j][i];
		rep(i, 6) rep(j, 3) --tl[2 - j][i];

		set<int> ans;
		for (auto &x : m){
			auto &v = x.second;
			for (auto &a : v){
				rep(i, 6) if (tl[0][i] >= 0 && tl[0][i] != a[i]) goto NGA;
				for (auto &b : v){
					rep(i, 6) if (tl[1][i] >= 0 && tl[1][i] != b[i]) goto NGB;
					for (auto &c : v){
						rep(i, 6) if (tl[2][i] >= 0 && tl[2][i] != c[i]) goto NGC;
						goto OK;
					NGC:;
					}
				NGB:;
				}
			NGA:;
			}
			continue;
		OK:
			ans.insert(accumulate(ALL(x.first), 0) + 9);
		}

		bool f = true;
		for (auto a : ans){
			cout << (f ? "" : " ") << a;
			f = false;
		}
		if (ans.empty()) cout << 0;
		cout << endl;
	}

	return 0;
}

Measured memory_bytes: 1584