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.ArrayList;
import java.util.List;
import java.util.Scanner;

class Main{

    static boolean check(int[] a, int[] b){
        for(int i=0;i<26;++i)if(a[i]!=b[i])return false;
        return true;
    }

    static int pareNum(int[][] cnt){
        int N = cnt.length;
        int res = 0;
        boolean pared[] = new boolean[N];
        for(int i=0;i<N;++i){
            if(pared[i])continue;
            for(int j=i+1;j<N;++j){
                if(check(cnt[i],cnt[j])){
                    pared[i]=pared[j]=true;
                    ++res;
                    break;
                }
            }
        }
        for(int i=0;i<N;++i)if(!pared[i]){
            remain.add(cnt[i]);
            odd.add(N);
        }

        return res;
    }

    static List<int[]> remain = new ArrayList<>();
    static List<Integer> odd = new ArrayList<>();
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int H = scan.nextInt();
        int W = scan.nextInt();
        int[][] mat = new int[H][W];
        for(int i=0;i<H;++i){
            String s = scan.next();
            for(int j=0;j<W;++j)mat[i][j]=s.charAt(j)-'a';
        }
        int vcnt[][] = new int[H][26];
        for(int i=0;i<H;++i){
            for(int j=0;j<W;++j)vcnt[i][mat[i][j]]++;
        }

        if(pareNum(vcnt)<H/2){
            System.out.println("NO");
            return;
        }
        int hcnt[][] = new int[W][26];
        for(int j=0;j<W;++j){
            for(int i=0;i<H;++i)hcnt[j][mat[i][j]]++;
        }
        if(pareNum(hcnt)<=W/2){
            System.out.println("NO");
            return;
        }
        // boolean flag = false;
        // int rem = -1;
        // for(int i=0;i<odd.size();++i){
        //     boolean used = false;
        //     for(int j=0;j<26;++j)if(remain.get(i)[j]%2==1){
        //         if(used || (rem>=0 && rem!=j)){
        //             System.out.println("NO");
        //             return;
        //         }
        //         used=true;
        //         rem=j;
        //     }
        // }
        System.out.println("YES");


    }
}