#include <iostream>
#include <string>

using namespace std;

const int Q = 998244353;
int fact[100];
int revf[100];

int comb(int n, int r)
{
    if(n < r) return 0;
    return (long long)fact[n] * revf[n - r] % Q * revf[r] % Q;
}

bool nextComb(bool *arr, int n, int r)
{
    int cnt = 0;
    for(int i = n - 1; i >= 0; --i)
    {
        if(arr[i])
        {
            ++cnt;
            if(i < n - 1 && !arr[i + 1])
            {
                arr[i] = false;
                for(int j = i + 1; j <= i + cnt; ++j) arr[j] = true;
                for(int j = i + cnt + 1; j < n; ++j) arr[j] = false;
                return true;
            }
        }
    }
    return false;
}

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

    int n, m; cin >> n >> m;
    fact[0] = 1; for(int i = 1; i < 100; ++i) fact[i] = (long long)fact[i - 1] * i % Q;
    revf[0] = revf[1] = 1; for(int i = 2; i < 100; ++i) revf[i] = Q - (long long)revf[Q % i] * (Q / i) % Q;
    for(int i = 2; i < 100; ++i) revf[i] = (long long)revf[i] * revf[i - 1] % Q;

    int dp[n + 1][m + 1]{};
    for(int i = 0; i <= n; ++i)
    {
        for(int j = 0; j <= m; ++j)
        {
            int ans = 0;
            bool arr[i + j];
            for(int k = 0; k < i; ++k) arr[k] = true;
            for(int k = i; k < i + j; ++k) arr[k] = false;
            do
            {
                int cnt = 0, tmp = 1;
                for(int k = 0; k < i + j; ++k)
                {
                    ++cnt;
                    if(k == i + j - 1 || arr[k] != arr[k + 1])
                        tmp = (long long)tmp * revf[cnt] % Q, cnt = 0;
                }
                ans = (ans + tmp) % Q;
            }while(nextComb(arr, i + j, i));
            dp[i][j] = (long long)ans * fact[i] % Q * fact[j] % Q;
        }
    }

    int ans = dp[n][m];
    string s[n]; for(int i = 0; i < n; ++i) cin >> s[i];
    int N = 1 << (n + m);
    for(int i = 1; i < N; ++i)
    {
        bool __flag = true;

        for(int j = 0; j < n; ++j)
        {
            if(!(i >> j & 1)) continue;
            char prev = 0;
            bool flag = false;
            for(int k = 0; k < m; ++k)
            {
                if(!(i >> (k + n) & 1)) continue;
                if(!prev) prev = s[j][k];
                else if(prev != s[j][k]) {flag = true; break;}
            }
            if(!flag) {__flag = false; break;}
        }

        for(int k = 0; k < m; ++k)
        {
            if(!(i >> (k + n) & 1)) continue;
            char prev = 0;
            bool flag = false;
            for(int j = 0; j < n; ++j)
            {
                if(!(i >> j & 1)) continue;
                if(!prev) prev = s[j][k];
                else if(prev != s[j][k]) {flag = true; break;}
            }
            if(!flag) {__flag = false; break;}
        }

        if(__flag)
        {
            int _m = __builtin_popcount(i >> n);
            int _n = __builtin_popcount(i) - _m;
            _n = n - _n; _m = m - _m;

            for(int j = 0; j <= _n; ++j)
            {
                for(int k = 0; k <= _m; ++k)
                {
                    ans += (long long)dp[j][_m - k] * dp[k][_n - j] % Q
                            * comb(_n, j) % Q * comb(_m, k) % Q;
                    ans %= Q;
                }
            }
        }
    }

    cout << ans;
    return 0;
}


Measured memory_bytes: 256