#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <unordered_map>

using namespace std;

typedef pair<int,int> P;

int HashH(int now, set<int>& vis) {
    int val=now;
    for(auto x : vis) {
        val+=(1<<(x+7));
    }
    return val;
}

int dfs(int now, set<int>& vis, unordered_map<int,int>& dp, vector<vector<vector<int> > >& e, int church, int cnt) {
    int hashval=HashH(now,vis);

    if(dp.count(hashval)!=0) {
        return dp[hashval];
    } else if(cnt==0 && now==church) {
        return dp[hashval]=1;
    }

    int dh[4]={-1,0,1,0};
    int dw[4]={0,-1,0,1};

    int ret=0;
    for(int d=0; d<4; ++d) {
        for(int i=0; i<(int)e[d][now].size(); ++i) {
            if(vis.count(e[d][now][i])==0) {
                if(e[d][now][i]==church && cnt>1) continue;
                vis.insert(e[d][now][i]);
                ret+=dfs(e[d][now][i],vis,dp,e,church,cnt-1);
                vis.erase(e[d][now][i]);
                break;
            }
        }
    }
    return dp[hashval]=ret;
}

void solve(int m, int n) {
    vector<vector<int> > mp(n);
    int cnt=0;
    vector<P> hou;
    P ch;
    set<int> vis;

    for(int i=0; i<n; ++i) {
        for(int j=0; j<m; ++j) {
            int temp;
            cin >> temp;
            if(temp==1) {
                mp[i].push_back(cnt);
                hou.push_back(P(i,j));
                ++cnt;
            } else if(temp==2) {
                ch=P(i,j);
                mp[i].push_back(-2);
            } else {
                mp[i].push_back(-1);
            }
        }
    }

    hou.push_back(ch);
    mp[ch.first][ch.second]=cnt;

    // edge
    vector<vector<vector<int> > > e(4);
    for(int i=0; i<4; ++i) e[i].resize(cnt+1);

    for(int i=0; i<(int)hou.size(); ++i) {
        P now=hou[i];
        int dh[4]={-1,0,1,0};
        int dw[4]={0,-1,0,1};
        for(int d=0; d<4; ++d) {
            P nxt=now;
            while(true) {
                nxt.first+=dh[d];
                nxt.second+=dw[d];
                if(nxt.first<0 || nxt.first>=n || nxt.second<0 || nxt.second>=m) break;
                if(mp[nxt.first][nxt.second]>=0) e[d][i].push_back(mp[nxt.first][nxt.second]);
            }
        }
    }

    unordered_map<int,int> dp;
    int ans=dfs(cnt,vis,dp,e,cnt,cnt+1);
    cout << ans << endl;
    return;
}

int main() {
    int m,n;
    while(true) {
        cin >> m >> n;
        if(m==0 && n==0) break;
        solve(m,n);
    }
    return 0;
}
