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 PHP (5.6.30) (judge verdict: Wrong Answer)

<?php

$input = explode(' ', trim(fgets(STDIN)));
$maxH = $input[0];
$maxW = $input[1];

$h = [];
$w = [];
$all = [];
for ($i=0; $i<$maxH; $i++) {
    $h[$i] = str_split(trim(fgets(STDIN)));
    foreach ($h[$i] as $key => $value) {
        $w[$key][$i] = $value;
        $all[] = $value;
    }
}

$isOddH = ($maxH % 2 == 1);
$isOddW = ($maxW % 2 == 1);
$isOddHW = $isOddH && $isOddW;
$isEvenHW = !$isOddH && !$isOddW;


// 各文字の登場回数を数え、奇数のものだけリスト化する
$countAll = array_count_values($all);
$oddList = array_filter($countAll, function($entry) {
    return $entry % 2;
});

// 奇数の文字が二つ以上あったら点対称にはならない
// 奇数の文字が一つあっても良いのは、行と列がどちらも奇数の場合のみ
$oddCount = count($oddList);
if ($oddCount >= 2 ||
    (!$isOddHW && $oddCount >= 1)) {
    echo "NO\n";
    return;
}

// 行内に同じ文字があるかどうか
$dupListH = [];
foreach ($h as $value) {
    $countList = array_count_values($value);
    $dupList = array_filter($countList, function($entry) {
        return $entry >= 2;
    });
    foreach ($dupList as $k => $v) {
        if (isset($dupListH["$k$v"])) {
            $dupListH["$k$v"] += 1;
        } else {
            $dupListH["$k$v"] = 1;
        }
    }
}

$oddDupListH = array_filter($dupListH, function($entry) {
    return $entry % 2;
});

// 行・列が偶数の時は、奇数回重複した文字があったらNG
if (count($oddDupListH) >= 1 && $isEvenHW) {
    echo "NO\n";
    return;
}

// 行だけが奇数なら、列の数の半分だけ重複が許される
if (count($oddDupListH) > intval($maxH/2) && $isOddH && !$isOddW) {
    echo "NO\n";
    return;
}




// 列内に同じ文字があるかどうか
$dupListW = [];
foreach ($w as $value) {
    $countList = array_count_values($value);
    $dupList = array_filter($countList, function($entry) {
        return $entry >= 2;
    });
    foreach ($dupList as $k => $v) {
        if (isset($dupListW["$k$v"])) {
            $dupListW["$k$v"] += 1;
        } else {
            $dupListW["$k$v"] = 1;
        }
    }
}

$oddDupListW = array_filter($dupListW, function($entry) {
    return $entry % 2;
});

// 行・列が偶数の時は、奇数回重複した文字があったらNG
if (count($oddDupListW) >= 1 && $isEvenHW) {
    echo "NO\n";
    return;
}

// 列だけが奇数なら、行の数の半分だけ重複が許される
if (count($oddDupListW) > intval($maxW/2) && $isOddW && !$isOddH) {
    echo "NO\n";
    return;
}
echo "YES\n";