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: Wrong Answer)

#include<bits/stdc++.h>
#define X first
#define Y second
#define pb emplace_back
#define FOR(i,a,b) for(int (i)=(a);i<(b);++(i))
#define EFOR(i,a,b) for(int (i)=(a);i<=(b);++(i))
#define rep(X,Y) for (int (X) = 0;(X) < (Y);++(X))
#define reps(X,S,Y) for (int (X) = S;(X) < (Y);++(X))
#define rrep(X,Y) for (int (X) = (Y)-1;(X) >=0;--(X))
#define rreps(X,S,Y) for (int (X) = (Y)-1;(X) >= (S);--(X))
#define all(X) (X).begin(),(X).end()
#define rall(X) (X).rbegin(),(X).rend()
#define eb emplace_back
#define UNIQUE(X) (X).erase(unique(all(X)),(X).end())

using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef ll LL;
typedef pii PII;
typedef pll PLL;
template<class T> using vv=vector<vector<T>>;
template<class T> inline bool MX(T &l,const T &r){return l<r?l=r,1:0;}
template<class T> inline bool MN(T &l,const T &r){return l>r?l=r,1:0;}
const ll MOD=1e9+7;

int H;
int W;
int oppo[12];
char S[13][13];

LL mypow(LL base, LL exp) {
  if (exp == 0) return 1 % MOD;
  LL res = mypow(base*base%MOD, exp/2);
  if (exp%2) res = res*base%MOD;
  return res;
}

int Rank(vector<vector<LL>> &mat) {
  int n = mat.size();
  rep(i, n) {
    if (!mat[i][i]) {
      reps(j, i+1, n) {
        if (mat[j][i]) {
          rep(k, n) {
            swap(mat[i][k], mat[j][k]);
          }
          break;
        }
      }
    }

    if (!mat[i][i]) continue;
    LL v = mypow(mat[i][i], MOD-2);
    rep(k, n) (mat[i][k] *= v) %= MOD;
    assert(mat[i][i] == 1);
    rep(j, n) {
      if (i == j) continue;
      if (!mat[j][i]) continue;
      LL t = mat[j][i];
      rep(k, n) {
        mat[j][k] += MOD;
        mat[j][k] -= mat[i][k]*t % MOD;
        mat[j][k] %= MOD;
      }
      assert(mat[j][i] == 0);
    }
  }

  int ret = 0;
  rep(i, n) {
    if (mat[i][i]) ret++;
  }
  return ret/2;
}


void Try(vector<int> &p, vector<int> &q) {
  rep(i, H) oppo[i] = i;
   
  rep(i, H/2) {
    int a = p[i];
    int b = q[i];
    oppo[a] = b;
    oppo[b] = a;
  }

  vector<vector<LL>> mat(W, vector<LL>(W));
  rep(u, W) {
    mat[u][u] = 0;
    rep(v, u) {
      LL t = 1 + rand() % (MOD-1);
      mat[u][v] = t;
      mat[v][u] = MOD - t;
    }
  }

  rep(i, H) {
    int j = oppo[i];
    rep(k, W) {
      rep(l, k) {
        bool ok = true;
        ok &= S[i][k] == S[j][l];
        ok &= S[i][l] == S[j][k];

        if (!ok) mat[k][l] = mat[l][k] = 0;
      }
    }
  }

  if (Rank(mat) == W/2) {
    puts("YES");
    exit(0);
  }
}

void Brute(vector<int> &p, vector<int> &q) {
  do {
    Try(p, q);
  } while (next_permutation(all(q)));
}

void Dfs(int idx, vector<int> &p, vector<int> &q) {
  if (idx >= H) {
    if (p.size() == q.size() && p.size() == H/2) {
      Brute(p, q);
    }
    return;
  }

  if (p.size() < H/2) {
    p.eb(idx);
    Dfs(idx+1, p, q);
    p.pop_back();
  }

  if (q.size() < H/2) {
    q.eb(idx);
    Dfs(idx+1, p, q);
    q.pop_back();
  }
}

int main() {
  scanf("%d%d", &H, &W);
  rep(i, H) {
    scanf(" %s", S[i]);
  }

  vector<int> p, q;
  p.eb(0);
  Dfs(1, p, q);
  puts("NO");
}