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`.

Examples

Input

2 3
arc
rac


Output

YES


Input

3 7
atcoder
regular
contest


Output

NO


Input

12 12
bimonigaloaf
faurwlkbleht
dexwimqxzxbb
lxdgyoifcxid
ydxiliocfdgx
nfoabgilamoi
ibxbdqmzxxwe
pqirylfrcrnf
wtehfkllbura
yfrnpflcrirq
wvcclwgiubrk
lkbrwgwuiccv


Output

YES
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

#define ll long long
#define mp make_pair
#define pb push_back

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define rep(i, n) for (int i = 0; i < (int)(n); ++ i)

int n, m;
char s[15][15];
int cnt[15][26];
int mr[15], mc[15];

void prt() {
	// rep(i, n) printf("%d ", mr[i]);
	// puts("");
	// rep(i, m) printf("%d ", mc[i]);
	// puts("");
}

void c(int j, bool f = m & 1) {
	// printf("c(%d, %d)\n", j, f);
	if (j == m) prt(), exit(puts("YES") & 0);
	if (~mc[j]) return c(j + 1, f);
	if (f) {
		bool ok = 1;
		rep(i, n) ok &= s[mr[i]][j] == s[i][j];
		if (ok) mc[j] = j, c(j + 1, 0), mc[j] = -1;
	}
	rep(j0, m) if (j != j0 && !~mc[j0]) {
		bool ok = 1;
		rep(i, n) ok &= s[i][j] == s[mr[i]][j0];
		if (!ok) continue;
		mc[j] = j0; mc[j0] = j;
		c(j + 1, f);
		mc[j] = -1; mc[j0] = -1;
	}
}

void r(int i, bool f = n & 1) {
	// printf("r(%d, %d)\n", i, f);
	if (i == n) {memset(mc, -1, sizeof(mc)); return c(0);}
	if (~mr[i]) return r(i + 1, f);
	if (f) mr[i] = i, r(i + 1, 0), mr[i] = -1;
	rep(i0, n) if (i != i0 && !~mr[i0]) {
		bool ok = 1;
		rep(ch, 26) ok &= cnt[i][ch] == cnt[i0][ch];
		if (!ok) continue;
		mr[i] = i0; mr[i0] = i;
		r(i + 1, f);
		mr[i] = -1; mr[i0] = -1;
	}
}

int main() {
	scanf("%d %d", &n, &m);
	rep(i, n) scanf("%s", s[i]);
	rep(i, n) rep(j, m) cnt[i][s[i][j] - 'a'] ++;
	memset(mr, -1, sizeof(mr));
	r(0); puts("NO");
	return 0;
}
