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 <algorithm>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

#define REP(i,a,n) for(int i=(a); i<(int)(n); i++)
#define rep(i,n) REP(i,0,n)
#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define DEB 0

/*
real	0m2.117s
*/
const int dx[] = {1,0,-1,0}; //r,d,l,u
const int dy[] = {0,1,0,-1};

int w,h,sx,sy,home,last;
int field[16][16];
int num[16][16];
int hS[24],hx[24],hy[24],edge[24][4][24]; //[src][dir][dest]

#if DEB
int already_1,already_2;
#endif

class state{
public:
  char x,y;
  int s;
  state(char _x, char _y, int _s){
    x=_x; y=_y; s=_s;
  }
  
  bool operator<(const state& a)const{
    if( s==a.s ){
      if( x==a.x ) return y<a.y;
      else         return x<a.x;
    }else{
      return s<a.s;
    }
  }
  
};

map<state,int> msi;

inline bool isnotgoal(int s){
  return (((last&s)) == last);
}
inline bool isnot(int s){
  rep(i,home)if( !(s&(1<<i)) ){
    if( (hS[i]&s)==hS[i] ) return true;
  }
  return false;
}
inline bool inside(int x, int y){
  return (x<0 || y<0 || x>=w || y>=h);
}


int dfs(int x, int y, int s, int src){
  if( (1<<home)-1 == s ){ //âÎÉßêé
    return 1;
  }
  if( isnotgoal(s) ){ //³ïÉßé½ßÌÆðÁïµ½©Ç¤©
    return 0;
  }
  state tmp(x,y,s);
  if( msi.count(tmp) ){ //ùÉÊÁ½óÔ
#if DEB
    if( msi[tmp]>0 ){
      already_1++;
    }else{
      already_2++;
    }
#endif
    return msi[tmp];
  }
  
  // v[gªu¯È¢ÆÌL³
  // numofbits(~s&mask)>1
  if( s>0 && ((s&(s-1))!=0) && isnot(s&~(1<<num[y][x])) ){
    return 0;
  }
  
  int ret = 0;
  rep(k,4){
    for(int j=0; edge[src][k][j]!=-1; j++){
      int dest = edge[src][k][j];
      int nx = hx[dest];
      int ny = hy[dest];
      if( field[ny][nx]==1 ){
	field[ny][nx] = 0;
	ret += dfs(nx, ny, s|(1<<dest), dest);
	field[ny][nx] = 1;
	break;
      }
    }
  }
  /*
  int ret = 0;
  rep(k,4){
    for(int i=1; i<20; i++){
      int tx = x + dx[k]*i;
      int ty = y + dy[k]*i;
      if( inside(tx,ty) ) break;
      if( field[ty][tx]==1 ){
	field[ty][tx] = 0;
	ret += dfs(tx,ty,s|(1<<num[ty][tx]));
	field[ty][tx] = 1;
	break;
      }
    }
  }
  */
  msi[tmp] = ret;
  return ret;
}

int main(){

  while(scanf("%d%d",&w,&h),w|h){
    msi.clear();
    memset(num,-1,sizeof(num));
    memset(edge,-1,sizeof(edge));
    memset(hS,0,sizeof(hS));
    home = last = 0;
    rep(i,h){
      rep(j,w){
	scanf("%d",&field[i][j]);
	if( field[i][j]==2 ){
	  sx=j; sy=i;
	}
	if( field[i][j]==1 ){
	  hx[home]=j; hy[home]=i;
	  num[i][j] = home;
	  home++;
	}
      }
    }

    // other homes
    rep(i,home){
      rep(k,4){
	int sz = 0;
	for(int j=1; j<20; j++){
	  int tx = hx[i] + dx[k]*j;
	  int ty = hy[i] + dy[k]*j;
	  if( inside(tx,ty) ) break;
	  if( field[ty][tx]==1 ){
	    hS[i] |= (1<<num[ty][tx]);
	    edge[i][k][sz++] = num[ty][tx];
	  }
	}
      }
    }

#if DEB
    rep(i,home){
      printf("i:(%d,%d)\n",hx[i],hy[i]);
    }
    rep(i,home){
      rep(k,4){
	for(int j=0; edge[i][k][j]!=-1;j++){
	  printf("i:%d(%d)  --> %d\n",i,k,edge[i][k][j]);
	}
      }
    }
#endif

    //last homes
    rep(k,4){
      int sz = 0;
      for(int i=1; i<20; i++){
	int tx = sx + dx[k]*i;
	int ty = sy + dy[k]*i;
	if( inside(tx,ty) )break;
	if( field[ty][tx]==1 ){
	  last |= (1<<num[ty][tx]);
	  edge[home][k][sz++] = num[ty][tx];
	}
      }
    }
    printf("%d\n",dfs(sx,sy,0,home));

#if DEB
    int cnt = 0;
    map<state,int>::iterator it;
    for(it=msi.begin(); it!=msi.end(); it++){
      if( it->second == 0 ){
	cnt++;
      }
    }
    printf("msi_sz:%d  >0:%d  ==0:%d  already>0:%d , already==0:%d\n",msi.size(),msi.size()-cnt,cnt,already_1,already_2);
    already_1 = already_2 = 0;
#endif

  }
  

  return 0;
}