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 Rust (1.42.0) (judge verdict: Accepted)

use proconio::input;

fn generate_even_pairings(n: usize) -> Vec<Vec<(usize, usize)>> {
    assert!(n % 2 == 0);

    fn dfs(ckd: &mut [bool], now: &mut Vec<(usize, usize)>, ans: &mut Vec<Vec<(usize, usize)>>) {
        if 2 * now.len() == ckd.len() {
            ans.push(now.clone());
            return;
        }
        let i = ckd
            .iter()
            .copied()
            .enumerate()
            .find(|&(_, b)| !b)
            .unwrap()
            .0;
        ckd[i] = true;
        for j in 0..ckd.len() {
            if ckd[j] {
                continue;
            }
            ckd[j] = true;
            now.push((i, j));
            dfs(ckd, now, ans);
            now.pop();
            ckd[j] = false;
        }
        ckd[i] = false;
    }

    let mut ckd = vec![false; n];
    let mut now = vec![];
    let mut ans = vec![];

    dfs(&mut ckd, &mut now, &mut ans);

    ans
}

fn convert_to_permutation(pairs: Vec<(usize, usize)>) -> Vec<usize> {
    let n = pairs.len() * 2;
    let mut seq = vec![0; n];
    for (i, (x, y)) in pairs.into_iter().enumerate() {
        seq[i] = x;
        seq[n - 1 - i] = y;
    }
    seq
}

fn generate_representitve_parmutations(n: usize) -> Vec<Vec<usize>> {
    if n % 2 == 0 {
        generate_even_pairings(n)
            .into_iter()
            .map(convert_to_permutation)
            .collect()
    } else {
        (0..n)
            .map(|center| {
                generate_even_pairings(n - 1)
                    .into_iter()
                    .map(convert_to_permutation)
                    .map(move |mut seq| {
                        for x in &mut seq {
                            if center <= *x {
                                *x += 1;
                            }
                        }
                        seq.insert(n / 2, center);
                        seq
                    })
            })
            .flatten()
            .collect()
    }
}

fn main() {
    input!(h: usize, w: usize, v: [proconio::marker::Chars; h]);
    let ans = generate_representitve_parmutations(w).iter().any(|seq| {
        let mut v: Vec<Vec<char>> = v
            .iter()
            .map(|s| {
                let mut ret = vec!['$'; w];
                for (i, &x) in seq.iter().enumerate() {
                    ret[i] = s[x];
                }
                ret
            })
            .collect();

        loop {
            if v.len() <= 1 {
                return v.is_empty() || v[0] == v[0].iter().copied().rev().collect::<Vec<char>>();
            }
            if let Some((i, j)) = (0..v.len())
                .map(|i| {
                    let s = &v[i];
                    let t: &Vec<_> = &s.iter().copied().rev().collect();
                    if let Some(j) = v
                        .iter()
                        .enumerate()
                        .skip(i + 1)
                        .find(|&(_, u)| t == u)
                        .map(|p| p.0)
                    {
                        Some((i, j))
                    } else {
                        None
                    }
                })
                .filter_map(std::convert::identity)
                .next()
            {
                assert!(i < j);
                v.remove(j);
                v.remove(i);
            } else {
                return false;
            }
        }
    });
    println!("{}", if ans { "YES" } else { "NO" });
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_generate_representitive_permutations_zero() {
        let expected = vec![Vec::<usize>::new()];
        let result = generate_representitve_parmutations(0);
        assert_eq!(expected, result);
    }

    #[test]
    fn test_generate_representitive_permutations_one() {
        let expected = vec![vec![0]];
        let result = generate_representitve_parmutations(1);
        assert_eq!(expected, result);
    }

    #[test]
    fn test_generate_representitive_permutations_two() {
        let expected = vec![vec![0, 1]];
        let result = generate_representitve_parmutations(2);
        assert_eq!(expected, result);
    }

    #[test]
    fn test_generate_representitive_permutations_three() {
        let expected = vec![vec![1, 0, 2], vec![0, 1, 2], vec![0, 2, 1]];
        let result = generate_representitve_parmutations(3);
        assert_eq!(expected, result);
    }

    #[test]
    fn test_generate_representitive_permutations_four() {
        let expected = vec![vec![0, 2, 3, 1], vec![0, 1, 3, 2], vec![0, 1, 2, 3]];
        let result = generate_representitve_parmutations(4);
        assert_eq!(expected, result);
    }

    #[test]
    fn test_generate_representitive_permutations_five() {
        let result = generate_representitve_parmutations(5);
        println!("{:?}", &result);
        assert_eq!(15, result.len());
    }

    #[test]
    fn test_generate_representitive_permutations_six() {
        let result = generate_representitve_parmutations(6);
        println!("{:?}", &result);
        assert_eq!(15, result.len());
    }

    #[test]
    fn test_generate_even_pairs_zero() {
        let expected = vec![Vec::<(usize, usize)>::new()];
        let result = generate_even_pairings(0);
        assert_eq!(expected, result);
    }

    #[test]
    fn test_generate_even_pairs_two() {
        let expected = vec![vec![(0, 1)]];
        let result = generate_even_pairings(2);
        assert_eq!(expected, result);
    }

    #[test]
    fn test_generate_even_pairs_four() {
        let expected = vec![
            vec![(0, 1), (2, 3)],
            vec![(0, 2), (1, 3)],
            vec![(0, 3), (1, 2)],
        ];
        let result = generate_even_pairings(4);
        assert_eq!(expected, result);
    }
}