Problem: Snuke has a grid with H rows and W columns. The square at the i-th row and j-th column contains a character S_{i,j}.

He can perform the following two kinds of operation on the grid:

* Row-reverse: Reverse the order of the squares in a selected row.
* Column-reverse: Reverse the order of the squares in a selected column.



For example, reversing the 2-nd row followed by reversing the 4-th column will result as follows:

<image>

By performing these operations any number of times in any order, how many placements of characters on the grid can be obtained?

Constraints

* 1≦H,W≦200
* S_{i,j} is a lowercase English letter (`a`-`z`).

Input

The input is given from Standard Input in the following format:


H W
S_{1,1}S_{1,2}...S_{1,W}
S_{2,1}S_{2,2}...S_{2,W}
:
S_{H,1}S_{H,2}...S_{H,W}


Output

Print the number of placements of characters on the grid that can be obtained, modulo 1000000007 (=10^9+7).

Examples

Input

2 2
cf
cf


Output

6


Input

1 12
codefestival


Output

2

Solution (in CPP):

Solution:
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define REP(i,n) for(int i=0;i<(n);i++)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef long long ll;

template<class T> inline void read(T &x){
	int f=0; x=0; char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) f|=(ch=='-');
	for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
	if(f) x=-x;
}

const int N=205,mod=1e9+7;
int pa[N],c[26],h,w,n,m,pw,ans=1;
char s[N][N];

int gp(int x){
	return pa[x]==x?x:pa[x]=gp(pa[x]);
}

int main(){
	read(h),read(w);
	rep(i,1,h) scanf("%s",s[i]+1);
	n=h/2,m=w/2,pw=n+m;
	rep(i,1,n+m) pa[i]=i;
	int fac[5]={1,1,2,6,24};
	rep(i,1,n) rep(j,1,m){
		fill(c,c+26,0);
		c[s[i][j]-'a']++;
		c[s[h+1-i][j]-'a']++;
		c[s[i][w+1-j]-'a']++;
		c[s[h+1-i][w+1-j]-'a']++;
		int res=24;
		REP(i,26) res/=fac[c[i]];
		if(res==24) ans=12ll*ans%mod,pa[gp(i)]=gp(n+j);
		else ans=(ll)res*ans%mod;
	}
	rep(i,1,n+m) if(pa[i]==i) pw--;
	while(pw--) ans=2*ans%mod;
	if(h&1){
		int p=n+1,l=1,r=w,flag=0;
		while(l<r) flag|=(s[p][l]!=s[p][r]),l++,r--;
		if(flag) ans=2*ans%mod;
	}
	if(w&1){
		int p=m+1,l=1,r=h,flag=0;
		while(l<r) flag|=(s[l][p]!=s[r][p]),l++,r--;
		if(flag) ans=2*ans%mod;
	}
	cout<<ans<<endl;
	return 0;
}