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 Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.util.Scanner;
public class Main {
    static boolean[] bh;
    static boolean[] bw;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int h = sc.nextInt();
        int w = sc.nextInt();
        
        int[][] ah = new int[26][h];
        int[][] aw = new int[26][w];
        char[][] ch = new char[h][w];
        int[] a = new int[26];
        
        for (int i = 0; i < h; i++) {
            String str = sc.next();
            for (int j = 0; j < w; j++) {
                ch[i][j] = str.charAt(j);

                ah[ch[i][j] - 'a'][i]++;
                aw[ch[i][j] - 'a'][j]++;
                a[ch[i][j] - 'a']++;
            }
        }
        bh = new boolean[h];
        bw = new boolean[w];
        f(ah, bh, h);
        f(aw, bw, w);
        
        if (no(bh, h)) {
            System.out.println("NO");
            return;
        }
        if (no(bw, w)) {
            System.out.println("NO");
            return;
        }
        
        int odd = 0;
        for (int i = 0; i < 26; i++) {
            if (a[i] % 2 == 1) {
                odd++;
            }
        }
        
        if ((h*w) % 2 == 1) {
            if (odd > 1) {
                System.out.println("NO");
                return;
            }
        } else {
            if (odd != 0) {
                System.out.println("NO");
                return;
            }
        }
        
        System.out.println("YES");
    }
    private static void f(int[][] a, boolean[] b, int n) {
//        UArr.printArr(b);
        for (int i = 0; i < n-1; i++) {
            if (b[i]) continue;
            for (int j = i+1; j < n; j++) {
                if (b[j]) continue;
                boolean flg = true;
//                U.println("i: " + i + ", j: " + j);
                for (int k = 0; k < 26; k++) {
//                    U.println("a[k][i]: " + a[k][i] + ", a[k][j]: " + a[k][j]);
                    if (a[k][i] != a[k][j]) {
//                        U.println("break");
                        flg = false;
                        break;
                    }
                }
                if (flg) {
//                    U.println("Flag is True");
                    b[i] = true;
                    b[j] = true;
//                    UArr.printArr(b);
                    continue;
                }
            }
        }
    }
    static boolean no(boolean[] b, int n) {
        int fCount = 0;
        for (int i = 0; i < n; i++) {
            if (!b[i]) fCount++;
        }
        if (n % 2 == 0 && fCount > 0){
            return true;
        }
        if (n % 2 == 1 && fCount > 1) {
            return true;
        }
        return false;
    }
}