Problem: problem

Santa Claus came from the sky to JOI town this year as well. Since every house in JOI has children, this Santa Claus must give out presents to every house in JOI. However, this year the reindeer I am carrying is a little deaf and I can only get off the top of the building, so it seems that I have to devise a little route to distribute gifts to all the houses.

JOI Town is divided into north, south, east and west, and each section is a house, a church, or a vacant lot. There is only one church in JOI town. According to the following rules, Santa Claus and reindeer depart from the church, give out one gift to every house, and then return to the church.

* This year's reindeer is a little deaf, so it can only fly straight in either the north, south, east, or west, and cannot change direction in the air.
* You can pass freely over the house where you haven't handed out the presents yet. You can get off at a house that hasn't given out presents yet. Whenever I get home, I give out presents and then take off in either direction of north, south, east or west.
* At the house in JOI town, I spend Christmas night without the fireplace until Santa Claus arrives, but after Santa Claus takes off, I turn on the fireplace. When you turn on the fireplace, smoke comes out of the chimney, so you can't pass over the house where you've finished giving out presents.
* You can pass freely over the church. However, since worship is held in the church, you cannot go down to the church until you have distributed all the presents.
* You can pass freely over the vacant lot, but you cannot get off at the vacant lot.


Create a program that asks how many directions Santa Claus and reindeer can give gifts to, given the structure of the town as input.

input

The input consists of multiple datasets. Each dataset is given in the following format.

Each dataset has n + 1 rows. On the first line, the integer m (1 ≤ m ≤ 10) and the integer n (1 ≤ n ≤ 10) are written separated by a space. In each line from the 2nd line to the n + 1th line, m of 0, 1, or 2 are written, separated by a blank, and each represents the state of each section. If we write the i-th section from the north and the j-th section from the west as (i, j) (1 ≤ i ≤ n, 1 ≤ j ≤ m), the j-th value on the i + 1 line is If the lot (i, j) is a vacant lot, it will be 0, if it is a house, it will be 1, and if it is a church, it will be 2. The number of churches is 1, and the number of houses is 1 or more and 23 or less. However, in the input data for scoring, the number of directions to be distributed does not exceed 2000000.

When both m and n are 0, it indicates the end of input. The number of data sets does not exceed 5.

Input / output example

Input example


3 2
1 0 1
1 0 2
3 3
1 1 1
1 0 1
1 1 2
0 0


Output example


2
6


<image>


Figure: All 6 directions to the second input example (numbers indicate the order of distribution)

The above question sentences and the data used for the automatic referee are the question sentences created and published by the Japan Committee for Information Olympics and the test data for scoring.



output

For each dataset, an integer indicating how many directions to distribute gifts is output on one line.

Example

Input

3 2
1 0 1
1 0 2
3 3
1 1 1
1 0 1
1 1 2
0 0


Output

2
6

Solution (in CPP):

Solution:
#include<iostream>
#include<map>
#include<cassert>
#define rep(i, n) for ( int i = 0; i < n; i++)
using namespace std;

#define MAX 10

#define HOUSE 3
#define SPACE 0
#define SMOKE 1
#define START 2
#define BLOCK 4
/*
#define HOUSE '3'
#define SPACE '0'
#define SMOKE '1'
#define START '2'
#define BLOCK 'X'
*/

int H, W;
class State{
public:
  unsigned short pi, pj, total;
  //unsigned short G[MAX+2][MAX+2];
  //char G[MAX+2][MAX+2];
  bool V[MAX+2][MAX+2];

  State(){total = 0;}
  //State(int H, int W):H(H), W(W){ total = 0;}

  bool operator < ( const State &s) const{
    if ( pi != s.pi ) return pi < s.pi;
    if ( pj != s.pj ) return pj < s.pj;
    for ( int i = 1; i <= H; i++ ){
      for ( int j = 1; j <= W; j++ ){
	//if ( G[i][j] == s.G[i][j] ) continue;
	//return G[i][j] < s.G[i][j];
	if ( V[i][j] == s.V[i][j] ) continue;
	return V[i][j] < s.V[i][j];
      }
    }
    return false;
  }

};

static int di[4] = {0, -1, 0, 1};
static int dj[4] = {1, 0, -1, 0};

int  G[MAX+2][MAX+2];


