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 C (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#include <stdlib.h>

int is_equal(int *A, int *B){
	int i;
	for(i = 0; i < 26; i++){
		if(A[i] != B[i]){
			return 0;
		}
	}
	return 1;
}

int is_equal_t(char **S, int i, int l, int H, int W){
	int j;
	for(j = 0; j < W; j++){
		if(S[i][j] != S[l][j]){
			return 0;
		}
	}
	return 1;
}

int is_equal_y(char **S, int j, int l, int H, int W){
	int i;
	for(i = 0; i < H; i++){
		if(S[i][j] != S[i][l]){
			return 0;
		}
	}
	return 1;
}

int main(){
	int H, W, i, j, k, l;
	scanf("%d%d", &H, &W);
	int *alf = (int *)malloc(sizeof(int) * 26);
	for(k = 0; k < 26; k++){
		alf[k] = 0;
	}
	char **S = (char **)malloc(sizeof(char *) * H);
	for(i = 0; i < H; i++){
		S[i] = (char *)malloc(sizeof(char) * (W + 1));
		scanf("%s", S[i]);
		for(j = 0; j < W; j++){
			alf[(int)S[i][j] - (int)'a']++;
		}
	}
	int alf_odd = 0;
	for(k = 0; k < 26; k++){
		alf_odd += alf[k] % 2;
	}
	if(alf_odd != (H * W) % 2){
		printf("NO\n");
		return 0;
	}
	int **tate = (int **)malloc(sizeof(int *) * H);
	for(i = 0; i < H; i++){
		tate[i] = (int *)malloc(sizeof(int) * 26);
		for(k = 0; k < 26; k++){
			tate[i][k] = 0;
		}
	}
	int **yoko = (int **)malloc(sizeof(int *) * W);
	for(j = 0; j < W; j++){
		yoko[j] = (int *)malloc(sizeof(int) * 26);
		for(k = 0; k < 26; k++){
			yoko[j][k] = 0;
		}
	}
	for(i = 0; i < H; i++){
		for(j = 0; j < W; j++){
			tate[i][(int)S[i][j] - (int)'a']++;
			yoko[j][(int)S[i][j] - (int)'a']++;
		}
	}
/*	for(i = 0; i < H; i++){
		alf_odd = 0;
		for(k = 0; k < 26; k++){
			alf_odd += tate[i][k] % 2;
		}
		if(alf_odd != H % 2){
			printf("NO\n");
		}
		return 0;
	}
	for(j = 0; j < W; j++){
		alf_odd = 0;
		for(k = 0; k < 26; k++){
			alf_odd += yoko[j][k] % 2;
		}
		if(alf_odd != W % 2){
			printf("NO\n");
		}
		return 0;
	}
*/	int *is_used_tate = (int *)malloc(sizeof(int) * H);
	for(i = 0; i < H; i++){
		is_used_tate[i] = 0;
	}
	int *is_used_yoko = (int *)malloc(sizeof(int) * W);
	for(j = 0; j < W; j++){
		is_used_yoko[j] = 0;
	}
	int amari_tate = 0, amari_yoko = 0;
	for(i = 0; i < H; i++){
		if(is_used_tate[i] == 0){
			for(l = i + 1; l < H; l++){
				if(is_equal(tate[i], tate[l]) == 1){
					if(is_equal_t(S, i, l, H, W) == 1){
						printf("NO\n");
						return 0;
					}
					is_used_tate[i] = 1;
					is_used_tate[l] = 1;
					break;
				}
			}
			if(is_used_tate[i] == 0){
				amari_tate++;
			}
		}
	}
//	printf("yoko[0][0] = %d\n", yoko[0][0]);
//	printf("yoko[1][0] = %d\n", yoko[1][0]);
	for(j = 0; j < W; j++){
		if(is_used_yoko[j] == 0){
			for(l = j + 1; l < W; l++){
//				printf("is_equal = %d\n", is_equal(yoko[j], yoko[l]));
				if(is_equal(yoko[j], yoko[l]) == 1){
					if(is_equal_y(S, j, l, H, W) == 1){
						printf("NO\n");
						return 0;
					}
					is_used_yoko[j] = 1;
					is_used_yoko[l] = 1;
					break;
				}
			}
			if(is_used_yoko[j] == 0){
				amari_yoko++;
			}
		}
	}
//	printf("amari_tate = %d\n", amari_tate);
//	printf("amari_yoko = %d\n", amari_yoko);
	if(amari_tate <= 1 && amari_yoko <= 1){
		printf("YES\n");
	}
	else{
		printf("NO\n");
	}
	return 0;
}