#include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,_6,NAME,...) NAME
#define pr(...) GET_MACRO(__VA_ARGS__,pr6,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__)
#define Pr(a) (#a)<<"="<<(a)<<" "
#define pr1(a) cerr<<Pr(a)<<endl;
#define pr2(a,b) cerr<<Pr(a)<<Pr(b)<<endl;
#define pr3(a,b,c) cerr<<Pr(a)<<Pr(b)<<Pr(c)<<endl;
#define pr4(a,b,c,d) cerr<<Pr(a)<<Pr(b)<<Pr(c)<<Pr(d)<<endl;
#define pr5(a,b,c,d,e) cerr<<Pr(a)<<Pr(b)<<Pr(c)<<Pr(d)<<Pr(e)<<endl;
#define pr6(a,b,c,d,e,f) cerr<<Pr(a)<<Pr(b)<<Pr(c)<<Pr(d)<<Pr(e)<<Pr(f)<<endl;
#define int long long
#define double long double
using namespace std;
const int N = 100010;
const int INF = 1LL<<55;
const int mod = (1e9)+7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
typedef pair<int,int> P;
typedef long long ll;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
ostream& operator<<(ostream& o,P p){return o<<"("<<p.first<<","<<p.second<<")";}
istream& operator>>(istream& i,P &p){return i>>p.first>>p.second;}
ostream& operator<<(ostream& o,vector<auto> &a){int i=0;for(auto t:a)o<<(i++?" ":"")<<t;return o;}
istream& operator>>(istream& i,vector<auto> &a){for(auto &t:a)i>>t;return i;}
void prArr(auto a,string s=" "){int i=0;for(auto t:a)cout<<(i++?s:"")<<t;cout<<endl;}

class RollingHash{
public:
  typedef unsigned long long ull;
  ull B = 1777771; //ハッシュ基数
  //ull B = 100; //ハッシュ基数
  int n;
  string s;
  vector<ull> hash;
  vector<ull> k;

  RollingHash():n(-1){};
  RollingHash(string s):n(s.size()),s(s),hash(n+1),k(n+1){
    for(int i=0;i<n;i++) hash[i+1] = hash[i] * B + s[i];
    k[0] = 1;
    for(int i=1;i<=n;i++) k[i] = k[i-1] * B;
  }

  ull get(int l,int r){assert(0<=l && r<=n && l<=r);return hash[r] - hash[l] * k[r-l];}//[l,r)
  
  //hash[a]とB.hash[b]からみて何文字一致してるか。
  int count(int a, RollingHash &B, int b){
    int L = 0, R = min( n - a, B.n - b ) + 1;
    while( L + 1 < R ){
      int M = ( L + R ) / 2;
      get( a, a + M ) != B.get( b, b + M ) ? R = M : L = M;
    }
    return L;
  }
};

vector<string> rot90(const vector<string> &v){
  int h = v.size(), w = v[0].size();
  vector<string> res(w,string(h,'.'));
  for(int i=0;i<h;i++) for(int j=0;j<w;j++) res[j][h-i-1] = v[i][j];
  return res;
}

typedef unsigned long long ull;
signed main(){
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  int n;
  cin>>n;
  
  vector<string> mp(n+n);
  for(int i=0;i<n;i++) cin>>mp[i];
  
  for(int i=0;i<n;i++) mp[i] += mp[i];
  for(int i=0;i<n;i++) mp[n+i] = mp[i];

  auto rmp = mp;
  rmp = rot90(rmp);
  //rmp = rot90(rmp);
  //rmp = rot90(rmp);
  auto tmp = rmp;
  //for(int i=0;i<n+n;i++) rmp[i] = tmp[n+n-1-i];
  for(int i=0;i<n+n;i++) reverse(rmp[i].begin(),rmp[i].end());
  
  
  vector<RollingHash> A(n+n),B(n+n);
  for(int i=0;i<n+n;i++) A[i] = RollingHash(mp[i]);
  for(int i=0;i<n+n;i++) B[i] = RollingHash(rmp[i]);
  
  //for(int i=0;i<n+n;i++) cout<<mp[i]<<endl;
  //cout<<endl;
  
  //for(int i=0;i<n+n;i++) cout<<rmp[i]<<endl;
  //cout<<endl;

  auto check=[&](int a,int b){
    //pr(a,b);
    for(int i=0;i<n;i++){
      ull ha = A[i+a].get(i+b, i + b + n - i);
      ull hb = B[i+b].get(i+a, i + a + n - i);
      //pr(i, ha,hb);
      if(ha != hb) return 0;
    }
    return 1;
  };
  
  int ans = 0;
  for(int a=0;a<n;a++){
    for(int b=0;b<n;b++){
      ans += check(a,b);
      //pr(a,b,check(a,b));
    }
  }
  cout<<ans<<endl;

  return 0;
}


Measured memory_bytes: 14976