Problem:
Nets of Dice

In mathematics, some plain words have special meanings.
The word "net" is one of such technical terms.
In mathematics, the word "net" is sometimes used to
mean a plane shape
which can be folded into some solid shape.

The following are a solid shape (Figure 1) and one of its net (Figure 2).

Figure 1: a prism

Figure 2: a net of a prism

Nets corresponding to a solid shape are not unique.
For example, Figure 3 shows three of the nets of a cube.

Figure 3: examples of nets of a cube

In this problem, we consider nets of dice.
The definition of a die is as follows.

A die is a cube, each face marked with a number between one and six.

Numbers on faces of a die are different from each other.

The sum of two numbers on the opposite faces is always 7.

Usually, a die is used in pair with another die.
The plural form of the word "die" is "dice".

Some examples of proper nets of dice are shown in Figure 4,
and those of improper ones are shown in Figure 5.

Figure 4: examples of proper nets of dice

Figure 5: examples of improper nets

The reasons why each example in Figure 5 is improper are as follows.

(a) The sum of two numbers on the opposite faces is not always 7.

(b) Some faces are marked with the same number.

(c) This is not a net of a cube. Some faces overlap each other.

(d) This is not a net of a cube.
Some faces overlap each other and one face of a cube is not covered.

(e) This is not a net of a cube.
The plane shape is cut off into two parts.
The face marked with '2' is isolated.

(f) This is not a net of a cube.
The plane shape is cut off into two parts.

(g) There is an extra face marked with '5'.

Notice that there are two kinds of dice.
For example, the solid shapes formed from
the first two examples in Figure 4
are mirror images of each other.

Any net of a die can be expressed on a sheet of 5x5 mesh like the one in Figure 6.
In the figure, gray squares are the parts to be cut off.
When we represent the sheet of mesh by numbers as in Figure 7,
squares cut off are marked with zeros.

Figure 6: 5x5 mesh

Figure 7: representation by numbers

Your job is to write a program which tells
the proper nets of a die from the improper ones automatically.

Input

The input consists of multiple sheets of 5x5 mesh.

N

Mesh0

Mesh1

...

MeshN-1

N is the number of sheets of mesh.
Each Meshi gives a sheet of mesh
on which a net of a die is expressed.
Meshi is in the following format.

F00

F01

F02

F03

F04

F10

F11

F12

F13

F14

F20

F21

F22

F23

F24

F30

F31

F32

F33

F34

F40

F41

F42

F43

F44

Each Fij is an integer between 0 and 6.
They are separated by a space character.

Output

For each Meshi,
the truth value, true or false,
should be output, each in a separate line.
When the net of a die expressed on the Meshi is proper,
output "true".
Otherwise, output "false".

Sample Input

6
0 0 0 0 0
0 0 0 0 6
0 2 4 5 3
0 0 1 0 0
0 0 0 0 0
0 0 3 0 0
0 0 2 0 0
0 0 4 1 0
0 0 0 5 0
0 0 0 6 0
0 0 0 3 0
0 0 2 5 0
0 4 1 0 0
0 0 6 0 0
0 0 0 0 0
0 6 2 0 0
0 0 4 0 0
0 1 5 0 0
0 0 3 0 0
0 0 0 0 0
0 0 0 0 6
0 2 4 5 3
0 0 1 0 0
0 0 0 0 0
0 0 0 1 0
0 0 0 0 6
0 2 4 5 3
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0

Output for the Sample Input

true
true
false
false
false
false

Solution in JAVA (judge verdict: Accepted)

import java.util.*;

public class Main{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();

		while(n-- > 0){
			t = new int[5][5];
			int m = 0;
			boolean[] used = new boolean[7];
			boolean trueFlg = true;

			for(int i=0;i<5;i++){
				for(int j=0;j<5;j++){
					t[i][j] = sc.nextInt();

					//ツ督ッツつカツ青板篠堋つェツ出ツづつォツづづ按つ「ツつゥツづ個確ツ認
					if(t[i][j] != 0){
						if(!used[t[i][j]]){
							m++;
							used[t[i][j]] = true;
						}
						else{
							trueFlg = false;
						}
					}
				}
			}
			if(m != 6) trueFlg = false;

			//ツサツイツコツδ債づ青ャツ猟ァツつオツづつ「ツづゥツつゥツづ個確ツ認
			if(trueFlg){
				int sy=-1,sx=-1;
				for(sy=0;sy<5;sy++){
					for(sx=0;sx<5;sx++) if(t[sy][sx] != 0) break;
					if(sx != 5) break;
				}

				Dice d = new Dice(0,0,0,0,0,0);
				makeDice(d,sx,sy);
				trueFlg = d.isDice();
			}

			System.out.println(trueFlg ? "true" : "false");
		}
	}

	private static int[][] t;
	private static int dx[] = {0,1,0,-1};
	private static int dy[] = {-1,0,1,0};

	private static void makeDice(Dice d,int x,int y){
		d.b = t[y][x];
		t[y][x] = 0;

		for(int i=0;i<4;i++){
			int nx = x + dx[i];
			int ny = y + dy[i];
			if(nx>=0 && nx<5 && ny>=0 && ny<5 && t[ny][nx]>0){
				d.move(i);
				makeDice(d,nx,ny);
				d.move((i+2)%4);
			}
		}
	}
}

class Dice{
	int t,b,w,e,n,s;

	Dice(int t,int b,int w,int e,int n,int s){
		this.t = t;
		this.b = b;
		this.w = w;
		this.e = e;
		this.n = n;
		this.s = s;
	}

	boolean isDice(){
		return t+b==7 && w+e==7 && n+s==7;
	}

	void move(int dir){
		Dice d = this.copy();
			
		switch(dir){
		case 0:
			t = d.s;
			b = d.n;
			n = d.t;
			s = d.b;
			break;
		case 1:
			t = d.w;
			b = d.e;
			w = d.b;
			e = d.t;
			break;
		case 2:
			t = d.n;
			b = d.s;
			n = d.b;
			s = d.t;
			break;
		case 3:
			t = d.e;
			b = d.w;
			w = d.t;
			e = d.b;
			break;
		}
	}

	Dice copy(){
		return new Dice(t,b,w,e,n,s);
	}
}