Problem:
引っ越し
あなたは昨今の事情を踏まえて広い部屋に引っ越すことにした．新しい部屋の間取りは正方形のマス目を縦
H
マス，横
W
マスに並べたグリッドで表すことができる．それぞれのマスは壁や柱のような侵入できないマス（以下，壁マスと呼ぶ）か，それ以外のマス（以下，床マスと呼ぶ）である．
あなたが新しい部屋の間取りを SNS で共有したところ，引っ越し祝いと称して友人からマス目のちょうど 3 マスを覆う大きさの L 字型のタイルカーペットがたくさん送られてきた．なんでもその友人が言うところによると，あなたの新しい部屋の間取りならば，L 字型のタイルカーペットをマス目に沿って適切に配置することで，タイルカーペットが重なることなく全ての床マスをタイルカーペットで覆うことができるらしい．
あなたは実際にタイルカーペットを敷く前に，全ての床マスを覆うことができるような配置が何通りあるのか調べることにした．組合せを数える際には個々のタイルカーペットは区別せず，タイルカーペットには裏表の区別がないこととする．
Input
入力は複数のデータセットからなる．各データセットは次の形式で表される．
H
W
a
1,1
...
a
1,W
...
a
H,1
...
a
H,W
1 行目には部屋の間取りを表すグリッドの大きさを表す 2 つの整数
H
,
W
(
2 ≤ H, W ≤ 8
) が与えられる．続く
H
行はそれぞれ
W
文字からなり，各文字は壁マスを表す '#' と床マスを表す '.' のいずれかである．
部屋の間取りを表すグリッドは以下の制約を満たす．
床マスが 3 つ以上ある．
タイルカーペットが重なることなく全ての床マスをタイルカーペットで覆うことができる配置が 1 通り以上ある．
入力の終わりは二つのゼロからなる行で表される．データセットの個数は 50 を超えない．
Output
各データセットについて，すべての床マスが L 字型のタイルカーペットで覆われるような配置の組合せの数を 1 行で出力せよ．
Sample Input
4 3
..#
..#
...
#..
4 4
####
#.##
#..#
####
8 6
......
......
......
......
......
......
......
......
0 0
Output for the Sample Input
2
1
1514

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) (a).begin(), (a).end()
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rrep(i, n) for (int i = (int)(n) - 1; 0 <= i; --i)
template <typename T> bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
void solve();
int H,W;
string a[8];
signed main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  cout << fixed << setprecision(20);
  int TESTCASES = 1<<30;
  //cin >> TESTCASES;
  while (TESTCASES--) {
    cin>>H>>W;
    if(H==0)break;
    rep(i,H)cin>>a[i];
    solve();
  }
}
int calc(){
  int x=-1,y=-1;
  rep(i,H){
    rep(j,W){
      if(a[i][j]=='.'){
        x=i,y=j;
        break;
      }
    }
    if(x!=-1)break;
  }
  if(x==-1)return 1;
  vector<vector<int>>dx={{0,0,1},{0,1,1},{0,0,1},{0,1,1}};
  vector<vector<int>>dy={{0,1,0},{0,0,1},{0,1,1},{0,-1,0}};
  int ret=0;
  rep(mode,4){
    bool ok=1;
    rep(i,dx[mode].size()){
      int xx=x+dx[mode][i],yy=y+dy[mode][i];
      if(!(0<=xx&&xx<H&&0<=yy&&yy<W)||a[xx][yy]!='.'){
        ok=0;
        break;
      }
    }
    if(!ok)continue;
    rep(i,dx[mode].size()){
      int xx=x+dx[mode][i],yy=y+dy[mode][i];
      a[xx][yy]='#';
    }
    ret+=calc();
    rep(i,dx[mode].size()){
      int xx=x+dx[mode][i],yy=y+dy[mode][i];
      a[xx][yy]='.';
    }
  }
  return ret;
}
void solve() {
  cout<<calc()<<'\n';
}
accuracy: 1
time_ms: 740
memory_kb: 3584
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;
using PP = pair<int, P>;
using PLL = pair<ll, ll>;
using PPLL = pair<ll, PLL>;
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define rrep(i, n) for (ll i = n - 1; i >= 0; --i)
#define loop(i, a, b) for (ll i = a; i <= b; ++i)
#define all(v) v.begin(), v.end()
#define nC2(n) n *(n - 1) / 2
constexpr ll INF = 9009009009009009009LL;
constexpr int INF32 = 2002002002;
constexpr ll MOD = 998244353;
constexpr ll MOD107 = 1000000007;

// Linear Algebra ////////////////////////////////////////////////
const double Rad2Deg = 180.0 / M_PI;
const double Deg2Rad = M_PI / 180.0;
//////////////////////////////////////////////////////////////////

