Problem: Have you ever heard of Moduic Squares? They are like 3 × 3 Magic Squares, but each of them has one extra cell called a moduic cell. Hence a Moduic Square has the following form.

<image>

Figure 1: A Moduic Square

Each of cells labeled from A to J contains one number from 1 to 10, where no two cells contain the same number. The sums of three numbers in the same rows, in the same columns, and in the diagonals in the 3 × 3 cells must be congruent modulo the number in the moduic cell. Here is an example Moduic Square:

<image>

Figure 2: An example Moduic Square

You can easily see that all the sums are congruent to 0 modulo 5.

Now, we can consider interesting puzzles in which we complete Moduic Squares with partially filled cells. For example, we can complete the following square by filling 4 into the empty cell on the left and 9 on the right. Alternatively, we can also complete the square by filling 9 on the left and 4 on the right. So this puzzle has two possible solutions.

<image>

Figure 3: A Moduic Square as a puzzle

Your task is to write a program that determines the number of solutions for each given puzzle.



Input

The input contains multiple test cases. Each test case is specified on a single line made of 10 integers that represent cells A, B, C, D, E, F, G, H, I, and J as shown in the first figure of the problem statement. Positive integer means that the corresponding cell is already filled with the integer. Zero means that the corresponding cell is left empty.

The end of input is identified with a line containing ten of -1’s. This is not part of test cases.

Output

For each test case, output a single integer indicating the number of solutions on a line. There may be cases with no solutions, in which you should output 0 as the number.

Example

Input

3 1 6 8 10 7 0 0 2 5
0 0 0 0 0 0 0 0 0 1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1


Output

2
362880

Solution (in CPP):

Solution:
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info{
	int table[3][3];
	int mod_num,used,decided_num;
};

int POW[11];

int ans;

bool check(Info info){

	bool check_table[10];
	for(int i = 0; i < 10; i++)check_table[i] = false;
	int row_0_num,row_1_num,row_2_num,col_0_num,col_1_num,col_2_num,cross_0_num,cross_1_num;

	if(info.table[0][0] == 0 || info.table[0][1] == 0 || info.table[0][2] == 0){

	}else{
		row_0_num = (info.table[0][0]+info.table[0][1]+info.table[0][2])%info.mod_num;
		check_table[row_0_num] = true;
	}

	if(info.table[1][0] == 0 || info.table[1][1] == 0 || info.table[1][2] == 0){

	}else{
		row_1_num = (info.table[1][0]+info.table[1][1]+info.table[1][2])%info.mod_num;
		check_table[row_1_num] = true;
	}

	if(info.table[2][0] == 0 || info.table[2][1] == 0 || info.table[2][2] == 0){

	}else{
		row_2_num = (info.table[2][0]+info.table[2][1]+info.table[2][2])%info.mod_num;
		check_table[row_2_num] = true;
	}

	if(info.table[0][0] == 0 || info.table[1][0] == 0 || info.table[2][0] == 0){

	}else{
		col_0_num = (info.table[0][0]+info.table[1][0]+info.table[2][0])%info.mod_num;
		check_table[col_0_num] = true;
	}

	if(info.table[0][1] == 0 || info.table[1][1] == 0 || info.table[2][1] == 0){

	}else{
		col_1_num = (info.table[0][1]+info.table[1][1]+info.table[2][1])%info.mod_num;
		check_table[col_1_num] = true;
	}

	if(info.table[0][2] == 0 || info.table[1][2] == 0 || info.table[2][2] == 0){

	}else{
		col_2_num = (info.table[0][2]+info.table[1][2]+info.table[2][2])%info.mod_num;
		check_table[col_2_num] = true;
	}

	if(info.table[0][0] == 0 || info.table[1][1] == 0 || info.table[2][2] == 0){

	}else{
		cross_0_num = (info.table[0][0]+info.table[1][1]+info.table[2][2])%info.mod_num;
		check_table[cross_0_num] = true;
	}

	if(info.table[0][2] == 0 || info.table[1][1] == 0 || info.table[2][0] == 0){

	}else{
		cross_1_num = (info.table[0][2]+info.table[1][1]+info.table[2][0])%info.mod_num;
		check_table[cross_1_num] = true;
	}

	int count = 0;
	for(int i = 0; i < 10; i++){
		if(check_table[i]){
			count++;
		}
	}

	return count <= 1;

}

void copyInfo(Info& to,Info from){
	for(int row = 0; row < 3; row++){
		for(int col = 0; col < 3; col++){
			to.table[row][col] = from.table[row][col];
		}
	}
	to.mod_num = from.mod_num;
}

void recursive(Info info){

	if(info.decided_num == 10){

		if(check(info)){
			ans++;
		}
		return;
	}


	if(info.mod_num == 0){
		for(int loop = 1; loop <= 10; loop++){
			if(info.used & (1 << loop)){
				//Do nothing
			}else{
				Info new_info;
				copyInfo(new_info,info);
				new_info.mod_num = loop;
				new_info.decided_num = info.decided_num+1;
				new_info.used = info.used + POW[loop];
				if(check(new_info)){
					recursive(new_info);
				}
			}
		}
		return;
	}

	for(int row = 0; row < 3; row++){
		for(int col = 0; col < 3; col++){
			if(info.table[row][col] == 0){
				for(int loop = 1; loop <= 10; loop++){
					if(info.used & (1 << loop)){
						//Do nothing
					}else{
						Info new_info;
						copyInfo(new_info,info);
						new_info.table[row][col] = loop;
						new_info.decided_num = info.decided_num+1;
						new_info.used = info.used + POW[loop];
						if(check(new_info)){
							recursive(new_info);
						}
					}
				}
				return;
			}
		}
	}
}


int main(){

	for(int i = 1; i <= 10; i++)POW[i] = pow(2,i);

	while(true){
		Info first;
		for(int row = 0; row < 3; row++){
			for(int col = 0; col < 3; col++)scanf("%d",&first.table[row][col]);
		}
		scanf("%d",&first.mod_num);

		if(first.table[0][0] == -1)break;

		first.used = 0;
		first.decided_num = 0;

		for(int row = 0; row < 3; row++){
			for(int col = 0; col < 3; col++){
				if(first.table[row][col] != 0){
					first.used += POW[first.table[row][col]];
					first.decided_num++;
				}
			}
		}

		if(first.mod_num != 0){
			first.used += POW[first.mod_num];
			first.decided_num++;
		}

		ans = 0;

		recursive(first);

		printf("%d\n",ans);
	}

	return 0;
}