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.*;

public class Main
{

    public void run( )
    {
        Scanner sc = new Scanner( System.in );
        int n = sc.nextInt( );
        int m = sc.nextInt( );
        char[][] texts = new char[ n ][ m ];
        for ( int i = 0; i < n; i++ )
        {
            String text = sc.next( );
            for ( int l = 0; l < m; l++ )
            {
                texts[ i ][ l ] = text.charAt( l );
            }
        }

        Boolean[] okRow = new Boolean[ n ];
        Arrays.fill( okRow, Boolean.FALSE );


        for ( int i = 0; i < n; i++ )
        {
            if ( okRow[ i ] ) continue;

            for ( int j = i + 1; j < n; j++ )
            {
                Boolean[] okRowColumn = new Boolean[ m ];
                Arrays.fill( okRowColumn, Boolean.FALSE );
                for ( int k = 0; k < m; k++ )
                {
                    if ( okRowColumn[ k ] ) continue;

                    for ( int l = 0; l < m; l++ )
                    {
                        if ( texts[ i ][ k ] == texts[ j ][ l ] && texts[ i ][ l ] == texts[ j ][ k ] )
                        {
                            okRowColumn[ k ] = true;
                            okRowColumn[ l ] = true;
                        }
                    }
                }


                if ( !Arrays.asList( okRowColumn ).contains( false ) )
                {
                    okRow[ i ] = true;
                    okRow[ j ] = true;
                }
            }
        }

        Boolean[] okColumn = new Boolean[ m ];
        Arrays.fill( okColumn, Boolean.FALSE );

        for ( int i = 0; i < m; i++ )
        {
            if ( okColumn[ i ] ) continue;

            for ( int j = i + 1; j < m; j++ )
            {
                Boolean[] okColumnRow = new Boolean[ n ];
                Arrays.fill( okColumnRow, Boolean.FALSE );
                for ( int k = 0; k < n; k++ )
                {
                    if ( okColumnRow[ k ] ) continue;

                    for ( int l = 0; l < n; l++ )
                    {
                        if ( texts[ k ][ i ] == texts[ l ][ j ] && texts[ l ][ i ] == texts[ k ][ j ] )
                        {
                            okColumnRow[ k ] = true;
                            okColumnRow[ l ] = true;
                        }
                    }
                }


                if ( !Arrays.asList( okColumnRow ).contains( false ) )
                {
                    okColumn[ i ] = true;
                    okColumn[ j ] = true;
                }
            }
        }

        int countRowNotOk = 0;
        int countColumnNotOk = 0;

        for ( int i = 0; i < n; i++ )
        {
            if ( !okRow[ i ] ) countRowNotOk++;
        }
        for ( int i = 0; i < m; i++ )
        {
            if ( !okColumn[ i ] ) countColumnNotOk++;
        }

        boolean result = true;
        if ( n % 2 == 0 )
        {
            result &= countRowNotOk == 0;
        } else
        {
            result &= countRowNotOk <= 1;
        }
        if( m % 2 == 0)
        {
            result &= countColumnNotOk == 0;
        } else
        {
            result &= countColumnNotOk <= 1;
        }
        if(result)
        {
            System.out.println( "YES" );
        } else
        {
            System.out.println( "NO" );
        }
    }

    public static void main( String[] args )
    {
        new Main( ).run( );
    }
}