#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define pi 3.141592653589793238
#define int long long
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;


  

long long power(long long a, long long b,long long mod) {
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a %mod;
        a = a * a %mod;
        b >>= 1;
    }
    return res;
}

int pre[2005];
int ans[2005][2005];
const int mod=1e9+7;
int pp[4000005];

signed main()
{

ios_base::sync_with_stdio(false);
cin.tie(NULL);  
cout.tie(0);   

#ifndef ONLINE_JUDGE
    if(fopen("INPUT.txt","r"))
    {
    freopen ("INPUT.txt" , "r" , stdin);
    freopen ("OUTPUT.txt" , "w" , stdout);
    }
#endif      

    pp[0]=1;
    for(int i=1;i<=4000000;i++)
        pp[i]=pp[i-1]*2%mod;

    int n,m;
    cin>>n>>m;
    string a[n+1];
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        a[i]="#"+a[i];
    }
    int fi=0;
    for(int i=1;i<=n;i++)
    {
        int x=0;
        for(int j=1;j<=m;j++)
        {
            if(a[i][j]=='.')
                fi++;
            if(a[i][j]=='.')
                x++;
            else 
                x=0;
            ans[i][j]+=x;
        }
        x=0;
        for(int j=m;j>=1;j--)
        {
            if(a[i][j]=='.')
                x++;
            else 
                x=0;
            ans[i][j]+=x;
            if(a[i][j]=='.')
                ans[i][j]--;
        }
    }

    for(int i=1;i<=m;i++)
    {
        int x=0;
        for(int j=1;j<=n;j++)
        {
            if(a[j][i]=='.')
                x++;
            else 
                x=0;
            ans[j][i]+=x;
            if(a[j][i]=='.')
                ans[j][i]--;
        }
        x=0;
        for(int j=n;j>=1;j--)
        {
            if(a[j][i]=='.')
                x++;
            else 
                x=0;
            ans[j][i]+=x;
            if(a[j][i]=='.')
                ans[j][i]--;
        }
    }
    int tot=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
        if(ans[i][j])
        {
            int z=pp[ans[i][j]]-1+mod;
            z%=mod;
            z=(z*pp[(fi-ans[i][j])])%mod;
            tot+=z;
            tot%=mod;
        }
    }
    }
    cout<<tot;

}    
#include <stdio.h>
#include <vector>

using namespace std;

const long long mod = 998244353;
vector<long long> mem(2,1);

long long sol(int a) {
    return mem[a];
}

long long pow(long long a, long long b) {
    long long ans = 1;
    long long base = a;
    while (b) {
        if (b%2) ans = ans * base % mod;
        base = base * base % mod;
        b/=2;
    }
    return ans;
}

long long inv(long long a) {
    return pow(a, mod - 2);
}

long long Comb(int a, int b) {

    long long ans = sol(b);//printf("%d %d\n", a, b);
    ans *= inv(sol(a));
    ans %= mod;
    ans *= inv(sol(b-a));
    ans %= mod;
    return ans;
}

int main()
{
    int n,m;
    scanf("%d%d", &n, &m);
    vector<int> primes(m+1, 0);
    for (int i=2 ;i<=m; ++i) {
        if (primes[i] == 0) {
            for (int j=i; j<=m; j+=i) {
                if (primes[j] == 0) {
                    primes[j] = i;
                }
            }
        }
    }
    for (int i=2; i<=n+100; ++i) {
        mem.push_back(i*mem[i-1]%mod);
    }

    long long ans = 0;
    for (int i=1; i<=m; ++i) {
        long long tmp = 1;
        int x = i;
        while (x > 1) {
            int q = 0;
            int prime = primes[x];
            while (x%prime == 0) {
                q++;
                x/=prime;
            }
            tmp *= Comb(n-1, n-1+q);
            tmp %= mod;
        }
        ans = (ans + tmp) % mod;
    }
    printf("%lld\n", ans);
}
