Problem:
Score : 1900 points

Problem Statement

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:

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).

Sample Input 1

2 2
cf
cf

Sample Output 1

6

The following 6 placements of characters can be obtained:

Sample Input 2

1 12
codefestival

Sample Output 2

2

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
#define MOD 1000000007
using namespace std;
typedef long long LL;
LL gcd(LL a, LL b){
	if(b == 0) return a;
	return gcd(b,a%b);
}
int main(){
	int a, b;
	cin >> a >> b;
	int freq[26];
	string s[a];
	for(int i = 0; i < a; i++) cin >> s[i];
	LL ans = 1;
	LL all24 = 1;

	for(int i = 0; i < a-1-i; i++){
		for(int j = 0; j < b-1-j; j++){
			//cout << i << " " << j << endl;
			for(int z = 0; z < 26; z++) freq[z] = 0;
			freq[s[i][j]-'a']++;
			freq[s[a-1-i][j]-'a']++;
			freq[s[i][b-1-j]-'a']++;
			freq[s[a-1-i][b-1-j]-'a']++;
			LL r = 24;
			for(int z = 0; z < 26; z++){
				if(freq[z] == 4) r /= 24;
				if(freq[z] == 3) r /= 6;
				if(freq[z] == 2) r /= 2;
			}
			if(r != 24) all24 = 0;
			ans *= r;
			ans %= MOD;
		}
	}
	if(all24 && a >= 4 && b >= 1){
			ans *= 500000004;
			ans %= MOD;
	}
	if(a % 2){
		int c = (a-1)/2;
		LL ok = 1;
		for(int j = 0; j < b; j++){
			if(s[c][j] != s[c][b-1-j]) ok = 2;
		}
		ans *= ok;
		ans %= MOD;
	}
	if(b % 2){
		int c = (b-1)/2;
		LL ok = 1;
		for(int j = 0; j < a; j++){
			if(s[j][c] != s[a-1-j][c]) ok = 2;
		}
		ans *= ok;
		ans %= MOD;
	}
	cout << ans % MOD << endl;
}