#include <cstdio>
#include <set>
using namespace std;

const int max_l = 1000;

char mp[max_l][max_l+1];
int dsu[max_l<<1];

inline int my_min(int a, int b) { return (a < b)? a:b; }

int find(int x)
{
	if (dsu[x] != x) dsu[x] = find(dsu[x]);
	return dsu[x];
}

bool sam(int a, int b) { return find(a) == find(b); }

void unite(int a, int b)
{
	if (!sam(a, b))
		dsu[find(a)] = find(b);
}

int main()
{
	int h, w;
	set<int> rw, cl;

	scanf("%d%d", &h, &w);
	for (int i = 0; i < h; i++)
		scanf("%s", mp[i]);

	for (int i = 0; i < h + w; i++)
		dsu[i] = i;
	
	mp[0][0] = mp[0][w-1] = mp[h-1][0] = mp[h-1][w-1] = '#';
	for (int i = 0; i < h; i++)
		for (int j = 0; j < w; j++)
			if (mp[i][j] == '#')
				unite(i, j + h);
	
	for (int i = 0; i < h; i++)
		rw.insert(find(i));
	for (int i = 0; i < w; i++)
		cl.insert(find(i+h));

	printf("%d\n", my_min(rw.size(), cl.size()) - 1);

	return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define int long long
vector<set<int>> v;
vector<char> colour;
bool isValid(int i, char c){
    if(colour[i]!='.' && colour[i]!=c){
        return false;
    }
    for(auto z:v[i]){
        if(colour[z]==c){
            return false;
        }
    }
    return true;
}
int ways=0,n;
void f(int i,char c){
    if(i>=n || i<0 || !isValid(i,c)){
        return;
    }
    char x=colour[i];
    colour[i]=c;
    if(i==n-1){
        ways++;
        colour[i]=x;
        return;
    }
    f(i+1,'R');
    f(i+1,'G');
    f(i+1,'B');
    colour[i]=x;
}
vector<int> vis;
void dfs(int i,vector<int>&ps){
    if(vis[i]==0){
        vis[i]=1;
        ps.push_back(i);
        for(auto z:v[i])dfs(z,ps);
    }
}   
void solve(){
    cin>>n; int m; cin>>m;
    v.resize(n);
    vis.resize(n,0);
    colour.resize(n,'.');
    while(m--){
        int a,b; cin>>a>>b; a--; b--;
        v[a].insert(b);
        v[b].insert(a);
    }
    int ans=1;
    for(int i=0;i<n;i++){
        vector<int> vvv;
        dfs(i,vvv);
        map<int,int> mv;
        int nn=vvv.size();
        set<int> sv;
        if(nn>0){
            for(int j=0;j<nn;j++){
              // cout<<vvv[j]<<" ";
                mv[vvv[j]]=j;
                sv.insert(vvv[j]);
            }
            vector<set<int>> temp(nn),temp1;
            temp1=v;
            for(int j=0;j<n;j++){
                if(sv.find(j)!=sv.end()){
                    for(auto z:v[j]){
                        if(sv.find(z)!=sv.end()){
                            temp[mv[j]].insert(mv[z]);
                        }
                    }
                }
            }
            int xxxx=n;
            v=temp;
            n=nn;
            colour.clear();
            colour.resize(n,'.');
            f(0,'R');
            ways*=3;
            ans*=ways;
            // cout<<ans<<"\n";
            ways=0;
            n=xxxx;
            v=temp1;
        }
    }
    cout<<ans;
}
signed main(){
    // time_t start, end;
    // time(&start);
    cin.tie(NULL);
    ios_base::sync_with_stdio(false);
    // freopen("input.txt", "r", stdin); 
    // freopen("output.txt", "w", stdout);
    int tt=1,t=1; //cin>>tt;
    while(t<=tt){
        //cout<<"Case #"<<t<<": ";
        solve();
        cout<<"\n";
        t++;
    }
    // time(&end);
    // double time_taken = double(end - start);
    // cout << "Time taken by program is : " << fixed << time_taken << setprecision(5);
    // cout << " sec " << endl;
    return 0;
}