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 Python (3.4.3) (judge verdict: Wrong Answer)

import sys
input = sys.stdin.readline
import itertools
import numpy as np
from scipy.sparse.csgraph import connected_components

H,W = map(int,input().split())
words = np.array([list(input().rstrip()) for _ in range(H)], dtype='U1')

def gen_pair_pattern_even(rest):
    # 偶数個を仮定
    if len(rest) == 0:
        yield []
        return
    if len(rest) == 1:
        x = rest.pop()
        yield [(x,x)]
        return
    li = list(rest)
    x = li[0]
    for y in li[1:]:
        se = rest.copy()
        se.remove(x)
        se.remove(y)
        for p in gen_pair_pattern_even(se):
            yield p + [(x,y)]    

def gen_pair_pattern(N):
    if N & 1:
        for n in range(N):
            se = set(x for x in range(N) if x != n)
            for p in gen_pair_pattern_even(se):
                yield p + [(n,n)]
    else:
        for p in gen_pair_pattern_even(set(range(N))):
            yield p

def test(row_pairs):
    graph = np.ones((W,W), dtype = np.bool)
    for r1,r2 in row_pairs:
        graph &= (words[r1][:,None] == words[r2][None,:])
    se = set(range(W))
    while se:
        removed = False
        for i,j in itertools.combinations(se,2):
            if graph[i,j]:
                se.remove(i)
                se.remove(j)
                removed = True
                break
        if not removed:
            break
    if len(se) > 1:
        return False
    return True

bl = False
for p in gen_pair_pattern(H):
    if test(p):
        bl = True
        break

answer = 'YES' if bl else 'NO'
print(answer)