int dx[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int dy[8] = {1, 0, -1, 0, 1, -1, 1, -1};

template <class T>
inline bool chmax(T &a, const T &b)
{
	if (a < b)
	{
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmin(T &a, const T &b)
{
	if (a > b)
	{
		a = b;
		return true;
	}
	return false;
}

template <typename Container,
		  typename = std::enable_if_t<
			  !std::is_same_v<Container, std::string> &&
			  std::is_convertible_v<decltype(std::declval<Container>().begin()),
									typename Container::iterator>>>
ostream &operator<<(ostream &os, const Container &container)
{
	auto it = container.begin();
	auto end = container.end();

	if (it != end)
	{
		os << *it;
		++it;
	}
	for (; it != end; ++it)
	{
		os << " " << *it;
	}
	return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v)
{
	for (size_t i = 0; i < v.size(); ++i)
	{
		os << v[i];
		if (i != v.size() - 1)
			os << " ";
	}
	return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &vv)
{
	for (size_t i = 0; i < vv.size(); ++i)
	{
		os << vv[i];
		if (i != vv.size() - 1)
			os << "\n";
	}
	return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v)
{
	assert(v.size() > 0);
	for (size_t i = 0; i < v.size(); ++i)
		is >> v[i];
	return is;
}
template <typename T>
istream &operator>>(istream &is, vector<vector<T>> &vv)
{
	assert(vv.size() > 0);
	for (size_t i = 0; i < vv.size(); ++i)
		is >> vv[i];
	return is;
}

struct phash
{
	template <class T1, class T2>
	inline size_t operator()(const pair<T1, T2> &p) const
	{
		auto h1 = hash<T1>()(p.first);
		auto h2 = hash<T2>()(p.second);

		size_t seed = h1 + h2;
		h1 = ((h1 >> 16) ^ h1) * 0x45d9f3b;
		h1 = ((h1 >> 16) ^ h1) * 0x45d9f3b;
		h1 = (h1 >> 16) ^ h1;
		seed ^= h1 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
		h2 = ((h2 >> 16) ^ h2) * 0x45d9f3b;
		h2 = ((h2 >> 16) ^ h2) * 0x45d9f3b;
		h2 = (h2 >> 16) ^ h2;
		seed ^= h2 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
		return seed;
	}
};

int solve()
{
	ll h, w;
	cin >> h >> w;
	if (h == 0 && w == 0)
		return 1;
	vector<string> g(h);
	cin >> g;

	const PLL dL1[4] = {{0, 1}, {1, 0}, {0, 1}, {1, 0}};
	const PLL dL2[4] = {{1, 1}, {1, 1}, {1, 0}, {1, -1}};

	ll ans = 0;
	auto dfs = [&](auto dfs, vector<vector<bool>> &filled, ll sy, ll sx) -> void
	{
		while (sy < h && sx < w)
		{
			if (g[sy][sx] == '.' && !filled[sy][sx])
				break;

			sx++;
			if (sx == w)
			{
				sx = 0;
				sy++;
			}
			if (sy == h)
			{
				ans++;
				return;
			}
		}

		rep(rot, 4)
		{
			ll ny1 = sy + dL1[rot].first;
			ll nx1 = sx + dL1[rot].second;
			ll ny2 = sy + dL2[rot].first;
			ll nx2 = sx + dL2[rot].second;

			if (ny1 < 0 || h <= ny1 || nx1 < 0 || w <= nx1)
				continue;
			if (ny2 < 0 || h <= ny2 || nx2 < 0 || w <= nx2)
				continue;
			if (g[ny1][nx1] == '#' || filled[ny1][nx1])
				continue;
			if (g[ny2][nx2] == '#' || filled[ny2][nx2])
				continue;

			filled[sy][sx] = true;
			filled[ny1][nx1] = true;
			filled[ny2][nx2] = true;
			dfs(dfs, filled, sy, sx);
			filled[sy][sx] = false;
			filled[ny1][nx1] = false;
			filled[ny2][nx2] = false;
		}
	};
	vector<vector<bool>> filled(h, vector<bool>(w, false));
	dfs(dfs, filled, 0, 0);

	cout << ans << "\n";

	return 0;
}

int main()
{
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	while (!solve())
	{
	}
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 3472
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define ld long double
#define s_int signed
#define yes cout<<"Yes"<<endl;
#define rep(i, n, k) for (ll i = k; i < (ll)(n); i++)
#define no cout<<"No"<<endl;
#define Cans cout<<ans<<endl;
using namespace std;
ll INF=9223372036854775807;
template<typename T>
void coutvec(vector<T> a){rep(i,a.size(),0){cout<<a[i];if(i<a.size()-1)cout<<' ';else cout<<endl;}}//vecの空白付き出力
int main(){
    while(true){
        ll h,w,ans=0;
        cin>>h>>w;
        if(h==0&&w==0)return 0;
        vector<string>a(h);
        rep(i,h,0)cin>>a[i];
        pair<ll,ll>s={-1,-1};
        rep(i,h,0){
            rep(j,w,0){
                if(a[i][j]=='.'){
                    s={i,j};
                    break;
                }
            }
            if(s!=make_pair(-1LL,-1LL))break;
        }
        queue<pair<vector<string>,pair<ll,ll>>>q;
        q.push({a,s});
        while(!q.empty()){
            vector<string>an=q.front().first;
            pair<ll,ll>now=q.front().second;
            q.pop();
            if(now.first+1<h&&now.second+1<w&&an[now.first][now.second+1]=='.'&&an[now.first+1][now.second]=='.'){
                vector<string>an1=an;
                an1[now.first][now.second]='l';
                an1[now.first+1][now.second]='l';
                an1[now.first][now.second+1]='l';
                pair<ll,ll>next={-1,-1};
                rep(i,h,0){
                    rep(j,w,0){
                        if(an1[i][j]=='.'){
                            next=make_pair(i,j);
                            break;
                        }
                    }
                    if(next!=make_pair(-1LL,-1LL))break;
                }
                if(next==make_pair(-1LL,-1LL))ans++;
                else q.push({an1,next});
            }
            if(now.first+1<h&&now.second+1<w&&an[now.first][now.second+1]=='.'&&an[now.first+1][now.second+1]=='.'){
                vector<string>an1=an;
                an1[now.first][now.second]='l';
                an1[now.first][now.second+1]='l';
                an1[now.first+1][now.second+1]='l';
                pair<ll,ll>next={-1,-1};
                rep(i,h,0){
                    rep(j,w,0){
                        if(an1[i][j]=='.'){
                            next=make_pair(i,j);
                            break;
                        }
                    }
                    if(next!=make_pair(-1LL,-1LL))break;
                }
                if(next==make_pair(-1LL,-1LL))ans++;
                else q.push({an1,next});
            }
            if(now.first+1<h&&now.second+1<w&&an[now.first+1][now.second+1]=='.'&&an[now.first+1][now.second]=='.'){
                vector<string>an1=an;
                an1[now.first][now.second]='l';
                an1[now.first+1][now.second+1]='l';
                an1[now.first+1][now.second]='l';
                pair<ll,ll>next={-1,-1};
                rep(i,h,0){
                    rep(j,w,0){
                        if(an1[i][j]=='.'){
                            next=make_pair(i,j);
                            break;
                        }
                    }
                    if(next!=make_pair(-1LL,-1LL))break;
                }
                if(next==make_pair(-1LL,-1LL))ans++;
                else q.push({an1,next});
            }
            if(now.first+1<h&&now.second-1>=0&&an[now.first+1][now.second-1]=='.'&&an[now.first+1][now.second]=='.'){
                vector<string>an1=an;
                an1[now.first][now.second]='l';
                an1[now.first+1][now.second-1]='l';
                an1[now.first+1][now.second]='l';
                pair<ll,ll>next={-1,-1};
                rep(i,h,0){
                    rep(j,w,0){
                        if(an1[i][j]=='.'){
                            next=make_pair(i,j);
                            break;
                        }
                    }
                    if(next!=make_pair(-1LL,-1LL))break;
                }
                if(next==make_pair(-1LL,-1LL))ans++;
                else q.push({an1,next});
            }
        }
        Cans
    }
}
accuracy: 1
time_ms: 540
memory_kb: 173324
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

map<ll,vector<ll>>edge[9];

void init()
{
	for(int i=2; i<=8; i++)
	{
		ll maxi = 1;
		for(int j=0; j<i; j++) maxi *= 5;
						
		for(int j=0; j<maxi; j++)
		{
			ll now = 0;
			ll nxt = 0;
			int s = j;
			bool flag = true;
			for(int k=0; k<i; k++)
			{
				if(s%5==1)
				{
					if(k==i-1) flag = false;
					if(now & ((1<<k) | (1<<(k+1)))) flag = false;
					if(nxt & (1<<k)) flag = false;
					now |= ((1<<k) | (1<<(k+1)));
					nxt |= (1<<k);
				}
				if(s%5==2)
				{
					if(k==0) flag = false;
					if(now & ((1<<k))) flag = false;
					if(nxt & ((1<<k) | (1<<(k-1)))) flag = false;
					now |= (1<<k);
					nxt |= ((1<<k) | (1<<(k-1)));
				}
				if(s%5==3)
				{
					if(k==i-1) flag = false;
					if(now & ((1<<k) | (1<<(k+1)))) flag = false;
					if(nxt & (1<<(k+1))) flag = false;
					now |= ((1<<k) | (1<<(k+1)));
					nxt |= (1<<(k+1));
				}
				if(s%5==4)
				{
					if(k==i-1) flag = false;
					if(now & (1<<k)) flag = false;
					if(nxt & ((1<<k) | (1<<(k+1)))) flag = false;
					now |= (1<<k);
					nxt |= ((1<<k) | (1<<(k+1)));
				}
				s /= 5;
			}
			if(flag)
			{
				edge[i][((1<<i)-1)^now].push_back(nxt);
			}
		}
	}
}

int main()
{
	init();
	while(1)
	{
		ll h,w;
		cin >> h >> w;
		if(h==0 || w==0) break;

		string m[8];
		for(int i=0; i<h; i++) cin >> m[i];

		ll mi[8];
		for(int i=0; i<h; i++)
		{
			ll sum = 0;
			for(int j=0; j<w; j++)
			{
				if(m[i][j]=='#') sum |= (1<<j);
			}
			mi[i] = sum;
		}
		
		ll dp[9][(1<<8)];
		for(int i=0; i<=h; i++)
		{
			for(int j=0; j<(1<<w); j++)
			{
				dp[i][j] = 0;
			}
		}

		dp[0][mi[0]] = 1;
		for(int i=0; i<h-1; i++)
		{
			for(int j=0; j<(1<<w); j++)
			{
				if(dp[i][j]==0) continue;
				for(auto nxt:edge[w][j])
				{
					if(nxt & mi[i+1]) continue;
					dp[i+1][nxt|mi[i+1]] += dp[i][j];
				}
			}
		}
		cout << dp[h-1][(1<<w)-1] << endl;
	}
}
accuracy: 1
time_ms: 20
memory_kb: 3712
final_rank: 5

code_snippet: #include <bits/stdc++.h>
#include <unordered_map>
#include <stdlib.h>
using namespace std;
#define rep(i, a, n) for(ll i = a; i < n; i++)
#define rrep(i, a, n) for(ll i = a; i >= n; i--)
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(x) (x).begin(), (x).end()
//constexpr ll MOD = 1000000007;
constexpr ll MOD = 998244353;
constexpr int IINF = 1001001001;
constexpr ll INF = 1LL<<60;
template<class t,class u> void chmax(t&a,u b){if(a<b)a=b;}
template<class t,class u> void chmin(t&a,u b){if(b<a)a=b;}

ll gcd(ll a, ll b){
    if(a%b == 0){
      return b;
    }else{
      return gcd(b, a%b);
    }
}

ll lcm(ll a, ll b){
    return a*b / gcd(a, b);
}

ll powMod(ll x, ll n) {
    if (n == 0) return 1 % MOD;
    ll val = powMod(x, n / 2);
    val *= val;
    val %= MOD;
    if (n % 2 == 1) val *= x;
    return val % MOD;
}

int main() {
    while(true){
        ll h, w; cin >> h >> w;
        if(h*w == 0) break;
        vector<string> s(h);
        rep(i,0,h) cin >> s[i];
        ll ans = 0;
        auto solve = [&](auto solve, ll i, ll j) -> void {
            if(i == h-1 && j == w){
                ans++;
                return;
            }else if(j == w){
                solve(solve, i+1, 0);
            }
            if(s[i][j] == '#') solve(solve, i, j+1);
            else{
                if(i < h-1 && j < w-1){
                    if(s[i][j+1] == '.' && s[i+1][j] == '.'){
                        s[i][j] = '#';
                        s[i][j+1] = '#';
                        s[i+1][j] = '#';
                        solve(solve, i, j+2);
                        s[i][j] = '.';
                        s[i][j+1] = '.';
                        s[i+1][j] = '.';
                    }
                    if(s[i][j+1] == '.' && s[i+1][j+1] == '.'){
                        s[i][j] = '#';
                        s[i][j+1] = '#';
                        s[i+1][j+1] = '#';
                        solve(solve, i, j+2);
                        s[i][j] = '.';
                        s[i][j+1] = '.';
                        s[i+1][j+1] = '.';
                    }
                    if(s[i+1][j] == '.' && s[i+1][j+1] == '.'){
                        s[i][j] = '#';
                        s[i+1][j] = '#';
                        s[i+1][j+1] = '#';
                        solve(solve, i, j+1);
                        s[i][j] = '.';
                        s[i+1][j] = '.';
                        s[i+1][j+1] = '.';
                    }
                }
                if(i < h-1 && j > 0){
                    if(s[i+1][j-1] == '.' && s[i+1][j] == '.'){
                        s[i][j] = '#';
                        s[i+1][j-1] = '#';
                        s[i+1][j] = '#';
                        solve(solve, i, j+1);
                        s[i][j] = '.';
                        s[i+1][j-1] = '.';
                        s[i+1][j] = '.';
                    }
                }

            } 
        };
        solve(solve, 0, 0);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3456
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using a2 = array<ll, 2>;
using a3 = array<ll, 3>;

template <typename A> void chmin(A &l, const A &r) {
    if(r < l)
        l = r;
}
template <typename A> void chmax(A &l, const A &r) {
    if(l < r)
        l = r;
}

ll mod = 998244353;

vector<char> isprime;
void init() {
    isprime.assign(1000005, 1);
    isprime[0] = 0;
    isprime[1] = 0;
    for(int i = 2; i < 1000005; i++) {
        if(isprime[i]) {
            for(int j = i * 2; j < 1000005; j += i) {
                isprime[j] = 0;
            }
        }
    }
}

ll h, w;
vector<string> s;
void input() {
    cin >> h >> w;
    s.resize(h);
    for(auto &x : s)
        cin >> x;
}

void solve() {
    vector<vector<a2>> put;
    put.push_back({{0, 1}, {1, 0}});
    put.push_back({{0, 1}, {1, 1}});
    put.push_back({{1, 0}, {1, -1}});
    put.push_back({{1, 0}, {1, 1}});

    ll ans = 0;

    auto dfs = [&](auto self, int depth)->void {
        
        if(depth == 0)
        {
            ans++;
            return;
        }else {
            ll p = -1, q = -1;
            for(int i = 0; i < h && p == -1; i++) {
                for(int j = 0; j < w && p == -1; j++) {
                    if(s[i][j] == '.') {
                        p = i;
                        q = j;
                    }
                }
            }

            s[p][q] = '/';
            for(auto &x : put) {
                bool ok = true;
                int loo = 0;
                for(auto &y : x) {
                    ll a = p + y[0], b = q + y[1];
                    if(a < 0 || a >= h || b < 0 || b >= w)
                    {
                        ok = false;
                        break;
                    }
                    if(s[a][b] != '.') {
                        ok = false;
                        break;
                    }
                    s[a][b] = '/';
                    loo++;
                }

                if(ok)
                    self(self, depth - 1);
                for(auto &y : x) {
                    if(loo==0)
                    break;
                    ll a = p + y[0], b = q + y[1];
                    if(a < 0 || a >= h || b < 0 || b >= w)
                        break;
                    if(s[a][b] != '/') 
                        break;
                    s[a][b] = '.';
                    loo--;
                }
            }
            s[p][q] = '.';
        }
        return;
    };

    ll dep = 0;
    for(auto &x : s) {
        dep += count(x.begin(), x.end(), '.');
    }
    dfs(dfs, dep / 3);
    cout << ans << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    // init();
    while(1) {
        input();
        if(h == 0)
            break;
        solve();
    }

    return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 3320
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main(){
    while(1){
        int H, W; cin >> H >> W;
        if(H == 0) break;
        vector<string> a(H);
        for(int i = 0; i < H; ++i) cin >> a[i];

        int ans = 0, rem = 0;
        for(int i = 0; i < H; ++i){
            for(int j = 0; j < W; ++j){
                rem += (a[i][j] == '.');
            }
        }
        /*
            $1
            2.

            $1
            .2

            $.
            12

            .$
            12
        */
        int dy1[4] = {0, 0, 1, 1}, dx1[4] = {1, 1, 0, -1};
        int dy2[4] = {1, 1, 1, 1}, dx2[4] = {0, 1, 1, 0};
        auto dfs = [&](auto &self, int i, int j) -> void {
            if(rem == 0){
                ++ans;
                return;
            }
            if(a[i][j] != '.'){
                if(j + 1 == W) self(self, i + 1, 0);
                else self(self, i, j + 1);
            }
            else{
                for(int k = 0; k < 4; ++k){
                    bool f = true;
                    {
                        int ni = i + dy1[k], nj = j + dx1[k];
                        if(ni < 0 or ni >= H or nj < 0 or nj >= W) f = false;
                        else f &= a[ni][nj] == '.';
                    }
                    {
                        int ni = i + dy2[k], nj = j + dx2[k];
                        if(ni < 0 or ni >= H or nj < 0 or nj >= W) f = false;
                        else f &= a[ni][nj] == '.';
                    }
                    if(!f) continue;
                    a[i][j] = '$';
                    {
                        int ni = i + dy1[k], nj = j + dx1[k];
                        a[ni][nj] = '$';
                    }
                    {
                        int ni = i + dy2[k], nj = j + dx2[k];
                        a[ni][nj] = '$';
                    }
                    rem -= 3;
                    if(j + 1 == W) self(self, i + 1, 0);
                    else self(self, i, j + 1);
                    rem += 3;
                    a[i][j] = '.';
                    {
                        int ni = i + dy1[k], nj = j + dx1[k];
                        a[ni][nj] = '.';
                    }
                    {
                        int ni = i + dy2[k], nj = j + dx2[k];
                        a[ni][nj] = '.';
                    }
                }
            }
        };
        dfs(dfs, 0, 0);
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3456
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ALL(v) (v).begin(), (v).end()
using ll = long long;

int main() {
    // int s1 = 3, s21 = 1, s22 = 2;
    // while (s1 < (1 << 8)) {
    //     pattern.emplace_back(s1, s21);
    //     pattern.emplace_back(s1, s22);
    //     pattern.emplace_back(s21, s1);
    //     pattern.emplace_back(s22, s1);
    //     s1 <<= 1;
    //     s21 <<= 1;
    //     s22 <<= 1;
    // }
    // cout<<(1<<24)<<endl;
    while (true) {
        int h,w;
        cin>>h>>w;
        if (h == 0 && w == 0) break;
        vector<string> s(h);
        vector<int> bit_table(h,0);
        for(int i=0;i<h;i++){
            cin>>s[i];
            for(int j=0;j<w;j++){
                if(s[i][j] == '.')continue;
                bit_table[i] |= (1<<j);
            }
        }
        // int h=8,w=8;
        vector<pair<int,int>> pattern;
        deque<tuple<int,int,int>> dq;
        dq.push_back({0,0,0});
        while(!dq.empty()){
            auto [s1,s2,k] = dq.front();
            dq.pop_front();
            if(k==w){
                pattern.push_back({s1,s2});
                auto f = [] (int s) {
                    string T;
                    while (s > 0) {
                        T += (s & 1 ? '1' : '0');
                        s >>= 1;
                    }
                    reverse(ALL(T));
                    return T;
                };
                // cout << setw(10) << setfill('0') << f(s1) << " "<< setw(10) << setfill('0') << f(s2) <<endl;
                continue;
            }
            int a = (s1>>k)&1;
            int b = (s1>>(k+1))&1;
            int c = (s2>>k)&1;
            int d = (s2>>(k+1))&1;
            if(a==1){
                dq.push_back({s1,s2,k+1});
                continue;
            }

            if(a+b+d==0&&k+1<w){
                int ns1 = s1,ns2=s2;
                ns1 |=(1<<k);//a
                ns1 |=(1<<(k+1));//b
                //ns2 |=(1<<k);//c
                ns2 |=(1<<(k+1));//d
                dq.push_back({ns1,ns2,k+1});
            }
            if(a+c+d==0&&k+1<w){
                int ns1 = s1,ns2=s2;
                ns1 |=(1<<k);//a
                //ns1 |=(1<<(k+1));//b
                ns2 |=(1<<k);//c
                ns2 |=(1<<(k+1));//d
                dq.push_back({ns1,ns2,k+1});
            }
            if(a+b+c==0&&k+1<w){
                int ns1 = s1,ns2=s2;
                ns1 |=(1<<k);//a
                ns1 |=(1<<(k+1));//b
                ns2 |=(1<<k);//c
                // ns2 |=(1<<(k+1));//d
                dq.push_back({ns1,ns2,k+1});

            }
            if(a+c==0&&k!=0&&((s2>>(k-1))&1)==0){
                int ns1 = s1,ns2=s2;
                ns1 |=(1<<k);//a
                // ns1 |=(1<<(k+1));//b
                ns2 |=(1<<k);//c
                ns2 |=(1<<(k-1));//e
                dq.push_back({ns1,ns2,k+1});
            }
             dq.push_back({s1,s2,k+1});
        }
        // sort(ALL(pattern));
        // pattern.erase(unique(ALL(pattern)), pattern.end());
        auto f = [] (int s) {
            string T;
            while (s > 0) {
                T += (s & 1 ? '1' : '0');
                s >>= 1;
            }
            reverse(ALL(T));
            return T;
        };
        deque<pair<int,int>> d;
        d.push_back({0,bit_table[0]});
        vector<vector<int>> dp(h,vector<int>(1<<w,0));
        dp[0][bit_table[0]]=1;
        for(int i=0;i<h-1;i++){
            for(int base = 0; base < (1<<w);base++){
                int nxt=bit_table[i+1];
                for(auto[from,to] :pattern){
                    if((base&from)==0&&(to&nxt)==0&&((base|from)==((1<<w)-1))){
                        dp[i+1][nxt|to]+=dp[i][base];
                        // cerr << i+1<<" "<<setw(8) << setfill('0') << f(from) << "\n" << i << " " << setw(8) << setfill('0') << f(to) <<endl;
                        // cerr << i+1<<" "<<setw(8) << setfill('0') << f(base) << " "<< setw(8) << setfill('0') << f(nxt) <<endl;

                        // cerr << i+1<<" "<<setw(8) << setfill('0') << f(base|from) << " "<< setw(8) << setfill('0') << f(to|nxt) <<endl;
                        // cerr<<endl;
                    }
                }
            }
        }
        cout<<dp[h-1][(1<<w)-1]<<endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3712
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long int;
using ld = long double;
using vl = vector<ll>;
using vvl = vector<vl>;
using vc=vector<char>;
using vvc=vector<vc>;
using pl = pair<ll,ll>;
#define rep(i,l,r) for(ll i=(l);i<(r);i++)
#define drep(i,l,r) for(ll i=(r)-1;i>=(l);i--)

vvc c(10,vc(10,'#'));
ll h,w;

pl decode(ll n){
    return {n/h,n%h};
    // column,row
}

bool put1(ll n){
    if(n/h==w-1||n%h==h-1)return false;
    if(c[n/h+1][n%h]=='#')return false;
    if(c[n/h+1][n%h+1]=='#')return false;
    c[n/h][n%h]='#';
    c[n/h+1][n%h]='#';
    c[n/h+1][n%h+1]='#';
    return true;
}

bool put2(ll n){
    if(n/h==w-1||n%h==h-1)return false;
    if(c[n/h][n%h+1]=='#')return false;
    if(c[n/h+1][n%h+1]=='#')return false;
    c[n/h][n%h]='#';
    c[n/h][n%h+1]='#';
    c[n/h+1][n%h+1]='#';
    return true;
}

bool put3(ll n){
    if(n/h==w-1||n%h==h-1)return false;
    if(c[n/h][n%h+1]=='#')return false;
    if(c[n/h+1][n%h]=='#')return false;
    c[n/h][n%h]='#';
    c[n/h][n%h+1]='#';
    c[n/h+1][n%h]='#';
    return true;
}

bool put4(ll n){
    if(n/h==w-1||n%h==0)return false;
    if(c[n/h+1][n%h]=='#')return false;
    if(c[n/h+1][n%h-1]=='#')return false;
    c[n/h][n%h]='#';
    c[n/h+1][n%h]='#';
    c[n/h+1][n%h-1]='#';
    return true;
}


void inv_put1(ll n){
    c[n/h][n%h]='.';
    c[n/h+1][n%h]='.';
    c[n/h+1][n%h+1]='.';
}

void inv_put2(ll n){
    c[n/h][n%h]='.';
    c[n/h][n%h+1]='.';
    c[n/h+1][n%h+1]='.';
}

void inv_put3(ll n){
    c[n/h][n%h]='.';
    c[n/h][n%h+1]='.';
    c[n/h+1][n%h]='.';
}

void inv_put4(ll n){
    c[n/h][n%h]='.';
    c[n/h+1][n%h]='.';
    c[n/h+1][n%h-1]='.';
}

ll f(ll k){
    ll l=k;
    ll ans=0;
   while(true){
    if(c[l/h][l%h]=='.'){
        bool sub1=put1(l);
        if(sub1){
        ans+=f(l);
        inv_put1(l);
        }
        bool sub2=put2(l);
        if(sub2){
        ans+=f(l);
        inv_put2(l);
        } 
        bool sub3=put3(l);
        if(sub3){
        ans+=f(l);
        inv_put3(l);
        }
        bool sub4=put4(l);
        if(sub4){
        ans+=f(l);
        inv_put4(l);
        }
        break;
    }
    else l++;    
    if(l>=h*w){
        ans=1;break;
    }
    }
    return ans;
}


int main(){
    while(true){
        rep(i,0,10){
            rep(j,0,10){
                c[i][j]='#';
            }
        }
       cin>>h>>w;
       if(h==0){
        break;
       }
       rep(i,0,h){
        rep(j,0,w){
            cin>>c[i][j];
        }
       }
       swap(h,w);
       cout<<f(0)<<endl;
    }
}
accuracy: 1
time_ms: 70
memory_kb: 3584
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

#include <atcoder/all>
using namespace atcoder;

using ll = long long;
using mint = modint998244353;

bool solving = true;

void solve() {
  int H, W;
  cin >> H >> W;
  if(H == 0 && W == 0) {
    solving = false;
    return;
  }
  vector A(H, vector<int>(W));
  for(int i = 0; i < H; i++) {
    string s;
    cin >> s;
    for(int j = 0; j < W; j++) {
      A[i][j] = (s[j] == '.');
    }
  }
  int ans = 0;
  auto dfs = [&](auto dfs, int ij) -> void {
    int i = ij / W, j = ij % W;
    if(ij == H * W) {
      ans++;
      return;
    }else {
      if(!A[i][j]) {
        dfs(dfs, ij + 1);
      }
      if(i + 1 < H && j + 1 < W && A[i][j] && A[i][j + 1] && A[i + 1][j]) {
        A[i][j] = A[i][j + 1] = A[i + 1][j] = 0;
        dfs(dfs, ij + 1);
        A[i][j] = A[i][j + 1] = A[i + 1][j] = 1;
      }
      if(i + 1 < H && j + 1 < W && A[i][j] && A[i][j + 1] && A[i + 1][j + 1]) {
        A[i][j] = A[i][j + 1] = A[i + 1][j + 1] = 0;
        dfs(dfs, ij + 1);
        A[i][j] = A[i][j + 1] = A[i + 1][j + 1] = 1;
      }
      if(i + 1 < H && j + 1 < W && A[i][j] && A[i + 1][j] && A[i + 1][j + 1]) {
        A[i][j] = A[i + 1][j] = A[i + 1][j + 1] = 0;
        dfs(dfs, ij + 1);
        A[i][j] = A[i + 1][j] = A[i + 1][j + 1] = 1;
      }
      if(i + 1 < H && j - 1 >= 0 && A[i][j] && A[i + 1][j] && A[i + 1][j - 1]) {
        A[i][j] = A[i + 1][j] = A[i + 1][j - 1] = 0;
        dfs(dfs, ij + 1);
        A[i][j] = A[i + 1][j] = A[i + 1][j - 1] = 1;
      }
    }
  };
  dfs(dfs, 0);
  cout << ans << endl;
}

int main() {
  while(solving) solve();
}
accuracy: 1
time_ms: 30
memory_kb: 3584
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__)
#define OVERLOAD_REP(_1, _2, _3, _4, name, ...) name
#define REP1(n) for(ll i=0;i<(n);i++)
#define REP2(i, n) for (ll i=0;i<(n);i++)
#define REP3(i, a, n) for (ll i=a;i<(n);i++)
#define REP4(i, a, b, n) for(ll i=a;i<(n);i+=b)
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define OVERLOAD_RREP(_1, _2, _3, _4, name, ...) name
#define RREP1(n) for(ll i=(n)-1;i>=0;i--)
#define RREP2(i, n) for(ll i=(n)-1;i>=0;i--)
#define RREP3(i, a, n) for(ll i=(n)-1;i>=(a);i--)
#define RREP4(i, a, b, n) for(ll i=(n)-1;i>=(a);i-=(b))
#define rrep(...) OVERLOAD_RREP(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define len(n) (long long)(n).size()
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vs = vector<string>;
using vvs = vector<vs>;
using vvvs = vector<vvs>;
using vld = vector<ld>;
using vvld = vector<vld>;
using vvvld = vector<vvld>;
using vc = vector<char>;
using vvc = vector<vc>;
using vvvc = vector<vvc>;
using pll = pair<ll,ll>;
using vpll = vector<pll>;
using vvpll = vector<vpll>;

ll intpow(ll a,ll b){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
        }
        a *= a;
        b /= 2;
    }
    return ans;
}
ll modpow(ll a,ll b,ll c){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
            ans %= c;
        }
        a *= a;
        a %= c;
        b /= 2;
    }
    return ans;
}

template<class... T>
void input(T&... a){
    (cin >> ... >> a);
}

#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHA(...) char __VA_ARGS__; input(__VA_ARGS__)
#define VLL(name,length) vll name(length);rep(i,length){cin >> name[i];}
#define VVLL(name,h,w) vvll name(h,vll(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLL(name,a,b,c) vvvll name(a,vvll(b,vll(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VI(name,length) vi name(length);rep(i,length){cin >> name[i];}
#define VVI(name,h,w) vvi name(h,vi(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVI(name,a,b,c) vvvi name(a,vvll(b,vi(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VLD(name,length) vld name(length);rep(i,length){cin >> name[i];}
#define VVLD(name,h,w) vvld name(h,vld(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLD(name,a,b,c) vvvld name(a,vvld(b,vld(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VC(name,length) vc name(length);rep(i,length){cin >> name[i];}
#define VVC(name,h,w) vvc name(h,vc(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVC(name,a,b,c) vvvc name(a,vvc(b,vc(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VS(name,length) vs name(length);rep(i,length){cin >> name[i];}
#define VVS(name,h,w) vvs name(h,vs(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVS(name,a,b,c) vvvs name(a,vvs(b,vs(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define PLL(name) pll name;cin>>name.first>>name.second;
#define VPLL(name,length) vpll name(length);rep(i,length){cin>>name[i].first>>name[i].second;}

void print(){cout << "\n";}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
    os << "[";
    for (size_t i = 0; i < vec.size(); ++i) {
        os << vec[i];
        if (i + 1 < vec.size()) os << ", ";
    }
    os << "]";
    return os;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::vector<std::pair<T1, T2>>& a) {
    os << "[";
    for (size_t j = 0; j < a.size(); ++j) {
        os << "(" << a[j].first << ", " << a[j].second << ")";
		if (j + 1 < a.size()) os << ", ";
    }
	os << "]";
    return os;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<std::pair<T1, T2>>>& mat) {
	os << "[";
    for (size_t i = 0; i < mat.size(); ++i) {
		os << "[";
        for (size_t j = 0; j < mat[i].size(); ++j) {
            os << "(" << mat[i][j].first << ", " << mat[i][j].second << ")";
			if (j + 1 < mat[i].size()) os << ", ";
        }
		os << "]";
		if (i + 1 < mat.size()) os << ", ";
    }
	os << "]";
    return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::set<T>& s) {
    os << "{";
    bool first = true;
    for (const auto& x : s) {
        if (!first) os << ", ";
        os << x;
        first = false;
    }
    os << "}";
    return os;
}

template <typename K, typename V>
std::ostream& operator<<(std::ostream& os, const std::map<K, V>& m) {
    os << "{";
    bool first = true;
    for (const auto& [key, val] : m) {
        if (!first) os << ", ";
        os << key << ": " << val;
        first = false;
    }
    os << "}";
    return os;
}

template<class T, class... Ts>
void print(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}

void write(){cout << "\n";}
template<class T, class... Ts>
void write(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}
void write(vll x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vi x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvi x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvi x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(vld x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvld x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvld x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(vc x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvc x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvc x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(vs x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvs x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvs x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(pll x){cout << x.first << ' ' << x.second << '\n';}
void write(vpll x){rep(i,len(x)){cout << x[i].first << ' ' << x[i].second << '\n';}}
void write(vvpll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j].first << ' ' << x[i][j].second;if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}

template <typename T>
T sum(const std::vector<T>& v) {
    return std::accumulate(v.begin(), v.end(), T(0));
}

template<class T> bool chmin(T& a, const T& b){ if(a > b){ a = b; return 1; } return 0; }
template<class T> bool chmax(T& a, const T& b){ if(a < b){ a = b; return 1; } return 0; }
template<class T, class U> bool chmin(T& a, const U& b){ if(a > T(b)){ a = b; return 1; } return 0; }
template<class T, class U> bool chmax(T& a, const U& b){ if(a < T(b)){ a = b; return 1; } return 0; }

long long mod_mul(long long a, long long b, long long mod) {
    return (__int128)a * b % mod;
}

long long mod_pow(long long a, long long b, long long mod) {
    long long result = 1;
    a %= mod;
    while (b > 0) {
        if (b & 1) result = mod_mul(result, a, mod);
        a = mod_mul(a, a, mod);
        b >>= 1;
    }
    return result;
}

bool MillerRabin(ll x){
    
    if(x <= 1){return false;}
    if(x == 2){return true;}
    if((x & 1) == 0){return false;}
    vll test;
    if(x < (1 << 30)){
        test = {2, 7, 61};
    } 
    else{
        test = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};
    }
    ll s = 0;
    ll d = x - 1;
    while((d & 1) == 0){
        s++;
        d >>= 1;
    }
    for(ll i:test){
        if(x <= i){return true;}
        ll y = mod_pow(i,d,x);
        if(y == 1 || y == x - 1){continue;}
        ll c = 0;
        for(int j=0;j<s-1;j++){
            y = mod_mul(y,y,x);
            if(y == x - 1){
                c = 1;
                break;
            }
        }
        if(c == 0){
            return false;
        }
    }
    return true;
}

#include<atcoder/dsu>
vpll rle(vll seq){
    vpll res;
    for(auto x:seq){
        if(res.empty() || res.back().first != x){
            res.emplace_back(x,1);
        }
        else{
            res.back().second++;
        }
    }
    return res;
}
int main(){
	ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
    vvpll a(10);
    rep(n,2,9){
        auto dfs = [&](auto dfs, vll s){
            if(len(s) == n){
                ll b = 0;
                ll c = 0;
                ll d = 1;
                rep(i,n){
                    ll x = s[i];
                    if(x == 0){
                        ;
                    }
                    if(x == 1){
                        if(((b >> i) & 1) == 1){
                            d = 0;
                        }
                        if(((b >> (i+1)) & 1) == 1){
                            d = 0;
                        }
                        if(((c >> i) & 1) == 1){
                            d = 0;
                        }
                        
                        b |= 1 << i;
                        b |= 1 << (i+1);
                        c |= 1 << i;

                        if(i+1 >= n){
                            d = 0;
                        }
                    }
                    if(x == 2){
                        if(((b >> i) & 1) == 1){
                            d = 0;
                        }
                        if(((b >> (i+1)) & 1) == 1){
                            d = 0;
                        }
                        if(((c >> (i+1)) & 1) == 1){
                            d = 0;
                        }
                        
                        b |= 1 << i;
                        b |= 1 << (i+1);
                        c |= 1 << (i+1);
                        
                        if(i+1 >= n){
                            d = 0;
                        }
                    }
                    if(x == 3){
                        if(((b >> i) & 1) == 1){
                            d = 0;
                        }
                        if(((c >> (i+1)) & 1) == 1){
                            d = 0;
                        }
                        if(((c >> i) & 1) == 1){
                            d = 0;
                        }
                        
                        b |= 1 << i;
                        c |= 1 << (i+1);
                        c |= 1 << i;
                        
                        if(i+1 >= n){
                            d = 0;
                        }
                    }
                    if(x == 4){
                        if(((b >> (i+1)) & 1) == 1){
                            d = 0;
                        }
                        if(((c >> (i+1)) & 1) == 1){
                            d = 0;
                        }
                        if(((c >> i) & 1) == 1){
                            d = 0;
                        }
                        
                        b |= 1 << (i+1);
                        c |= 1 << (i+1);
                        c |= 1 << i;
                        
                        if(i+1 >= n){
                            d = 0;
                        }
                    }
                    
                }
                if(d){
                    a[n].emplace_back(b,c);
                }
                return;
            }
            rep(i,5){
                s.push_back(i);
                dfs(dfs,s);
                s.pop_back();
            }
            return;
        };
        dfs(dfs,vll(0));
    }
    
    while(1){
        LL(h,w);
        if(h == 0 && w == 0){break;}
        VS(s,h);
        vvll dp(h,vll(1<<w,0));
        vll v(h,0);
        rep(i,h){
            rep(j,w){
                if(s[i][j] == '#'){
                    v[i] |= (1LL << j);
                }
            }
        }
        dp[0][v[0]] = 1;
        rep(i,h-1){
            rep(j,(1LL<<w)){
                for(auto [x,y]:a[w]){
                    if((x & j) == 0 && (y & v[i+1]) == 0 && (x | j) == ((1LL << w) - 1)){
                        dp[i+1][y | v[i+1]] += dp[i][j];
                    }
                }
            }
        }
        print(dp.back().back());
    }
    
}
accuracy: 1
time_ms: 60
memory_kb: 3584
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;

vector<string> a;
int h,w;
map<vector<string>, int> m;

int solve(vector<string> s){
    // for(int i=0;i<h;i++){
    //     cout << s.at(i) << endl;
    // }
    if(m.count(s)){
        return m[s];
    }
    int si = -1, sj = -1;
    bool f = true;
    for(int i=0;i<h;i++){
        if(!f) break;
        for(int j=0;j<w;j++){
            if(s.at(i).at(j) != '#'){
                si = i;
                sj = j;
                f = false;
                break;
            }
        }
    }
    // cout << si << ' ' << sj << endl;
    if(si == -1){
        m[s] = 1;
        return 1;
    }
    int cnt = 0;
    if(sj < w-1 && si < h-1 && s.at(si+1).at(sj+1) == '.' && s.at(si).at(sj+1) == '.'){
        s.at(si).at(sj) = '#';
        s.at(si+1).at(sj+1) = '#';
        s.at(si).at(sj+1) = '#';
        cnt += solve(s);
        s.at(si+1).at(sj+1) = '.';
        s.at(si).at(sj+1) = '.';
        s.at(si).at(sj) = '.';
    }
    if(sj < w-1 && si < h-1 && s.at(si+1).at(sj+1) == '.' && s.at(si+1).at(sj) == '.'){
        s.at(si+1).at(sj+1) = '#';
        s.at(si+1).at(sj) = '#';
        s.at(si).at(sj) = '#';
        cnt += solve(s);
        s.at(si+1).at(sj+1) = '.';
        s.at(si+1).at(sj) = '.';
        s.at(si).at(sj) = '.';
    }
    if(sj > 0 && si < h-1 && s.at(si+1).at(sj-1) == '.' && s.at(si+1).at(sj) == '.'){
        s.at(si+1).at(sj-1) = '#';
        s.at(si+1).at(sj) = '#';
        s.at(si).at(sj) = '#';
        cnt += solve(s);
        s.at(si+1).at(sj-1) = '.';
        s.at(si+1).at(sj) = '.';
        s.at(si).at(sj) = '.';
    }
    if(sj < w-1 && si < h-1 && s.at(si).at(sj+1) == '.' && s.at(si+1).at(sj) == '.'){
        s.at(si+1).at(sj) = '#';
        s.at(si).at(sj+1) = '#';
        s.at(si).at(sj) = '#';
        cnt += solve(s);
        s.at(si+1).at(sj) = '.';
        s.at(si).at(sj+1) = '.';
        s.at(si).at(sj) = '.';
    }
    m[s] = cnt;
    return cnt;
}

int main() {
    while(true){
        a.clear();
        m.clear();
        cin >> h >> w;
        if(h == 0 && w == 0) break;
        a.resize(h);
        for(int i=0;i<h;i++){
            cin >> a.at(i);
        }
        int ans = solve(a);
        cout << ans << endl;
    }
    
}
accuracy: 1
time_ms: 10
memory_kb: 4224
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

int dfs(vector<string>& room, int x, int y, int h, int w) {
    if (x == h - 1) {
        return all_of(room[h - 1].begin(), room[h - 1].end(), [](char c) { return c == '#'; }) ? 1 : 0;
    }
    
    if (room[x][y] == '#') {
        if (y == w - 1) return dfs(room, x + 1, 0, h, w);
        else return dfs(room, x, y + 1, h, w);
    }
    
    int ways = 0;
    if (y + 1 < w && room[x + 1][y] == '.' && room[x + 1][y + 1] == '.') {
        room[x + 1][y] = room[x + 1][y + 1] = room[x][y] = '#';
        ways += dfs(room, x, y + 1, h, w);
        room[x + 1][y] = room[x + 1][y + 1] = room[x][y] = '.';
    }
    if (y + 1 < w && room[x + 1][y] == '.' && room[x][y + 1] == '.') {
        room[x + 1][y] = room[x][y + 1] = room[x][y] = '#';
        ways += dfs(room, x, y + 1, h, w);
        room[x + 1][y] = room[x][y + 1] = room[x][y] = '.';
    }
    if (y + 1 < w && room[x + 1][y + 1] == '.' && room[x][y + 1] == '.') {
        room[x + 1][y + 1] = room[x][y + 1] = room[x][y] = '#';
        ways += dfs(room, x, y + 1, h, w);
        room[x + 1][y + 1] = room[x][y + 1] = room[x][y] = '.';
    }
    if (y - 1 >= 0 && room[x + 1][y - 1] == '.' && room[x + 1][y] == '.') {
        room[x + 1][y - 1] = room[x + 1][y] = room[x][y] = '#';
        if (y == w - 1) ways += dfs(room, x + 1, 0, h, w);
        else ways += dfs(room, x, y + 1, h, w);
        room[x + 1][y - 1] = room[x + 1][y] = room[x][y] = '.';
    }
    
    return ways;
}

int main() {
    int h, w;
    while (cin >> h >> w, h) {
        vector<string> room(h);
        for (int i = 0; i < h; ++i) cin >> room[i];
        cout << dfs(room, 0, 0, h, w) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3328
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<vvb> vvvb;
typedef vector<vvvb> vvvvb;
typedef pair<ll,ll> pi;
typedef pair<ll,pi> ppi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define RFOR(i,l,r) for(ll i=r-1;i>=l;i--)
#define RREP(i,n) RFOR(i,0,n)
#define sz(A) (ll)(A.size())
#define ALL(A) A.begin(),A.end()
#define LB(A,x) (ll)(lower_bound(ALL(A),x)-A.begin())
#define UB(A,x) (ll)(upper_bound(ALL(A),x)-A.begin())
#define COU(A,x) (UB(A,x)-LB(A,x))
#define F first
#define S second
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<typename T1,typename T2>ostream&operator<<(ostream&os,pair<T1,T2>&p){os<<p.F<<" "<<p.S;return os;}
template<typename T1,typename T2>istream&operator>>(istream&is,pair<T1,T2>&p){is>>p.F>>p.S;return is;}
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){REP(i,sz(v))os<<v[i]<<(i+1!=sz(v)?" ":"");return os;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(T&in:v)is>>in;return is;}
template<class T>bool chmax(T&a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T&a,T b){if(b<a){a=b;return 1;}return 0;}
const ll mod=998244353;
template<const long long int mod=998244353>
struct modint{
  using mint=modint<mod>;
  long long int x;
  modint(long long int _x=0):x(_x%mod){if(x<0)x+=mod;}
  long long int val(){return x;}
  mint&operator=(const mint&a){x=a.x;return *this;}
  mint&operator+=(const mint&a){x+=a.x;if(x>=mod)x-=mod;return *this;}
  mint&operator-=(const mint&a){x-=a.x;if(x<0)x+=mod;return *this;}
  mint&operator*=(const mint&a){x*=a.x;x%=mod;return *this;}
  friend mint operator+(const mint&a,const mint&b){return mint(a)+=b;}
  friend mint operator-(const mint&a,const mint&b){return mint(a)-=b;}
  friend mint operator*(const mint&a,const mint&b){return mint(a)*=b;}
  mint operator-()const{return mint(0)-*this;}
  mint pow(long long int n){
    if(!n)return 1;
    mint a=1;
    mint _x=x;
    while(n){
      if(n&1)a*=_x;
      _x=_x*_x;n>>=1;
    }
    return a;
  }
  mint inv(){return pow(mod-2);}
  mint&operator/=(mint&a){return *this*=a.inv();}
  friend mint operator/(const mint&a,mint b){return mint(a)/=b;}
};
using mint=modint<998244353>;
int main(){
    vvvi pe={
        {{0,0},{0,0}},
        {{1,1},{1,0}},
        {{1,1},{0,1}},
        {{1,0},{1,1}},
        {{0,1},{1,1}}
    };
    vvi tr(1<<8);
    REP(i,pow(5,7)){
        ll n=i;
        vvi A(2,vi(8));
        REP(j,7){
            REP(k,2)REP(l,2)A[k][j+l]+=pe[n%5][k][l];
            n/=5;
        }
        bool ok=1;
        REP(i,2)REP(j,8)if(A[i][j]>1)ok=0;
        if(!ok)continue;
        ll m=0;
        REP(j,8){
            if(A[0][j])n+=1<<j;
            if(A[1][j])m+=1<<j;
        }
        tr[n].emplace_back(m);
    }
    while(1){
        ll H,W;cin>>H>>W;
        if(!H)return 0;
        vector<string>A(H);cin>>A;
        vi G(H);
        REP(i,H)REP(j,W)if(A[i][j]=='#')G[i]+=1<<j;
        vvi DP(H,vi(1<<W));
        DP[0][G[0]]=1;
        FOR(i,1,H)REP(j,1<<W)for(auto k:tr[(1<<W)-1-j])if(k<(1<<W))if((k&G[i])==0){
            DP[i][k+G[i]]+=DP[i-1][j];
        }
        cout<<DP[H-1].back()<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3364
final_rank: 1

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

template <unsigned mod = 1000000007> struct fp {
    unsigned v;
    static constexpr int get_mod() {
        return mod;
    }
    constexpr unsigned inv() const {
        assert(v != 0);
        int x = v, y = mod, p = 1, q = 0, t = 0, tmp = 0;
        while (y > 0) {
            t = x / y;
            x -= t * y, p -= t * q;
            tmp = x, x = y, y = tmp;
            tmp = p, p = q, q = tmp;
        }
        if (p < 0)
            p += mod;
        return p;
    }
    constexpr fp(ll x = 0) : v(x >= 0 ? x % mod : (mod - (-x) % mod) % mod) {}
    fp operator-() const {
        return fp() - *this;
    }
    fp pow(ull t) {
        fp res = 1, b = *this;
        while (t) {
            if (t & 1)
                res *= b;
            b *= b;
            t >>= 1;
        }
        return res;
    }
    fp &operator+=(const fp &x) {
        if ((v += x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator-=(const fp &x) {
        if ((v += mod - x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator*=(const fp &x) {
        v = ull(v) * x.v % mod;
        return *this;
    }
    fp &operator/=(const fp &x) {
        v = ull(v) * x.inv() % mod;
        return *this;
    }
    fp operator+(const fp &x) const {
        return fp(*this) += x;
    }
    fp operator-(const fp &x) const {
        return fp(*this) -= x;
    }
    fp operator*(const fp &x) const {
        return fp(*this) *= x;
    }
    fp operator/(const fp &x) const {
        return fp(*this) /= x;
    }
    bool operator==(const fp &x) const {
        return v == x.v;
    }
    bool operator!=(const fp &x) const {
        return v != x.v;
    }
    friend istream &operator>>(istream &is, fp &x) {
        return is >> x.v;
    }
    friend ostream &operator<<(ostream &os, const fp &x) {
        return os << x.v;
    }
};

template <unsigned mod> void rd(fp<mod> &x) {
    fastio::rd(x.v);
}
template <unsigned mod> void wt(fp<mod> x) {
    fastio::wt(x.v);
}

template <typename T> T Inv(ll n) {
    static const int md = T::get_mod();
    static vector<T> buf({0, 1});
    assert(n > 0);
    n %= md;
    while (SZ(buf) <= n) {
        int k = SZ(buf), q = (md + k - 1) / k;
        buf.push_back(buf[k * q - md] * q);
    }
    return buf[n];
}

template <typename T> T Fact(ll n, bool inv = 0) {
    static const int md = T::get_mod();
    static vector<T> buf({1, 1}), ibuf({1, 1});
    assert(n >= 0 and n < md);
    while (SZ(buf) <= n) {
        buf.push_back(buf.back() * SZ(buf));
        ibuf.push_back(ibuf.back() * Inv<T>(SZ(ibuf)));
    }
    return inv ? ibuf[n] : buf[n];
}

template <typename T> T nPr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nCr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(r, inv ^ 1) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nHr(int n, int r, bool inv = 0) {
    return nCr<T>(n + r - 1, r, inv);
}

/**
 * @brief Modint
 */

int X[5][2][2] = {};

int main() {
rep(i,1,5) rep(j,0,2) rep(k,0,2) X[i][j][k] = 1;
X[1][0][0] = X[2][0][1] = X[3][1][0] = X[4][1][1] = 0;
while(1) {
    int N, M;
    cin >> N >> M;
    if (N == 0 && M == 0) return 0;
    int D = 1;
    rep(i,0,M-1) D *= 5;
    vector<vector<ll>> V(1<<M, vector<ll>(1<<M,0));
    rep(i,0,D) {
        vector<int> E(M-1);
        int I = i;
        rep(j,0,M-1) E[j] = I % 5, I /= 5;
        vector<vector<int>> COUNT(2, vector<int>(M,0));
        rep(j,0,M-1) {
            rep(k,0,2) {
                rep(l,0,2) {
                    COUNT[k][j+l] += X[E[j]][k][l];
                }
            }
        }
        bool check = true;
        rep(j,0,2) {
            rep(k,0,M) {
                if (COUNT[j][k] >= 2) check = false;
            }
        }
        if (!check) continue;
        int SUM[2] = {};
        rep(j,0,2) {
            rep(k,0,M) {
                SUM[j] += COUNT[j][k] * (1<<k);
            }
        }
        V[SUM[0]][SUM[1]]++;
    }
    vector<int> S(N);
    rep(i,0,N) {
        string T;
        cin >> T;
        int Cur = 0;
        rep(j,0,M) {
            if (T[j] == '#') Cur += (1<<j);
        }
        S[i] = Cur;
    }
    vector<ll> DP(1<<M,0);
    DP[S[0]] = 1;
    rep(i,0,N-1) {
        vector<ll> NewDP(1<<M,0);
        rep(j,0,1<<M) {
            rep(k,0,1<<M) {
                if ((k & S[i+1]) != 0) continue;
                NewDP[k | S[i+1]] += DP[j] * V[(1<<M)-1-j][k];
            }
        }
        rep(j,0,1<<M) DP[j] = NewDP[j];
    }
    cout << DP[(1<<M)-1] << endl;
}
}
accuracy: 1
time_ms: 170
memory_kb: 3620
final_rank: 15

code_snippet: #include <iostream>
#include <vector>
#include <string>

int H, W;

std::vector<std::vector<std::pair<int, int>>> piece = {
    {{0, 0}, {0, 1}, {1, 1}},
    {{0, 0}, {1, 0}, {0, 1}},
    {{0, 0}, {1, 0}, {1, 1}},
    {{0, 0}, {1, 0}, {1, -1}},
};

int dfs(std::vector<std::vector<int>> &used)
{
    int x = -1, y = -1;
    for (int i = 0; i < H && x == -1; i++)
    {
        for (int j = 0; j < W && x == -1; j++)
        {
            if (!used[i][j])
            {
                x = i;
                y = j;
                break;
            }
        }
    }
    if (x == -1)
    {
        return 1;
    }

    int ans = 0;
    for (auto &pp : piece)
    {
        bool ok = true;
        for (auto &[i, j] : pp)
        {
            if (0 <= x + i && x + i < H && 0 <= y + j && y + j < W && !used[x + i][y + j])
            {
            }
            else
            {
                ok = false;
            }
        }
        if (ok)
        {
            for (auto &[i, j] : pp)
                used[x + i][y + j] = 1;
            ans += dfs(used);
            for (auto &[i, j] : pp)
                used[x + i][y + j] = 0;
        }
    }
    return ans;
}

int main()
{
    while (std::cin >> H >> W, H && W)
    {
        std::vector<std::vector<int>> used(H, std::vector<int>(W));
        for (int i = 0; i < H; i++)
        {
            std::string s;
            std::cin >> s;
            for (int j = 0; j < W; j++)
            {
                used[i][j] = s[j] == '#';
            }
        }
        std::cout << dfs(used) << std::endl;
    }
}
accuracy: 1
time_ms: 150
memory_kb: 3356
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
    while (true) {
        int h, w;
        cin >> h >> w;
        if (h == 0) {
            return 0;
        }
        vector<string> s(h);

        for (int i = 0; i < h; i++) {
            cin >> s[i];
        }

        function<int(int, int, vector<string>)> dfs =
            [&](int x, int y, vector<string> s) {
                if (x == h) {
                    return 1;
                }
                if (y == w) {
                    return dfs(x + 1, 0, s);
                }
                if (s[x][y] == '#') {
                    return dfs(x, y + 1, s);
                }

                int sum = 0;

                if (x + 1 < h && y - 1 >= 0 && s[x + 1][y] == '.'
                    && s[x + 1][y - 1] == '.') {
                    s[x][y] = s[x + 1][y] = s[x + 1][y - 1] = '#';
                    sum += dfs(x, y + 1, s);
                    s[x][y] = s[x + 1][y] = s[x + 1][y - 1] = '.';
                }

                if (x + 1 < h && y + 1 < w && s[x + 1][y] == '.'
                    && s[x + 1][y + 1] == '.') {
                    s[x][y] = s[x + 1][y] = s[x + 1][y + 1] = '#';
                    sum += dfs(x, y + 1, s);
                    s[x][y] = s[x + 1][y] = s[x + 1][y + 1] = '.';
                }

                if (x + 1 < h && y + 1 < w && s[x][y + 1] == '.'
                    && s[x + 1][y + 1] == '.') {
                    s[x][y] = s[x][y + 1] = s[x + 1][y + 1] = '#';
                    sum += dfs(x, y + 1, s);
                    s[x][y] = s[x][y + 1] = s[x + 1][y + 1] = '.';
                }

                if (x + 1 < h && y < w && s[x + 1][y] == '.'
                    && s[x][y + 1] == '.') {
                    s[x][y] = s[x + 1][y] = s[x][y + 1] = '#';
                    sum += dfs(x, y + 1, s);
                    s[x][y] = s[x + 1][y] = s[x][y + 1] = '.';
                }

                return sum;
            };

        cout << dfs(0, 0, s) << endl;
    }
}
accuracy: 1
time_ms: 540
memory_kb: 3392
final_rank: 16

code_snippet: // #include "my_template.hpp"
// using namespace std;
// 
// void solve(int H, int W) {
//     VEC(string, S, H);
//     int ans = 0;
// 
//     auto rec = [&](auto f, int i, int j) -> void {
//         // show(i);
//         // show(j);
//         // show(S);
//         if (j == W) {
//             f(f, i + 1, 0);
//             return;
//         }
//         if (i == H) {
//             ans++;
//             return;
//         }
//         if (S[i][j] == '#') {
//             f(f, i, j + 1);
//             return;
//         }
//         // ##
//         // #.
//         if (i + 1 < H and j + 1 < W and S[i + 1][j] == '.' and S[i][j + 1] == '.') {
//             S[i][j] = '#';
//             S[i + 1][j] = '#';
//             S[i][j + 1] = '#';
//             f(f, i, j + 1);
//             S[i][j] = '.';
//             S[i + 1][j] = '.';
//             S[i][j + 1] = '.';
//         }
//         // ##
//         // .#
//         if (i + 1 < H and j + 1 < W and S[i][j + 1] == '.' and S[i + 1][j + 1] == '.') {
//             S[i][j] = '#';
//             S[i][j + 1] = '#';
//             S[i + 1][j + 1] = '#';
//             f(f, i, j + 1);
//             S[i][j] = '.';
//             S[i][j + 1] = '.';
//             S[i + 1][j + 1] = '.';
//         }
//         // #.
//         // ##
//         if (i + 1 < H and j + 1 < W and S[i + 1][j] == '.' and S[i + 1][j + 1] == '.') {
//             S[i][j] = '#';
//             S[i + 1][j] = '#';
//             S[i + 1][j + 1] = '#';
//             f(f, i, j + 1);
//             S[i][j] = '.';
//             S[i + 1][j] = '.';
//             S[i + 1][j + 1] = '.';
//         }
//         // .#
//         // ##
//         if (i + 1 < H and j - 1 >= 0 and S[i + 1][j - 1] == '.' and S[i + 1][j] == '.') {
//             S[i][j] = '#';
//             S[i + 1][j - 1] = '#';
//             S[i + 1][j] = '#';
//             f(f, i, j + 1);
//             S[i][j] = '.';
//             S[i + 1][j - 1] = '.';
//             S[i + 1][j] = '.';
//         }
//         return;
//     };
//     rec(rec, 0, 0);
//     print(ans);
//     return;
// }
// 
// int main() {
//     int H, W;
//     while (cin >> H >> W, H != 0) solve(H, W);
//     return 0;
// }
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <deque>
#include <forward_list>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#ifdef RUTHEN_LOCAL
#include <debug.hpp>
#else
#define show(x) true
#endif

// type definition
using i64 = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using f32 = float;
using f64 = double;
using f128 = long double;
template <class T> using pque = std::priority_queue<T>;
template <class T> using pqueg = std::priority_queue<T, std::vector<T>, std::greater<T>>;
// overload
#define overload4(_1, _2, _3, _4, name, ...) name
#define overload3(_1, _2, _3, name, ...) name
#define overload2(_1, _2, name, ...) name
// for loop
#define REP1(a) for (long long _ = 0; _ < (a); _++)
#define REP2(i, a) for (long long i = 0; i < (a); i++)
#define REP3(i, a, b) for (long long i = (a); i < (b); i++)
#define REP4(i, a, b, c) for (long long i = (a); i < (b); i += (c))
#define REP(...) overload4(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define RREP1(a) for (long long _ = (a)-1; _ >= 0; _--)
#define RREP2(i, a) for (long long i = (a)-1; i >= 0; i--)
#define RREP3(i, a, b) for (long long i = (b)-1; i >= (a); i--)
#define RREP(...) overload3(__VA_ARGS__, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define FORE1(x, a) for (auto&& x : a)
#define FORE2(x, y, a) for (auto&& [x, y] : a)
#define FORE3(x, y, z, a) for (auto&& [x, y, z] : a)
#define FORE(...) overload4(__VA_ARGS__, FORE3, FORE2, FORE1)(__VA_ARGS__)
#define FORSUB(t, s) for (long long t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
// function
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define SORT(a) std::sort((a).begin(), (a).end())
#define RSORT(a) std::sort((a).rbegin(), (a).rend())
#define REV(a) std::reverse((a).begin(), (a).end())
#define UNIQUE(a)                      \
    std::sort((a).begin(), (a).end()); \
    (a).erase(std::unique((a).begin(), (a).end()), (a).end())
#define LEN(a) (int)((a).size())
#define MIN(a) *std::min_element((a).begin(), (a).end())
#define MAX(a) *std::max_element((a).begin(), (a).end())
#define SUM1(a) std::accumulate((a).begin(), (a).end(), 0LL)
#define SUM2(a, x) std::accumulate((a).begin(), (a).end(), (x))
#define SUM(...) overload2(__VA_ARGS__, SUM2, SUM1)(__VA_ARGS__)
#define LB(a, x) std::distance((a).begin(), std::lower_bound((a).begin(), (a).end(), (x)))
#define UB(a, x) std::distance((a).begin(), std::upper_bound((a).begin(), (a).end(), (x)))
template <class T, class U> inline bool chmin(T& a, const U& b) { return (a > T(b) ? a = b, 1 : 0); }
template <class T, class U> inline bool chmax(T& a, const U& b) { return (a < T(b) ? a = b, 1 : 0); }
template <class T, class S> inline T floor(const T x, const S y) {
    assert(y);
    return (y < 0 ? floor(-x, -y) : (x > 0 ? x / y : x / y - (x % y == 0 ? 0 : 1)));
}
template <class T, class S> inline T ceil(const T x, const S y) {
    assert(y);
    return (y < 0 ? ceil(-x, -y) : (x > 0 ? (x + y - 1) / y : x / y));
}
template <class T, class S> std::pair<T, T> inline divmod(const T x, const S y) {
    T q = floor(x, y);
    return {q, x - q * y};
}
// 10 ^ n
constexpr long long TEN(int n) { return (n == 0) ? 1 : 10LL * TEN(n - 1); }
// 1 + 2 + ... + n
#define TRI1(n) ((n) * ((n) + 1LL) / 2)
// l + (l + 1) + ... + r
#define TRI2(l, r) (((l) + (r)) * ((r) - (l) + 1LL) / 2)
#define TRI(...) overload2(__VA_ARGS__, TRI2, TRI1)(__VA_ARGS__)
// bit operation
// bit[i] (= 0 or 1)
#define IBIT(bit, i) (((bit) >> (i)) & 1)
// (0, 1, 2, 3, 4) -> (0, 1, 3, 7, 15)
#define MASK(n) ((1LL << (n)) - 1)
#define POW2(n) (1LL << (n))
// (0, 1, 2, 3, 4) -> (0, 1, 1, 2, 1)
int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(i64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(i64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
// binary search
template <class T, class F> T bin_search(T ok, T ng, F& f) {
    while ((ok > ng ? ok - ng : ng - ok) > 1) {
        T md = (ng + ok) >> 1;
        (f(md) ? ok : ng) = md;
    }
    return ok;
}
template <class T, class F> T bin_search_real(T ok, T ng, F& f, const int iter = 100) {
    for (int _ = 0; _ < iter; _++) {
        T md = (ng + ok) / 2;
        (f(md) ? ok : ng) = md;
    }
    return ok;
}
// rotate matrix counterclockwise by pi / 2
template <class T> void rot(std::vector<std::vector<T>>& a) {
    if ((int)(a.size()) == 0) return;
    if ((int)(a[0].size()) == 0) return;
    int n = (int)(a.size()), m = (int)(a[0].size());
    std::vector res(m, std::vector<T>(n));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            res[m - 1 - j][i] = a[i][j];
        }
    }
    a.swap(res);
}
// const value
constexpr int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
constexpr int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
// infinity
template <class T> constexpr T INF = 0;
template <> constexpr int INF<int> = 1'000'000'000;                 // 1e9
template <> constexpr i64 INF<i64> = i64(INF<int>) * INF<int> * 2;  // 2e18
template <> constexpr u32 INF<u32> = INF<int>;                      // 1e9
template <> constexpr u64 INF<u64> = INF<i64>;                      // 2e18
template <> constexpr f32 INF<f32> = INF<i64>;                      // 2e18
template <> constexpr f64 INF<f64> = INF<i64>;                      // 2e18
template <> constexpr f128 INF<f128> = INF<i64>;                    // 2e18
// I/O
// input
template <class T> std::istream& operator>>(std::istream& is, std::vector<T>& v) {
    for (auto&& i : v) is >> i;
    return is;
}
template <class... T> void in(T&... a) { (std::cin >> ... >> a); }
void scan() {}
template <class Head, class... Tail> void scan(Head& head, Tail&... tail) {
    in(head);
    scan(tail...);
}
// input macro
#define INT(...)     \
    int __VA_ARGS__; \
    scan(__VA_ARGS__)
#define I64(...)     \
    i64 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define U32(...)     \
    u32 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define U64(...)     \
    u64 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define F32(...)     \
    f32 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define F64(...)     \
    f64 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define F128(...)     \
    f128 __VA_ARGS__; \
    scan(__VA_ARGS__)
#define STR(...)             \
    std::string __VA_ARGS__; \
    scan(__VA_ARGS__)
#define CHR(...)      \
    char __VA_ARGS__; \
    scan(__VA_ARGS__)
#define VEC(type, name, size)     \
    std::vector<type> name(size); \
    scan(name)
#define VEC2(type, name1, name2, size)          \
    std::vector<type> name1(size), name2(size); \
    for (int i = 0; i < size; i++) scan(name1[i], name2[i])
#define VEC3(type, name1, name2, name3, size)                \
    std::vector<type> name1(size), name2(size), name3(size); \
    for (int i = 0; i < size; i++) scan(name1[i], name2[i], name3[i])
#define VEC4(type, name1, name2, name3, name4, size)                      \
    std::vector<type> name1(size), name2(size), name3(size), name4(size); \
    for (int i = 0; i < size; i++) scan(name1[i], name2[i], name3[i], name4[i])
#define VV(type, name, h, w)                       \
    std::vector name((h), std::vector<type>((w))); \
    scan(name)
// output
template <class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
    auto n = v.size();
    for (size_t i = 0; i < n; i++) {
        if (i) os << ' ';
        os << v[i];
    }
    return os;
}
template <class... T> void out(const T&... a) { (std::cout << ... << a); }
void print() { out('\n'); }
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) {
    out(head);
    if (sizeof...(Tail)) out(' ');
    print(tail...);
}
// for interactive problems
void printi() { std::cout << std::endl; }
template <class Head, class... Tail> void printi(Head&& head, Tail&&... tail) {
    out(head);
    if (sizeof...(Tail)) out(' ');
    printi(tail...);
}
// bool output
void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void NO(bool t = 1) { YES(!t); }
void No(bool t = 1) { Yes(!t); }
void no(bool t = 1) { yes(!t); }
void POSSIBLE(bool t = 1) { print(t ? "POSSIBLE" : "IMPOSSIBLE"); }
void Possible(bool t = 1) { print(t ? "Possible" : "Impossible"); }
void possible(bool t = 1) { print(t ? "possible" : "impossible"); }
void IMPOSSIBLE(bool t = 1) { POSSIBLE(!t); }
void Impossible(bool t = 1) { Possible(!t); }
void impossible(bool t = 1) { possible(!t); }
void FIRST(bool t = 1) { print(t ? "FIRST" : "SECOND"); }
void First(bool t = 1) { print(t ? "First" : "Second"); }
void first(bool t = 1) { print(t ? "first" : "second"); }
void SECOND(bool t = 1) { FIRST(!t); }
void Second(bool t = 1) { First(!t); }
void second(bool t = 1) { first(!t); }
// I/O speed up
struct SetUpIO {
    SetUpIO() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        std::cout << std::fixed << std::setprecision(15);
    }
} set_up_io;
using namespace std;

void solve(int H, int W) {
    VEC(string, S, H);
    int ans = 0;

    auto rec = [&](auto f, int i, int j) -> void {
        // show(i);
        // show(j);
        // show(S);
        if (j == W) {
            f(f, i + 1, 0);
            return;
        }
        if (i == H) {
            ans++;
            return;
        }
        if (S[i][j] == '#') {
            f(f, i, j + 1);
            return;
        }
        // ##
        // #.
        if (i + 1 < H and j + 1 < W and S[i + 1][j] == '.' and S[i][j + 1] == '.') {
            S[i][j] = '#';
            S[i + 1][j] = '#';
            S[i][j + 1] = '#';
            f(f, i, j + 1);
            S[i][j] = '.';
            S[i + 1][j] = '.';
            S[i][j + 1] = '.';
        }
        // ##
        // .#
        if (i + 1 < H and j + 1 < W and S[i][j + 1] == '.' and S[i + 1][j + 1] == '.') {
            S[i][j] = '#';
            S[i][j + 1] = '#';
            S[i + 1][j + 1] = '#';
            f(f, i, j + 1);
            S[i][j] = '.';
            S[i][j + 1] = '.';
            S[i + 1][j + 1] = '.';
        }
        // #.
        // ##
        if (i + 1 < H and j + 1 < W and S[i + 1][j] == '.' and S[i + 1][j + 1] == '.') {
            S[i][j] = '#';
            S[i + 1][j] = '#';
            S[i + 1][j + 1] = '#';
            f(f, i, j + 1);
            S[i][j] = '.';
            S[i + 1][j] = '.';
            S[i + 1][j + 1] = '.';
        }
        // .#
        // ##
        if (i + 1 < H and j - 1 >= 0 and S[i + 1][j - 1] == '.' and S[i + 1][j] == '.') {
            S[i][j] = '#';
            S[i + 1][j - 1] = '#';
            S[i + 1][j] = '#';
            f(f, i, j + 1);
            S[i][j] = '.';
            S[i + 1][j - 1] = '.';
            S[i + 1][j] = '.';
        }
        return;
    };
    rec(rec, 0, 0);
    print(ans);
    return;
}

int main() {
    int H, W;
    while (cin >> H >> W, H != 0) solve(H, W);
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3328
final_rank: 6

code_snippet: //line 2 "/home/seekworser/.cpp_lib/competitive_library/competitive/std/std.hpp"
#include <bits/stdc++.h>
#ifndef LOCAL_TEST
#pragma GCC target ("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#endif // LOCAL_TEST
using namespace std;
// 型名の短縮
using ll = long long;
using pii = pair<int, int>; using pll = pair<ll, ll>;
using vi = vector<int>;  using vvi = vector<vi>; using vvvi = vector<vvi>;
using vl = vector<ll>;  using vvl = vector<vl>; using vvvl = vector<vvl>;
using vb = vector<bool>; using vvb = vector<vb>; using vvvb = vector<vvb>;
using vc = vector<char>; using vvc = vector<vc>; using vvvc = vector<vvc>;
using vd = vector<double>; using vvd = vector<vd>; using vvvd = vector<vvd>;
using vs = vector<string>; using vvs = vector<vector<string>>; using vvvs = vector<vector<vector<string>>>;
template<typename T> vector<vector<T>> vv(int h, int w, T val = T()) { return vector(h, vector<T>(w, val)); }
template<typename T> vector<vector<vector<T>>> vvv(int h1, int h2, int h3, T val = T()) { return vector(h1, vector(h2, vector<T>(h3, val))); }
template<typename T> vector<vector<vector<vector<T>>>> vvvv(int h1, int h2, int h3, int h4, T val = T()) { return vector(h1, vector(h2, vector(h3, vector<T>(h4, val)))); }
template <class T> using priority_queue_min = priority_queue<T, vector<T>, greater<T>>;
// 定数の定義
constexpr double PI = 3.14159265358979323;
constexpr int INF = 100100111; constexpr ll INFL = 3300300300300300491LL;
float EPS = 1e-8; double EPSL = 1e-16;
template<typename T> bool eq(const T x, const T y) { return x == y; }
template<> bool eq<double>(const double x, const double y) { return abs(x - y) < EPSL; }
template<> bool eq<float>(const float x, const float y) { return abs(x - y) < EPS; }
template<typename T> bool neq(const T x, const T y) { return !(eq<T>(x, y)); }
template<typename T> bool ge(const T x, const T y) { return (eq<T>(x, y) || (x > y)); }
template<typename T> bool le(const T x, const T y) { return (eq<T>(x, y) || (x < y)); }
template<typename T> bool gt(const T x, const T y) { return !(le<T>(x, y)); }
template<typename T> bool lt(const T x, const T y) { return !(ge<T>(x, y)); }
constexpr int MODINT998244353 = 998244353;
constexpr int MODINT1000000007 = 1000000007;
// 入出力高速化
struct Nyan { Nyan() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(18); } } nyan;
// 汎用マクロの定義
#define all(a) (a).begin(), (a).end()
#define sz(x) ((ll)(x).size())
#define rep1(n) for(ll dummy_iter = 0LL; dummy_iter < n; ++dummy_iter) // 0 から n-1 まで昇順
#define rep2(i, n) for(ll i = 0LL, i##_counter = 0LL; i##_counter < ll(n); ++(i##_counter), (i) = i##_counter) // 0 から n-1 まで昇順
#define rep3(i, s, t) for(ll i = ll(s), i##_counter = ll(s); i##_counter < ll(t); ++(i##_counter), (i) = (i##_counter)) // s から t まで昇順
#define rep4(i, s, t, step) for(ll i##_counter = step > 0 ? ll(s) : -ll(s), i##_end = step > 0 ? ll(t) : -ll(t), i##_step = abs(step), i = ll(s); i##_counter < i##_end; i##_counter += i##_step, i = step > 0 ? i##_counter : -i##_counter) // s から t まで stepずつ
#define overload4(a, b, c, d, e, ...) e
#define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__)
#define repe(a, v) for(auto& a : (v)) // v の全要素（変更可能）
#define smod(n, m) ((((n) % (m)) + (m)) % (m)) // 非負mod
#define sdiv(n, m) (((n) - smod(n, m)) / (m)) // 非負div
#define uniq(a) {sort(all(a)); (a).erase(unique(all(a)), (a).end());} // 重複除去
int Yes(bool b=true) { cout << (b ? "Yes\n" : "No\n"); return 0; };
int YES(bool b=true) { cout << (b ? "YES\n" : "NO\n"); return 0; };
int No(bool b=true) {return Yes(!b);};
int NO(bool b=true) {return YES(!b);};
template<typename T, size_t N> T max(array<T, N>& a) { return *max_element(all(a)); };
template<typename T, size_t N> T min(array<T, N>& a) { return *min_element(all(a)); };
template<typename T> T max(vector<T>& a) { return *max_element(all(a)); };
template<typename T> T min(vector<T>& a) { return *min_element(all(a)); };
template<typename T> vector<T> accum(const vector<T>& a) { vector<T> rev(sz(a)+1, 0); rep(i, sz(a)) rev[i+1] = rev[i] + a[i]; return rev; };
template<typename T> vector<T> vec_slice(const vector<T>& a, int l, int r) { vector<T> rev; rep(i, l, r) rev.push_back(a[i]); return rev; };
template<typename T> T sum(vector<T>& a, T zero = T(0)) { T rev = zero; rep(i, sz(a)) rev += a[i]; return rev; };
template<typename T> bool in_range(const T& val, const T& s, const T& t) { return s <= val && val < t; };

template <class T> inline vector<T>& operator--(vector<T>& v) { repe(x, v) --x; return v; }
template <class T> inline vector<T>& operator++(vector<T>& v) { repe(x, v) ++x; return v; }

// modでのpow
ll powm(ll a, ll n, ll mod=INFL) {
    ll res = 1;
    while (n > 0) {
        if (n & 1) res = (res * a) % mod;
        if (n > 1) a = (a * a) % mod;
        n >>= 1;
    }
    return res;
}
// 整数Sqrt
ll sqrtll(ll x) {
    assert(x >= 0);
    ll rev = sqrt(x);
    while(rev * rev > x) --rev;
    while((rev+1) * (rev+1)<=x) ++rev;
    return rev;
}
template <class T> inline bool chmax(T& M, const T& x) { if (M < x) { M = x; return true; } return false; } // 最大値を更新（更新されたら true を返す）
template <class T> inline bool chmin(T& m, const T& x) { if (m > x) { m = x; return true; } return false; } // 最小値を更新（更新されたら true を返す）
int digit(ll x, int d=10) { int rev=0; while (x > 0) { rev++; x /= d;}; return rev; } // xのd進数桁数
/**
 * @brief std.hpp
 * @docs docs/std/std.md
 */
//line 3 "/home/seekworser/.cpp_lib/competitive_library/competitive/math/bit.hpp"
namespace bit{
    bool lb(ll x) { return (x & 1); }
    bool get(ll x, int n) { return ((x >> n) & 1); }
    ll update(ll x, int n, bool b) { return (x & ~(1LL << n)) + (b << n); }
    ll lsb(ll x) { return -x & x; }
    int digit(ll x) { int rev=0; while(x) { rev++; x >>= 1; } return rev; }
    ll msb(ll x) { if (x==0) return 0; return 1LL << (digit(x) - 1); }
    int lsbd(ll x) {return digit(lsb(x)); }
    int count(ll x) { return __builtin_popcountll(x); }
    string to_string(ll x, bool rev=true) { stringstream ss; while (x) { ss << lb(x); x >>= 1;} string s(ss.str()); if (rev) reverse(all(s)); return s; }
}
/**
 * @brief ビット演算
 * @docs docs/math/bit.md
 */
//line 3 "/home/seekworser/.cpp_lib/competitive_library/competitive/std/io.hpp"
// 演算子オーバーロード（プロトタイプ宣言）
template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p);
template <class T> inline istream& operator>>(istream& is, vector<T>& v);
template <class T, class U> inline ostream& operator<<(ostream& os, const pair<T, U>& p);
template <class T> inline ostream& operator<<(ostream& os, const vector<T>& v);
template <typename T, typename S> ostream &operator<<(ostream &os, const map<T, S> &mp);
template <typename T> ostream &operator<<(ostream &os, const set<T> &st);
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &st);
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T> &st);
template <typename T> ostream &operator<<(ostream &os, queue<T> q);
template <typename T> ostream &operator<<(ostream &os, deque<T> q);
template <typename T> ostream &operator<<(ostream &os, stack<T> st);
template <class T, class Container, class Compare> ostream &operator<<(ostream &os, priority_queue<T, Container, Compare> pq);

// 演算子オーバーロード
template <class T, class U> inline istream& operator>>(istream& is, pair<T, U>& p) { is >> p.first >> p.second; return is; }
template <class T> inline istream& operator>>(istream& is, vector<T>& v) { repe(x, v) is >> x; return is; }
template <class T, class U> inline ostream& operator<<(ostream& os, const pair<T, U>& p) { os << p.first << " " << p.second; return os; }
template <class T> inline ostream& operator<<(ostream& os, const vector<T>& v) { rep(i, sz(v)) { os << v.at(i); if (i != sz(v) - 1) os << " "; } return os; }
template <typename T, typename S> ostream &operator<<(ostream &os, const map<T, S> &mp) { for (auto &[key, val] : mp) { os << key << ":" << val << " "; } return os; }
template <typename T> ostream &operator<<(ostream &os, const set<T> &st) { auto itr = st.begin(); for (int i = 0; i < (int)st.size(); i++) { os << *itr << (i + 1 != (int)st.size() ? " " : ""); itr++; } return os; }
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &st) { auto itr = st.begin(); for (int i = 0; i < (int)st.size(); i++) { os << *itr << (i + 1 != (int)st.size() ? " " : ""); itr++; } return os; }
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T> &st) { ll cnt = 0; for (auto &e : st) { os << e << (++cnt != (int)st.size() ? " " : ""); } return os; }
template <typename T> ostream &operator<<(ostream &os, queue<T> q) { while (q.size()) { os << q.front() << " "; q.pop(); } return os; }
template <typename T> ostream &operator<<(ostream &os, deque<T> q) { while (q.size()) { os << q.front() << " "; q.pop_front(); } return os; }
template <typename T> ostream &operator<<(ostream &os, stack<T> st) { while (st.size()) { os << st.top() << " "; st.pop(); } return os; }
template <class T, class Container, class Compare> ostream &operator<<(ostream &os, priority_queue<T, Container, Compare> pq) { while (pq.size()) { os << pq.top() << " "; pq.pop(); } return os; }

template <typename T> int print_sep_end(string sep, string end, const T& val) { (void)sep; cout << val << end; return 0; };
template <typename T1, typename... T2> int print_sep_end(string sep, string end, const T1 &val, const T2 &...remain) {
    cout << val << sep;
    print_sep_end(sep, end, remain...);
    return 0;
};
template <typename... T> int print(const T &...args) { print_sep_end(" ", "\n", args...); return 0; };
template <typename... T> void flush() { cout << flush; };
template <typename... T> int print_and_flush(const T &...args) { print(args...); flush(); return 0; };
#define debug(...) debug_func(0, #__VA_ARGS__, __VA_ARGS__) // debug print
template <typename T> void input(T &a) { cin >> a; };
template <typename T1, typename... T2> void input(T1&a, T2 &...b) { cin >> a; input(b...); };
#ifdef LOCAL_TEST
template <typename T> void debug_func(int i, const T name) { (void)i; (void)name; cerr << endl; }
template <typename T1, typename T2, typename... T3> void debug_func(int i, const T1 &name, const T2 &a, const T3 &...b) {
    int scope = 0;
    for ( ; (scope != 0 || name[i] != ',') && name[i] != '\0'; i++ ) {
        cerr << name[i];
        if (name[i] == '(' || name[i] == '{') scope++;
        if (name[i] == ')' || name[i] == '}') scope--;
    }
    cerr << ":" << a << " ";
    debug_func(i + 1, name, b...);
}
template <typename T1, typename T2, typename... T3> void debug_func(int i, const T1 &name, T2 &a, T3 &...b) {
    int scope = 0;
    for ( ; (scope != 0 || name[i] != ',') && name[i] != '\0'; i++ ) {
        cerr << name[i];
        if (name[i] == '(' || name[i] == '{') scope++;
        if (name[i] == ')' || name[i] == '}') scope--;
    }
    cerr << ":" << a << " ";
    debug_func(i + 1, name, b...);
}
#endif
#ifndef LOCAL_TEST
template <typename... T>
void debug_func(T &...) {}
template <typename... T>
void debug_func(const T &...) {}
#endif
/**
 * @brief io.hpp
 * @docs docs/std/io.md
 */
//line 4 "answer.cpp"
int main() {
    while (true) {
        ll h,w; input(h, w);
        if (h == 0 && w == 0) break;
        vector<string> s(h); input(s);
        vl row_bit(h+1, 0);
        rep(i, h) rep(j, w) if (s[i][j] == '#') row_bit[i] |= (1LL << j);
        row_bit[h] = (1LL << w) - 1;
        auto dp = vvvv<ll>(h, w, (1LL << w), (1LL << w));
        dp[0][0][row_bit[0]][row_bit[1]] = 1;
        auto bget = [](ll b, ll x) -> ll { return (b >> x) & 1;};
        ll ans = 0;
        rep(i, h-1) rep(j, w) rep(b1, (1LL << w)) rep(b2, (1LL << w)) {
            if (dp[i][j][b1][b2] == 0) continue;
            string b1s = bit::to_string(b1);
            string b2s = bit::to_string(b2);
            debug(i, j, b1s, b2s, dp[i][j][b1][b2]);
            if (bget(b1, j)) {
                if (j != w-1) dp[i][j+1][b1][b2] += dp[i][j][b1][b2];
                else if (b1 == row_bit[h]) dp[i+1][0][b2][row_bit[i+2]] += dp[i][j][b1][b2];
                continue;
            }
            ll ni = i, nj = j+1;
            if (nj == w) { ni++, nj = 0; }
            if (j != w-1) {
                if (bget(b1, j+1) == 0 && bget(b2, j) == 0) {
                    ll b1n = b1 | (1LL << (j+1)) | (1LL << j);
                    ll b2n = b2 | (1LL << j);
                    dp[ni][nj][b1n][b2n] += dp[i][j][b1][b2];
                }
                if (bget(b1, j+1) == 0 && bget(b2, j+1) == 0) {
                    ll b1n = b1 | (1LL << (j+1)) | (1LL << j);
                    ll b2n = b2 | (1LL << (j+1));
                    dp[ni][nj][b1n][b2n] += dp[i][j][b1][b2];
                }
                if (bget(b2, j) == 0 && bget(b2, j+1) == 0) {
                    ll b1n = b1 | (1LL << j);
                    ll b2n = b2 | (1LL << j) | (1LL << (j+1));
                    dp[ni][nj][b1n][b2n] += dp[i][j][b1][b2];
                }
                if (j != 0) {
                    if (bget(b2, j) == 0 && bget(b2, j-1) == 0) {
                        ll b1n = b1 | (1LL << j);
                        ll b2n = b2 | (1LL << j) | (1LL << (j-1));
                        dp[ni][nj][b1n][b2n] += dp[i][j][b1][b2];
                    }
                }
            } else {
                if (b1 == (row_bit[h] >> 1) && bget(b2, j) == 0 && bget(b2, j-1) == 0) {
                    ll b2n = b2 | (1LL << j) | (1LL << (j-1));
                    dp[ni][nj][b2n][row_bit[i+2]] += dp[i][j][b1][b2];
                }
            }
        }
        print(dp[h-1][0][row_bit[h]][row_bit[h]]);
    }
}
accuracy: 1
time_ms: 400
memory_kb: 41276
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long int;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef vector<vvll> vvvll;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef pair<ll,ll> pll;
typedef vector<pair<ll,ll>> vp;
#define rep(i,a,n) for(ll i=a;i<n;i++)
#define rrep(i,a,n) for(ll i=n-1;i>=a;i--)
#define mod 998244353
#define all(a) a.begin(),a.end()

bool in_field(ll l,ll r,ll x){
    if(l <= x && x < r)return true;
    else return false;
}

ll h,w;
ll ans = 0;
void dfs(vs board,ll cnt,ll pos){
    vs b = board;
    bool ok = true;
    rep(i,0,h){
        rep(j,0,w){
            if(i*w+j <= cnt && b[i][j] == '.'){
                ok = false;
                break;
            }
            if(b[i][j] == '.'){
                if(in_field(0,h,i+1) & in_field(0,w,j-1)){
                    if(b[i][j] == '.' && b[i][j-1] == '#' && b[i+1][j] == '.' && b[i+1][j-1] == '.'){
                        b[i][j] = b[i+1][j] = b[i+1][j-1] = '#';
                        dfs(b,i*w+j,pos+3);
                        b[i][j] = b[i+1][j] = b[i+1][j-1] = '.';
                    }
                }
                if(in_field(0,h,i+1) & in_field(0,w,j+1)){
                    if(b[i][j] == '.'  && b[i+1][j] == '.' && b[i+1][j+1] == '.'){
                        b[i][j] = b[i+1][j] = b[i+1][j+1] = '#';
                        dfs(b,i*w+j,pos+3);
                        b[i][j] = b[i+1][j] = b[i+1][j+1] = '.';
                    }
                    if(b[i][j] == '.' && b[i][j+1] == '.'  && b[i+1][j+1] == '.'){
                        b[i][j] = b[i][j+1] = b[i+1][j+1] = '#';
                        dfs(b,i*w+j,pos+3);
                        b[i][j] = b[i][j+1] = b[i+1][j+1] = '.';
                    }
                    if(b[i][j] == '.' && b[i][j+1] == '.' && b[i+1][j] == '.'){
                        b[i][j] = b[i][j+1] = b[i+1][j] = '#';
                        dfs(b,i*w+j,pos+3);
                        b[i][j] = b[i][j+1] = b[i+1][j] = '.';
                    }
                }
            }
        }
        if(!ok)break;
    }
    if(pos == h*w)ans++;
}

int main(){
    while(true){
        cin >> h >> w;
        if(h == 0 && w==0)return 0;
        vs a(h);
        rep(i,0,h)cin >> a[i];
        ll cnt = 0;
        rep(i,0,h)rep(j,0,w)if(a[i][j] =='#')cnt++;
        dfs(a,-1,cnt);
        cout << ans << endl;
        ans = 0;
    }
}
accuracy: 1
time_ms: 1640
memory_kb: 3476
final_rank: 19