Problem:
Score : 500 points

Problem Statement

Snuke has two boards, each divided into a grid with N rows and N columns.
For both of these boards, the square at the i-th row from the top and the j-th column from the left is called Square (i,j).

There is a lowercase English letter written in each square on the first board. The letter written in Square (i,j) is S_{i,j}. On the second board, nothing is written yet.

Snuke will write letters on the second board, as follows:

First, choose two integers A and B ( 0 \leq A, B < N ).

Write one letter in each square on the second board.
Specifically, write the letter written in Square ( i+A, j+B ) on the first board into Square (i,j) on the second board.
Here, the k-th row is also represented as the (N+k)-th row, and the k-th column is also represented as the (N+k)-th column.

After this operation, the second board is called a good board when, for every i and j ( 1 \leq i, j \leq N ), the letter in Square (i,j) and the letter in Square (j,i) are equal.

Find the number of the ways to choose integers A and B ( 0 \leq A, B < N ) such that the second board is a good board.

Constraints

1 \leq N \leq 300

S_{i,j} ( 1 \leq i, j \leq N ) is a lowercase English letter.

Input

Input is given from Standard Input in the following format:

N
S_{1,1}S_{1,2}..S_{1,N}
S_{2,1}S_{2,2}..S_{2,N}
:
S_{N,1}S_{N,2}..S_{N,N}

Output

Print the number of the ways to choose integers A and B ( 0 \leq A, B < N ) such that the second board is a good board.

Sample Input 1

2
ab
ca

Sample Output 1

2

For each pair of A and B, the second board will look as shown below:

The second board is a good board when (A,B) = (0,1) or (A,B) = (1,0), thus the answer is 2.

Sample Input 2

4
aaaa
aaaa
aaaa
aaaa

Sample Output 2

16

Every possible choice of A and B makes the second board good.

Sample Input 3

5
abcde
fghij
klmno
pqrst
uvwxy

Sample Output 3

0

No possible choice of A and B makes the second board good.

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

#include <bits/stdc++.h>
using namespace std;

using ll = long long;

#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, m, n) for (int i = m; i < n; i++)
#define pb push_back
#define mp make_pair
#define fill(x, y) memset(x, y, sizeof(x))
#define even(x) x % 2 == 0
#define odd(x) x % 2 != 0
#define all(x) x.begin(), x.end()
#define pcnt __builtin_popcount
#define buli(x) __builtin_popcountll(x)
#define F first
#define S second
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());

ll qp(ll a, ll b, int mo) { ll ans = 1; do { if (b & 1) ans = 1ll * ans * a % mo; a = 1ll * a * a % mo; } while (b >>= 1); return ans; }
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

template <typename T>
vector<T> make_v(size_t a) { return vector<T>(a); }

template <typename T, typename... Ts>
auto make_v(size_t a, size_t b, Ts... ts) { return vector<decltype(make_v<T>(b, ts...))>(a, make_v<T>(b, ts...)); }
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type
fill_v(T &t, const V &v) { t = v; }
template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type
fill_v(T &t, const V &v) { for (auto &e : t) fill_v(e, v); }
// auto dp = make_v<int>(4, h, w);
// fill_v(dp, 0);

const ll INF_LL = (1ll << 60);
const int INF_INT = (int)1e9;
const ll MOD_CONST = (ll)(1e9 + 7);

template <class T>
bool chmax(T &a, const T &b) { if (a < b) { a = b; return 1; } return 0; }
template <class T>
bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; }

inline tuple<ll, ll> rotate45(tuple<ll, ll> p) { ll x = get<0>(p), y = get<1>(p); return tuple<ll, ll>(x + y, x - y); }

int lcp(const string &s1, const string &s2) {
	int cnt = 0, n = min(s1.size(), s2.size());
	REP(i, n) {
		if (s1[i] == s2[i]) cnt++;
		else break;
	}
	return cnt;
}

long long CountZeroSubstrings(vector<ll> A) {
    int n = A.size();

    vector<long long> S(n+1, 0);
    for (int i = 0; i < n; i++)
        S[i+1] = S[i] + A[i];

    long long answer = 0;
    unordered_map<long long, int> H;
    for (int i = 0; i <= n; i++) {
        if (H.count(S[i]))
            answer += H[S[i]];
        H[S[i]]++;      
    }

    return answer;
}

bool isSym(vector<string> &ss)
{
	REP(x, ss.size()) {
		REP(y, ss.size()) {
			if (ss[y][x] != ss[x][y]) return false;
		}
	}
	return true;
}

int main(void)
{
	cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(20);

	int N; cin >> N;
	vector<string> ss(N);
	REP(i, N) {
		string str; cin >> str;
		ss[i] = str;
	}

	if (isSym(ss)) {
		int cnt = 0;
		REP(i, N) {
			bool sym = true;			
			REP(y, N) {
				int ny = y - i; if (ny < 0) ny += N;
				bool out = false;
				REP(x, N) {
					int nx = x - i; if (nx < 0) nx += N;
					if (ss[ny][x] != ss[nx][y]) {
						sym = false; out = true;
						break;
					}
				}
				if (out) break;
			}
			if (sym) cnt++;
		}
		cout << cnt * 2 << endl;
	}else {
		int cnt = 0;
		REP(i, N) {
			bool sym = true;			
			REP(y, N) {
				int ny = y - i; if (ny < 0) ny += N;
				bool out = false;
				REP(x, N) {
					int nx = x - i; if (nx < 0) nx += N;
					if (ss[ny][x] != ss[nx][y]) {
						sym = false; out = true;
						break;
					}
				}
				if (out) break;
			}
			if (sym) cnt++;
		}
		REP(i, N) {
			bool sym = true;			
			REP(x, N) {
				int ny = x - i; if (ny < 0) ny += N;
				bool out = false;
				REP(y, N) {
					int nx = y - i; if (nx < 0) nx += N;
					if (ss[x][ny] != ss[y][nx]) {
						sym = false; out = true;
						break;
					}
				}
				if (out) break;
			}
			if (sym) cnt++;
		}
		cout << cnt << endl;
	}

	return 0;
}