#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <cstring>
#include <ctime>
#include <map>
#include <algorithm>
#include <cmath>
#define MAXN 200005
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ba 823
#define ha 99994711
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
int H,W,St;
int Row[14][26],Col[14][26];
int matR[14][14],matC[14][14],idC[14],idR[14],mat[14];
bool vis[14],used[14];
char S[14][14];
void swapRow(int x,int y) {
	if(x == y) return;
	swap(idR[x],idR[y]);
	for(int i = 1 ; i <= W ; ++i) swap(S[x][i],S[y][i]);
}
void swapCol(int x,int y) {
	if(x == y) return;
	swap(idC[x],idC[y]);
	for(int i = 1 ; i <= H ; ++i) swap(S[i][x],S[i][y]);
}
bool match(int c) {
	if(c == 0) {
		memset(mat,0,sizeof(mat));
		int cnt = 0;
		for(int i = 2 ; i <= H - 1; ++i) {
			if(mat[i]) continue;
			for(int j = i + 1 ; j <= H - 1; ++j) {
				if(mat[j]) continue;
				bool f = 1;
				for(int k = 1 ; k <= W ; ++k) {
					if(S[i][k] != S[j][W - k + 1]) {
						f = 0;
						break;
					}
				}
				if(f) {mat[i] = j;mat[j] = i;break;}
			}
			if(!mat[i] && cnt < 1 && (H & 1)) {
				++cnt;
				for(int k = 1 ; k <= W ; ++k) {
					if(S[i][k] != S[i][W - k + 1]) return 0;
				}
				mat[i] = i;
			}
			else if(!mat[i]) return 0;
		}
		return 1;
	}
	if(c == W - c + 1) {
		for(int i = 1 ; i <= W ; ++i) {
			if(vis[i]) continue;
			if(S[1][i] == S[H][i]) {
				swapCol(i,c);
				vis[c] = 1;
				if(match(c - 1)) return 1;
				vis[c] = 0;
				swapCol(i,c);
			}
		}
	}
	else {
		for(int i = 1; i <= W; ++i) {
			if(vis[i]) continue;
			if(matC[idC[c]][idC[i]]) {
				if(S[1][c] == S[H][i] && S[1][i] == S[H][c]) {
					vis[c] = vis[W - c + 1] = 1;
					swapCol(i,W - c + 1);
					if(match(c - 1)) return 1;
					swapCol(i,W - c + 1);
					vis[c] = vis[W - c + 1] = 0;
				}
			}
		}
	}
	return 0;
}
bool check() {
	for(int i = 2 ; i <= H ; ++i) {
		if(matR[idR[1]][idR[i]]) {
			if(used[idR[i]]) continue;
			swapRow(i,H);
			if(match((W & 1) ? W / 2 + 1 : W / 2)) return 1;
			swapRow(i,H);
		}
	}
	return 0;
}
void Solve() {
	scanf("%d%d",&H,&W);
	for(int i = 1 ; i <= H ; ++i) scanf("%s",S[i] + 1);
	for(int i = 1 ; i <= H ; ++i) {
		for(int j = 1 ; j <= W ; ++j) {
			Row[i][S[i][j] - 'a']++;
		}
	}
	for(int j = 1 ; j <= W ; ++j) {
		for(int i = 1 ; i <= H ; ++i) {
			Col[j][S[i][j] - 'a']++;
		}
	}
	if(H == 1) {
		int cnt = 0;
		for(int i = 0 ; i <= 25 ; ++i) {
			if(Row[1][i] & 1) ++cnt;
		}
		if(cnt > 1) puts("NO");
		else puts("YES");
		return;
	}
	else if(W == 1) {
		int cnt = 0;
		for(int i = 0 ; i <= 25 ; ++i) {
			if(Col[1][i] & 1) ++cnt;
		}
		if(cnt > 1) puts("NO");
		else puts("YES");
		return;
	}
	for(int i = 1 ; i <= H ; ++i) {
		for(int j = i ; j <= H ; ++j) {
			bool f = 1;
			for(int k = 0 ; k <= 25 ; ++k) {
				if(Row[i][k] != Row[j][k]) {f = 0;break;}
			}
			matR[i][j] = matR[j][i] = f;
			
		}
	}
	for(int i = 1 ; i <= W ; ++i) {
		for(int j = i ; j <= W ; ++j) {
			bool f = 1;
			for(int k = 0 ; k <= 25 ; ++k) {
				if(Col[i][k] != Col[j][k]) {f = 0;break;}
			}
			matC[i][j] = matC[j][i] = f;
		}
	}
	for(int i = 1 ; i <= H ; ++i) idR[i] = i;
	for(int i = 1 ; i <= W ; ++i) idC[i] = i;
	for(int i = 1 ; i <= H ; ++i) {
		used[i] = 1;
		swapRow(i,1);
		if(check()) {puts("YES");return;}
		swapRow(i,1);
	}
	
	puts("NO");
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

Measured memory_bytes: 256