Problem:
Score : 700 points

Problem Statement

There is an H \times W grid (H vertical, W horizontal), where each square contains a lowercase English letter.
Specifically, the letter in the square at the i-th row and j-th column is equal to the j-th character in the string S_i.

Snuke can apply the following operation to this grid any number of times:

Choose two different rows and swap them. Or, choose two different columns and swap them.

Snuke wants this grid to be symmetric.
That is, for any 1 \leq i \leq H and 1 \leq j \leq W, the letter in the square at the i-th row and j-th column and the letter in the square at the (H + 1 - i)-th row and (W + 1 - j)-th column should be equal.

Determine if Snuke can achieve this objective.

Constraints

1 \leq H \leq 12

1 \leq W \leq 12

|S_i| = W

S_i consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

H W
S_1
S_2
:
S_H

Output

If Snuke can make the grid symmetric, print YES; if he cannot, print NO.

Sample Input 1

2 3
arc
rac

Sample Output 1

YES

If the second and third columns from the left are swapped, the grid becomes symmetric, as shown in the image below:

Sample Input 2

3 7
atcoder
regular
contest

Sample Output 2

NO

Sample Input 3

12 12
bimonigaloaf
faurwlkbleht
dexwimqxzxbb
lxdgyoifcxid
ydxiliocfdgx
nfoabgilamoi
ibxbdqmzxxwe
pqirylfrcrnf
wtehfkllbura
yfrnpflcrirq
wvcclwgiubrk
lkbrwgwuiccv

Sample Output 3

YES

Solution in C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

#include <bits/stdc++.h>
using namespace std;
#define REP(i,a,n) for(int i=(a); i<(int)(n); i++)
#define rep(i,n) REP(i,0,n)
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it)
#define ALLOF(c) (c).begin(), (c).end()
typedef long long ll;
typedef unsigned long long ull;


int check(string s, string t){
  vector<bool> used(s.size(), false);

  rep(i,s.size()){
    if(used[i]) continue;
    char sc = s[i];
    char tc = t[i];
    rep(j,s.size()){
      if(i==j) continue;
      if(used[j]) continue;
      char sb = s[j];
      char tb = t[j];
      if(sc == tb && tc == sb){
        used[i] = true;
        used[j] = true;
        break;
      }
    }
  }
  int cnt = 0;
  rep(i,s.size()){
    if(used[i]){
      cnt++;
    }
  }
  return cnt;
}


int main(){
  int H, W;
  cin >> H >> W;
  vector<string> v;
  rep(i,H){
    string s;
    cin >> s;
    v.push_back(s);
  }

  vector<vector<int>> w;
  rep(i,H){
    vector<int> tmp;
    rep(j,H){
      if(i==j) continue;
      int res = check(v[i],v[j]);
      if((W%2==0 && res == W) || (W%2==1 && res == W-1)){
        tmp.push_back(j);
      }

    }
    w.push_back(tmp);
  }

  vector<bool> used(H, false);
  vector<pair<int,int>> pr;
  rep(i,H){
    if(used[i]) continue;
    rep(j,w[i].size()){
      if(used[w[i][j]]) continue;
      pr.push_back(make_pair(i,w[i][j]));
      used[i] = true;
      used[w[i][j]] = true;
      break;
    }
  }
  int cnt = 0;
  rep(i,H){
    if(used[i]) cnt++;
  }

  if((H%2==0 && cnt != H) || (H%2==1 && cnt != H-1)){
    cout << "NO" << endl;
    return 0;
  }

  vector<bool> used2(W,false);
  int base1 = pr[0].first;
  int base2 = pr[0].second;
  rep(j,W){
    if(used2[j]) continue;
    
    REP(k,j+1,W){
      if(v[base1][j] == v[base2][k] && v[base2][j] == v[base1][k]){
        bool flg = true;
        REP(l,1,pr.size()){
          int tr1 = pr[l].first;
          int tr2 = pr[l].second;
          if(v[tr1][j] == v[tr2][k] && v[tr2][j] == v[tr1][k]){
            ;//ok
          }else{
            flg = false;
          }
        }

        if(flg){
          used2[j] = true;
          used2[k] = true;
          break;
        }
      }
    }
  }
  cnt = 0;
  rep(i,W){
    if(used2[i]) cnt++;
  }

  if((W%2==0 && cnt != W) || (W%2==1 && cnt != W-1)){
    cout << "NO" << endl;
    return 0;
  }
  
  cout << "YES" << endl;
  
  return 0;
}