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>
using namespace std;

int H, W;
vector<string> S;

bool check(auto T) {
  vector<bool> used(W);
  set<int> uniq;
  for(auto i=0; i<W; ++i) if(!used[i]) {
    for(auto j=i+1; j<W; ++j) if(!used[j]) {
      auto same = true;
      for(auto k=0; k<H; ++k) same &= (T[k][i] == T[H-1-k][j]);
      if(!same) continue;
      used[i] = used[j] = true;
      break;
    }
    if(!used[i]) uniq.emplace(i);
  }
  if(uniq.empty()) return true;
  if(2 <= uniq.size()) return false;
  auto i = *begin(uniq);
  for(auto k=0; k<H; ++k) if(T[k][i] != T[H-1-k][i]) return false;
  return true;
}

bool dfs(auto T, auto used, auto n) {
  if(n == H) return check(T);
  if(used[n]) return dfs(T, used, n+1);
  for(auto i=0; i<H; ++i) if(T[i].empty()) {
    used[n] = true;
    T[i] = S[n];
    for(auto m=n+1; m<H; ++m) if(!used[m]) {
      used[m] = true;
      T[H-1-i] = S[m];
      if(dfs(T, used, n+1)) return true;
      used[m] = false;
      T[H-1-i].clear();
    }
    return false;
  }
  assert(-1);
}

string solve() {
  if(H&1) for(auto i=0; i<H; ++i) {
    vector<string> T(H);
    vector<bool> used(H);
    T[H/2] = S[i];
    used[i] = true;
    if(dfs(T, used, 0)) return "YES";
  } else {
    if(dfs(vector<string>(H), vector<bool>(H), 0)) return "YES";
  }
  return "NO";
}

int main() {
  cin >> H >> W;
  S.resize(H);
  for(auto& i: S) cin >> i;
  cout << solve() << endl;
}