#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <stack>
#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 EPS 1e-8
#define DEB 0

const int dx[] = {0,1,0,-1};
const int dy[] = {-1,0,1,0};
int w,h,sx,sy,home,last;
int field[16][16];
int num[16][16];

#if DEB
stack<int> st;
#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( x==a.x ){
      if( y==a.y ) return s<a.s;
      else         return y<a.y;
    }else{
      return x<a.x;
    }
  }
  
};


map<state,int> msi;

bool ischeck(int s){
  return (((last&s)) == last) ;
}
bool inside(int x, int y){
  return (x<0 || y<0 || x>=w || y>=h);
}


int dfs(int x, int y, int s){
  if( (1<<home)-1 == s ){ // ÆÍ³ïÉßêé©Ç¤©
    /*
    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) || field[ty][tx]==1 )break;
	if( inside(tx,ty) )break;

	if( field[ty][tx]==2 ){
#if DEB
	  printf("goal , (%d,%d)  s:%d\n",x,y,s);
	  stack<int> tmp = st;
	  while( !tmp.empty() ){
	    printf("%d,",tmp.top());
	    tmp.pop();
	  }
	  puts("\n");
#endif
	  return 1;
	}
      }
    }
    return 0;
    */
    return 1;
  }
  if( msi.count(state(x,y,s)) ){ //ùÉÊÁ½ê
    return msi[state(x,y,s)];
  }
  if( ischeck(s) ){
    return 0;
  }
  
  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 ){
	//if( s&(1<<num[ty][tx]) ) break;	
	field[ty][tx] = 0;
#if DEB
	st.push(num[ty][tx]);
#endif 
	ret += dfs(tx,ty,s|(1<<num[ty][tx]));
#if DEB
	st.pop();
#endif
	field[ty][tx] = 1;
	break;
      }
    }
  }
  msi[state(x,y,s)] = ret;
  return ret;
}

int main(){

  while(scanf("%d%d",&w,&h),w|h){
    msi.clear();
    memset(num,-1,sizeof(num));
    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 ){
	  num[i][j] = home;
	  home++;
	}
      }
    }

    //last homes
    rep(k,4){
      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]);
	}
      }
    }
#if DEB
    printf("home:%d  sx,sy = %d,%d\n",home,sx,sy);
    printf("last:%d\n",last);
    rep(i,h){
      rep(j,w){
	printf("%2d ",num[i][j]);
      }
      puts("");
    }
#endif   
    dfs(sx,sy,0);
    printf("%d\n",msi[state(sx,sy,0)]);
  }
  

  return 0;
}