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>

using namespace std;

const int N = 205;
const int mod = 1e9 + 7;

int n, m, res = 1;
int par[N];
char a[N][N];

int find(int u) { return (u == par[u]) ? u : par[u] = find(par[u]); }

void join(int u, int v) { par[find(u)] = find(v); }

int main() {
	ios::sync_with_stdio(false);
	cin >> n >> m;
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			cin >> a[i][j];
		}
	}
	if (n & 1) {
		string s, t;
		for (int i = 0; i < m; ++i) {
			s.push_back(a[n / 2][i]);
		}
		t = s, reverse(t.begin(), t.end());
		res *= (s != t) + 1;
	}
	if (m & 1) {
		string s, t;
		for (int i = 0; i < n; ++i) {
			s.push_back(a[i][m / 2]);
		}
		t = s, reverse(t.begin(), t.end());
		res *= (s != t) + 1;		
	}
	for (int i = 0; i < n / 2 + m / 2; ++i) par[i] = i;
	for (int i = 0; i < n / 2; ++i) {
		for (int j = 0; j < m / 2; ++j) {
			set<string> ss;
			vector<char> v;
			vector<int> p;
			v.push_back(a[i][j]), v.push_back(a[n - 1 - i][j]);
			v.push_back(a[i][m - 1 - j]), v.push_back(a[n - 1 - i][m - 1 - j]);
			for (int k = 0; k < 4; ++k) p.push_back(k);
			do {
				string s;
				for (int k = 0; k < 4; ++k) s.push_back(v[p[k]]);
				ss.insert(s);
			} while (next_permutation(p.begin(), p.end()));
			if (ss.size() != 24) res = 1LL * res * ss.size() % mod;
			else join(i, j + n / 2), res = 1LL * res * ss.size() / 2 % mod;
		}
	}
	int cnt = n / 2 + m / 2;
	for (int i = 0; i < n / 2 + m / 2; ++i) cnt -= find(i) == i;
	for (int i = 0; i < cnt; ++i) res = 2 * res % mod;
	cout << res;
}