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 Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

	public static void main(String[] args) throws IOException {
		MyScanner sc = new MyScanner(System.in);
		int n = sc.nextInt();
		char[][] map = new char[2*n][2*n];
		char[][] S = new char[n][n];
		for(int i=0; i<n; i++) {
			String s = sc.next();
			for(int j=0; j<n; j++) {
				S[i][j] = s.charAt(j);
			}
		}
		if(n==1) {
			System.out.println(1);
			return;
		}
		{
			for(int l=0; l<2*n; l+=n) {
				for(int k=0; k<2*n; k+=n) {
					for(int i=0; i<n; i++) {
						for(int j=0; j<n; j++) {
							map[l+i][k+j] = S[i][j];
						}
					}		
				}	
			}
		}
		int ans = 0;
		for(int i=0; i<n; i++) {
			if(isSym(i, 0, n, map)) {
				ans += (n-i);
			}
		}
		for(int i=1; i<n; i++) {
			if(isSym(0, i, n, map)) {
				ans += (n-i);
			}
		}
		System.out.println(ans);
	}
	
	static boolean isSym(int i, int j, int n, char[][] map) {
		for(int ii=0; ii<n; ii++) {
			for(int jj=ii; jj<n; jj++) {
				if(map[i+ii][j+jj]!=map[i+jj][j+ii]) {
					return false;
				}
			}
		}
		return true;
	}

	static class MyScanner
	{
		BufferedReader br;
		StringTokenizer st;
		public MyScanner(InputStream s)
		{
			br=new BufferedReader(new InputStreamReader(s));
		}
		public String nextLine() throws IOException
		{
			return br.readLine();
		}
		public String next() throws IOException
		{
			while(st==null || !st.hasMoreTokens())
				st=new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());
			
		}
		public double nextDouble() throws IOException
		{
			return Double.parseDouble(next());
		}
		public boolean ready() throws IOException
		{
			return br.ready();
		}
		public long nextLong() throws IOException
		{
			return Long.parseLong(next());
		}
	}
}