int main(){
  int si, sj;

  while(1){
    cin >> W >> H;
    if ( W == 0 && H == 0 ) break;
    int total = 0;

    for ( int i = 0; i < H+2; i++ )
      for ( int j = 0; j < W+2; j++ ) G[i][j] = BLOCK;
    for ( int i = 1; i <= H; i++ ){
      for ( int j = 1; j <= W; j++ ){
	cin >> G[i][j];
	if ( G[i][j] == START ){ si = i; sj = j;}
	if ( G[i][j] == SMOKE ) total++;
      }
    }

    /*
    bool zero[MAX+2];
    int tmp[MAX+2][MAX+2];
    for ( int i = 1; i <= H; i++ ) zero[i] = true;
    for ( int i = 0; i < H+2; i++ )
      for ( int j = 0; j < W+2; j++ ) tmp[i][j] =  G[i][j];
    for ( int i = 0; i < H+2; i++ )
      for ( int j = 1; j <= W; j++ ) if ( G[i][j] ) zero[i] = false;
    int ii = 0;
    int c = 0;
    for ( int i = 0; i < H+2; i++ ){
      if ( zero[i] ) { c++; continue;}
      for ( int j = 0; j < W+2; j++ ) G[ii][j] = tmp[i][j];
      ii++;
    }
    H -= c;

    for ( int j = 1; j <= W; j++ ) zero[j] = true;
    for ( int i = 0; i < H+2; i++ )
      for ( int j = 0; j < W+2; j++ ) tmp[i][j] =  G[i][j];
    for ( int j = 1; j <= W; j++ ) 
      for ( int i = 0; i < H+2; i++ )
	if ( G[i][j] ) zero[j] = false;
    
    int jj = 0;
    c = 0;
    for ( int j = 0; j < W+2; j++ ){
      if ( zero[j] ) { c++; continue;}
      for ( int i = 0; i < H+2; i++ ) G[i][jj] = tmp[i][j];
      jj++;
    }
    W -= c;

    */


    State s = State();
    
    for ( int i = 0; i <= H+1; i++ )
      for ( int j = 0; j <= W+1; j++ ) s.V[i][j] = ((G[i][j]==SMOKE)?true:false);
    
    map<State, int> M;
    State v;

    int ni, nj;
    M[s] = 0;
    
    for ( int r = 0; r < 4; r++ ){
      ni = si + di[r];
      nj = sj + dj[r];

      while(1){
	//if ( s.G[ni][nj] == SMOKE ){
	if ( s.V[ni][nj] ){
	  v = s;
	  v.pi = ni;
	  v.pj = nj;
	  //v.G[ni][nj] = HOUSE;
	  v.V[ni][nj] = false;
	  v.total = 1;
	  M[v] = 1;
	  break;
	} else if ( G[ni][nj] == BLOCK ) break;
	ni += di[r];
	nj += dj[r];
      }
    }

    map<State, int>::iterator it;
    
    int presize = M.size();

    int cc = 0;
    int x = 0;
    bool f;
    map<State, int> nM;

    
    while(1){
      //      nM = map<State, int>();
      nM.clear();
      f = true;
      for ( it = M.begin(); it != M.end(); it++ ){
	State cur = (*it).first;
	int cost = (*it).second;
	if ( cost == 0 ) continue;

	for ( int r = 0; r < 4; r++ ){
	  ni = cur.pi + di[r];
	  nj = cur.pj + dj[r];

	  while(1){
	    //if ( cur.G[ni][nj] == SMOKE ){
	    if ( cur.V[ni][nj]){
	      v = cur;
	      v.pi = ni;
	      v.pj = nj;
	      //v.G[ni][nj] = HOUSE;
	      v.V[ni][nj] = false;
	      v.total++;
	      f = false;
	      nM[v] += cost;
	      break;
	      //	    } else if ( cur.G[ni][nj] == START && cur.total == total ){
	    } else if ( ni == si && nj == sj && cur.total == total ){
	      x += cost;
	      break;
	    } else if ( G[ni][nj] == BLOCK ) {
	      break;
	    }

	    ni += di[r];
	    nj += dj[r];
	  }
	}
      }
      if ( f ) break;
      M = nM;
    }

    cout << x << endl;
    
  }
}