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 <bits/stdc++.h>
using namespace std;
#define LL long long
char a[20][20];
int n, m;
bool Ans;
multiset<LL> S;
inline bool check() {
	S.clear();
	for(int j = 1; j <= m; ++ j) {
		LL t = 0;
		for(int i = n; i >= 1; -- i) {
			t = t * 26 + a[i][j] - 'a';
		}
		if(S.find(t) != S.end()) {
			S.erase(S.find(t));
		}
		else {
			t = 0;
			for(int i = 1; i <= n; ++ i) {
				t = t * 26 + a[i][j] - 'a';
			}
			S.insert(t);
		}
	}
	if(m & 1) {
		if(S.size() == 1) {
			LL wt = (*S.begin());
			static int x[20];
			for(int i = 1; i <= n; ++ i) {
				x[i] = wt % 26; wt /= 26;
			}
			for(int i = 1; i <= n / 2; ++ i) {
				if(x[i] != x[n - i + 1]) return false;
			}
			return true;
		}
		return false;
	}
	else {
		if(S.size() == 0) return true;
		return false;
	}
}
inline void dfs(int x) {
	if(x == n / 2 + 1) {
		if(check()) Ans = true;
		return;
	}
	for(int i = x + 1; i <= n - x + 1; ++ i) {
		for(int j = 1; j <= m; ++ j) {
			swap(a[i][j], a[n - x + 1][j]);
		}
		dfs(x + 1);
		for(int j = 1; j <= m; ++ j) {
			swap(a[i][j], a[n - x + 1][j]);
		}
	}
}
int main() {
	//freopen("a.in", "r", stdin);
	n, m;
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++ i) {
		scanf("%s", a[i] + 1);
	}
	if(n & 1) {
		for(int i = 1; i <= n; ++ i) {
			for(int j = 1; j <= m; ++ j) {
				swap(a[i][j], a[n / 2 + 1][j]);
			}
			dfs(1);
			for(int j = 1; j <= m; ++ j) {
				swap(a[i][j], a[n / 2 + 1][j]);
			}
		}
	}
	else dfs(1);
	if(Ans) puts("YES");
	else puts("NO");
}