using System;
using System.Numerics;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace debug
{
class main
{
static void Main(string args)
{
//問題クラスを展開
ProgramE a = new ProgramE();
a.main();//実行する
}
}
//HHKB
class ProgramA
{
public void main()
{
//入力
string t = Console.ReadLine();
string s = Console.ReadLine();
//Yなら大文字(32を引く)出力、Nなら普通に出す
if (t[0] == 'Y')
Console.WriteLine((char)(s[0] - 32));
else
Console.WriteLine(s);
}
}
class ProgramB
{
public void main()
{
//入力
string s = Console.ReadLine().Split(' ');
int h = int.Parse(s[0]);
int w = int.Parse(s[1]);
int[,] huton = new int[h, w];
int ans = 0;
//配列作成
for (int i = 0; i < h; i++)
{
string t = Console.ReadLine();
for (int j = 0; j < w; j++)
{
if (t[j] == '.')
huton[i, j] = 0;
else
huton[i, j] = 1;
}
}
//すべてのマスで検索、ただし、w-1のときはヨコ判定はなく、h-1のときはタテ判定はない
for(int i = 0;i < h;i++)
for (int j = 0; j < w; j++)
{
if (j != w - 1)
if (huton[i, j] == 0 && huton[i, j + 1] == 0)
ans++;
if (i != h - 1)
if (huton[i, j] == 0 && huton[i + 1, j] == 0)
ans++;
}
//答え出力
Console.WriteLine(ans);
}
}
class ProgramC
{
public void main()
{
//入力
int n = int.Parse(Console.ReadLine());
string a = Console.ReadLine().Split(' ');
int count = new int[200002];//答としては200001まである
int index = 0;//最小としての答は残しておく
for (int i = 0; i < n; i++)
{
count[int.Parse(a[i])] = 1;//どの数があったかリストにしておく
for (int j = index; j < 200002; j++)//一意的なので逆に調べないようにする。現在の最小から0のところを探せばよい
{
if (count[j] == 0)//もし、数えて0ならそれが現在の最小
{
Console.WriteLine(j);
index = j;//更新
break;//次のループへ
}
}
}
}
}
class ProgramE
{
public void main()
{
//入力
string s = Console.ReadLine().Split(' ');
int h = int.Parse(s[0]);
int w = int.Parse(s[1]);
long mod = 1000000000 + 7;
long[,] huton = new long[h, w];
long[,] num_w = new long[h, w];
long[,] num_h = new long[h, w];
long count = 0;
//迷路作成と横で影響のある電球の数を見ておく
for (int i = 0; i < h; i++)
{
long temp = 0;
string t = Console.ReadLine();
for (int j = 0; j < w; j++)
{
if (t[j] == '.')
{
huton[i, j] = 0;
count++;
temp++;
}
else
{
huton[i, j] = 1;
num_w[i, j - temp] = temp;
temp = 0;
}
if (j == w - 1 && temp > 0)
{
num_w[i, j - temp + 1] = temp;
}
}
}
//タテで電球の数の影響があるのを見ておく
for (int i = 0; i < w; i++)
{
long temp = 0;
for (int j = 0; j < h; j++)
{
if (huton[j, i] == 0)
temp++;
else
{
num_h[j - temp, i] = temp;
temp = 0;
}
if(j == h - 1 && temp > 0)
{
num_h[j - temp + 1, i] = temp;
}
}
}
//2のn乗はあらかじめメモ化しておく
long two_list = new long[count + 1];
two_list[0] = 1;
for (int i = 1; i <= count; i++)
two_list[i] = 2 * two_list[i - 1] % mod;
//それぞれの位置で数を足す
long ans = 0;
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
if (huton[j, i] == 0)
{
long tento = count - (num_w[j, i] + num_h[j, i] - 1);
if (j < h - 1)
num_h[j + 1, i] = num_h[j, i];//累積和
if (i < w - 1)
num_w[j, i + 1] = num_w[j, i];//累積和
ans += (two_list[count] - two_list[tento] + mod) % mod;//その場所が照らされる通り数を見る
ans %= mod;
}
}
}
//答え出力
Console.WriteLine(ans);
}
}
}