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: Accepted)

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

typedef pair<int,int> P;

int h, w;
string s[12];

void check(vector<P> A, int S){
  
  string t[12];
  
  for(int i=0;i<(int)A.size();i++){
    
    t[i] = s[A[i].first];
    
    t[h-i-1] = s[A[i].second];
    
  }
  
  if( h % 2 == 1 ){
    
    for(int i=0;i<h;i++){
      
      if( S >> i & 1 ) continue;
      
      t[h/2] = s[i];
      
    }
    
  }
  
  int S2 = 0;
  
  for(int i=0;i<w;i++){
    
    if( S2 >> i & 1 ) continue;
    
    for(int j=i+1;j<w;j++){
      
      if( S2 >> j & 1 ) continue;
      
      int flag = 1;
      
      for(int k=0;k<h;k++){
	if( t[k][i] != t[h-k-1][j] ) flag = 0;
      }
      
      if( flag == 1 ){
	S2 |= ( 1 << i ) | ( 1 << j );
	break;
      }
      
    }
    
  }
      
  if( w % 2 == 0 && __builtin_popcount(S2) == w ){
    cout << "YES" << endl;
    exit(0);
  }
  
  if( w % 2 == 1 && __builtin_popcount(S2) == w - 1 ){
    
    for(int i=0;i<w;i++){
      
      if( S2 >> i & 1 ) continue;
      
      int flag = 1;
      
      for(int j=0;j<h;j++){
	if( t[j][i] != t[h-j-1][i] ) flag = 0;
      }
      
      if( flag == 1 ){
	cout << "YES" << endl;
	exit(0);
      }
      
    }
    
  }
  
}

void dfs(vector<P> A, int S, int X){
  
  if( h - __builtin_popcount(S) <= 1 ){
    
    check( A, S );
    
    return;
  }
  
  int idx = -1;
  
  for(int i=0;i<h;i++){
    
    if( i == X ) continue;
    
    if( S >> i & 1 ) continue;
    
    idx = i;
    
    break;
    
  }
  
  if( idx == -1 ) return;
  
  for(int i=idx+1;i<h;i++){
    
    if( i == X ) continue;
    
    if( S >> i & 1 ) continue;
    
    vector<P> nA = A;
    
    nA.push_back(P( idx, i ));
    
    int nS = S | ( 1 << idx ) | ( 1 << i );
    
    dfs( nA, nS, X );
    
  }
  
}

signed main(){
  
  cin>>h>>w;
  
  for(int i=0;i<h;i++) cin>>s[i];
  
  if( h % 2 == 0 ) dfs( vector<P>(0), 0, -1 );
  else{
    for(int i=0;i<h;i++) dfs( vector<P>(0), 0, i );
  }
  
  cout << "NO" << endl;
  
  return 0;
}