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;
char str[15][15];

int p;
int rp[11000][15];

int trp[15];
void bt(int cnt) {
    int i;
    if (cnt==h) {
        for (i=0;i<h;i++) rp[p][i] = trp[i];
        p++;
        return;
    }
    if (trp[cnt]!=cnt) {
        bt(cnt+1);
        return;
    }
    for (i=cnt+1;i<h;i++) {
        if (trp[i]!=i) continue;
        trp[cnt] = i; trp[i] = cnt;
        bt(cnt+1);
        trp[i] = i;
    }
    trp[cnt] = cnt;
}

int bit[15];
int wp[15];
bool good(int cnt, int rem) {
    int i;
    if (cnt==w) return true;
    if (wp[cnt]!=cnt) {
        return good(cnt+1,rem);
    }
    for (i=cnt;i<w;i++){
        if ((!rem)&&i==cnt) continue;
        if (wp[i]!=i) continue;
        if (bit[cnt]>>i&1) {
            wp[cnt] = i; wp[i] = cnt;
            if (good(cnt+1,rem-(i==cnt))) return true;
            wp[i] = i;
        }
    }
    wp[cnt] = cnt;
    return false;
}

bool rchk() {
    int i, j, k, l;
    for (k=0;k<p;k++) {
        for (j=0;j<w;j++) bit[j] = (1<<w)-1;
        for (i=0;i<h;i++) {
            if (rp[k][i]<i) continue;
            for (j=0;j<w;j++) {
                for (l=0;l<w;l++) {
                    if (str[i][j]!=str[rp[k][i]][l]||
                        str[i][l]!=str[rp[k][i]][j]) bit[j] &= ~(1<<l);
                }
            }
        }
        for (j=0;j<w;j++) wp[j] = j;
        if (good(0,w%2)) return true;
    }
    return false;
}

void print(bool a) {
    puts(a?"YES":"NO");
    exit(0);
}

int main() {
    int i, j;

    scanf("%d%d",&h,&w);
    for (i=0;i<h;i++) scanf("%s",str[i]);
    for (i=0;i<h;i++) trp[i] = i;
    if (h&1) {
        bt(1);
        for (i=0;i<h;i++) {
            for (j=0;j<w;j++) swap(str[0][j],str[i][j]);
            if (rchk()) print(1);
        }
        print(0);
    }
    else {
        bt(0);
        print(rchk());
    }

    return 0;
}