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<bits/stdc++.h>
using namespace std;
int t[9],d;
bool used[11];
bool C(void){
  int r=(t[0]+t[1]+t[2])%t[9];
  return ((t[3]+t[4]+t[5])%t[9]==r&&(t[6]+t[7]+t[8])%t[9]==r&&(t[0]+t[3]+t[6])%t[9]==r&&(t[1]+t[4]+t[7])%t[9]==r&&(t[2]+t[5]+t[8])%t[9]==r&&(t[0]+t[4]+t[8])%t[9]==r&&(t[2]+t[4]+t[6])%t[9]==r);
}
 
int dfs(int d){
  if(d==10)return C()?1:0;
  if(t[d]!=0)return dfs(d+1);
  int res = 0;
  for(int i=1;i<=10;i++){
    if(!used[i]){
      t[d]=i;
      used[i]=1;
      res+=dfs(d+1);
      used[i]=0;
      t[d]=0;
    }
  }
  return res;
}
int main(){
  while(1){
    memset(used,0,sizeof(used));
    for(int i=0;i<10;i++){
      cin>>t[i];
      if(t[i]>0)used[t[i]]=1;
    }
    if(t[0]==-1)break;
    cout<<dfs(0)<<endl;
  }
  return 0;
}