#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstring>
#include <iostream>
#include <sstream>
#include <numeric>
#include <map>
#include <set>
#include <queue>
#include <vector>

using namespace std;

typedef long long LL;

struct Tree {
	int _size;
	vector<vector<int>> _edges;
	vector<int> _done;
	vector<int> _vis;
	vector<int> _color;
	vector<int> _shifts;
	vector<int> _nodes;

	Tree(int size) : _size(size), _edges(size), _done(size), _vis(size) { }

	void build_edges(const vector<int>& a, const vector<int>& b) {
		for (int i = 0; i < a.size(); ++i) {
			_edges[a[i]].emplace_back(b[i]);
			_edges[b[i]].emplace_back(a[i]);
		}
	}

	void dfs1(int n) {
		_done[n] = 1;
		for (auto next : _edges[n]) {
			if (_done[next] <= 0) {
				dfs1(next);
			}
		}
		_nodes.emplace_back(n);
	}

	bool dfs2(int n) {
		_vis[n] = 1;
		for (auto next : _edges[n]) {
			if (_vis[next] <= 0) {
				_color[next] = (_color[n] + _shifts[next]) % 3;
				if (!dfs2(next)) {
					return false;
				}
			}
			if (_color[n] == _color[next]) {
				return false;
			}
		}
		return true;
	}

	LL solve(int M, std::vector<int>& A, std::vector<int>& B) {
		LL ans = 1;
		for (int node = 0; node < _size; ++node) {
			if (_done[node]) {
				continue;
			}
			_nodes.clear();
			dfs1(node);
			_nodes.pop_back();
			_shifts = vector<int>(_size);
			_color = vector<int>(_size, -1);
			int sum = 0, bm = 1 << _nodes.size();
			for (int b = 0; b < bm; ++b) {
				for (int i = 0; i < _nodes.size(); ++i) {
					_shifts[_nodes[i]] = ((1 << i) & b) ? 1 : 2;
				}
				_color[node] = 0;
				_vis = vector<int>(_size);
				if (dfs2(node)) {
					++sum;
				}
			}
			ans *= sum * 3;
		}
		return ans;
	}
};

LL solve(int N, int M, std::vector<int> &A, std::vector<int> &B) {
	Tree tree(N);
	tree.build_edges(A, B);
	return tree.solve(M, A, B);
}

int main() {
	int N, M;
	std::cin >> N >> M;
	std::vector<int> A(M), B(M);
	for (int i = 0; i < M; i++) {
		std::cin >> A[i] >> B[i];
		--A[i], --B[i];
	}
	cout << solve(N, M, A, B) << endl;
	return 0;
}

/**
*    author:  
*    created: 16.11.2020 06:42:51
**/

#pragma region Macros
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
using P = pair<int,int>;
using ll = long long;
const int INF = 1001001001;
const int di[] = {-1,0,1,0}, dj[] = {0,-1,0,1};
typedef vector<int> vi;
typedef vector<vi> vvi;

#define rep(i,n) for(int i = 0; i < (n); i++)
#define repn(i,n) for(int i = 1; i <= (n); i++)
#define pb push_back
void debug_out() { cout << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cout << H << " ";
  debug_out(T...);
}
#ifdef LOCAL
#define debug(...) debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

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

const double PI = acos(-1);
const int mod = 1000000007;
class mint {
  long long x;
  public:
  mint(long long x=0) : x((x%mod+mod)%mod) {}
  mint operator-() const {
    return mint(-x);
  }
  mint& operator+=(const mint& a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator-=(const mint& a) {
    if ((x += mod-a.x) >= mod) x -= mod;
    return *this;
  }
  mint& operator*=(const  mint& a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint& a) const {
    mint res(*this);
    return res+=a;
  }
  mint operator-(const mint& a) const {
    mint res(*this);
    return res-=a;
  }
  mint operator*(const mint& a) const {
    mint res(*this);
    return res*=a;
  }
  mint pow(ll t) const {
    if (!t) return 1;
    mint a = pow(t>>1);
    a *= a;
    return a;
  }
  // for prime mod
  mint inv() const {
    return pow(mod-2);
  }
  mint& operator/=(const mint& a) {
    return (*this) *= a.inv();
  }
  mint operator/(const mint& a) const {
    mint res(*this);
    return res/=a;
  }

  friend ostream& operator<<(ostream& os, const mint& m){
    os << m.x;
    return os;
  }
};
#pragma endregion

int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  int h, w;
  cin >> h >> w;
  vector<string> s(h);
  rep(i,h) cin >> s[i];
  vector<vector<mint>> dp(h,vector<mint>(w,0));
  vector<vector<mint>> x(h,vector<mint>(w,0));
  vector<vector<mint>> y(h,vector<mint>(w,0));
  vector<vector<mint>> z(h,vector<mint>(w,0));
  dp[0][0] = 1;
  rep(i,h)rep(j,w){
    if(i==0 && j==0) continue;
    if(s[i][j]=='#')continue;
    if(j>0)x[i][j] = (x[i][j-1]+dp[i][j-1]);
    if(i>0)y[i][j] = (y[i-1][j]+dp[i-1][j]);
    if(i>0&&j>0)z[i][j] = (z[i-1][j-1]+dp[i-1][j-1]);
    dp[i][j] = (x[i][j]+y[i][j]+z[i][j]);
  }
  cout << dp[h-1][w-1] << endl;
  return 0;
}