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 (GCC 5.4.1) (judge verdict: Accepted)

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

typedef long long int int64;

#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define ABS(a) ((a)>(0)?(a):-(a))

#define POS(i,j) ((i)*w+(j))

int func(int i,int j,char *board,int h,int w){
  int k;
  for(k=0;k<h;k++){
    if(board[POS(k,i)]!=board[POS(h-1-k,j)]) return 0;
  }
  return 1;
}

int calcCol(char *board,int h,int w){
  int flag[16];
  int i,j;
  for(i=0;i<w;i++) flag[i]=0;
  int useCenter=0;
  for(i=0;i<w;i++){
    if(flag[i]) continue;
    for(j=i+1;j<w;j++){
      if(flag[j]) continue;
      if(func(i,j,board,h,w)){
	flag[i]=1;
	flag[j]=1;
	break;
      }
    }
    if(flag[i]==0){
      if(w%2==0 || useCenter) return 0;
      for(j=0;j<h-1-j;j++){
	if(board[POS(j,i)]!=board[POS(h-1-j,i)]) return 0;
      }
      useCenter=1;
      flag[i]=1;
    }
  }
  return 1;
}

void swapRow(int a,int b,char *board,int h,int w){
  int i;
  for(i=0;i<w;i++){
    char t=board[POS(a,i)];
    board[POS(a,i)]=board[POS(b,i)];
    board[POS(b,i)]=t;
  }
  return;
}

int loopRow(int d,char *board,int h,int w){
  if(d>=h-d-1) return calcCol(board,h,w);
  int i,j;
  for(i=d;i<h-d;i++){
    for(j=i+1;j<h-d;j++){
      swapRow(d,i,board,h,w);
      swapRow(h-d-1,j,board,h,w);
      if(loopRow(d+1,board,h,w)) return 1;
      swapRow(d,i,board,h,w);
      swapRow(h-d-1,j,board,h,w);
    }
  }
  return 0;
}

int calc(char *board,int h,int w){
  return loopRow(0,board,h,w);
}

void run(void){
  int h,w;
  scanf("%d%d",&h,&w);
  char *board=(char *)malloc(sizeof(char)*(h*w+1));
  int i;
  for(i=0;i<h;i++) scanf("%s",board+POS(i,0));
  printf("%s\n",calc(board,h,w)?"YES":"NO");
  free(board);
}

int main(void){
  run();
  return 0;
}