#include <bits/stdc++.h> 
using namespace std;

#define sz(x) (int)x.size() 
#define pb push_back 
#define mp make_pair 
#define fi(a, b) for(int i=a; i<=b; i++) 
#define fj(a, b) for(int j=a; j<=b; j++) 
#define fo(a, b) for(int o=a; o<=b; o++) 
#define fdi(a, b) for(int i=a; i>=b; i--) 
#define fdj(a, b) for(int j=a; j>=b; j--) 
#define fdo(a, b) for(int o=a; o>=b; o--) 

#ifdef LOCAL
#define err(...) fprintf(stderr, __VA_ARGS__)
#else
#define err(...) while(false) {}
#endif

typedef long long ll; 
typedef pair<int, int> pii; 
typedef pair<ll, ll> pll; 
typedef vector<int> vi; 
typedef vector<pii> vpii; 
typedef vector<pll> vpll; 
typedef long double ld;

/////////////////////////////////

int const MAX = 14;

char s[MAX][MAX];

int h, w;
int eh[MAX][MAX];
int ew[MAX][MAX];

int qa[241];
int qb[241];

void bad() {
	printf("NO\n");
	exit(0);
}

void ok() {
	printf("YES\n");
	exit(0);
}

void init() {
	fi(1, h) {
		fj(1, h) {
			if (i == j) continue;
			memset(qa, 0, sizeof(qa));
			memset(qb, 0, sizeof(qb));
			fo(1, w) {
				qa[(int)s[i][o]]++;
				qb[(int)s[j][o]]++;
			}
			eh[i][j] = 1;
			fo(0, 200) {
				if (qa[o] != qb[o]) eh[i][j] = 0;
			}
		}		
	}
	fi(1, w) {
		fj(1, w) {
			if (i == j) continue;
			memset(qa, 0, sizeof(qa));
			memset(qb, 0, sizeof(qb));
			fo(1, h) {
				qa[(int)s[o][i]]++;
				qb[(int)s[o][j]]++;
			}
			ew[i][j] = 1;
			fo(0, 200) {
				if (qa[o] != qb[o]) ew[i][j] = 0;
			}
		}		
	}
}

vpii st;
vector<vpii> a, b;

bool bit(int m, int i) {
	return (m & (1 << i));
}

void rech(int p, int mask) {
	if (p == h + 1) {
		a.pb(st);
		return;
	}
	if (bit(mask, p)) {  
		rech(p + 1, mask);
		return;
	}
	fi(p + 1, h) {
		if (bit(mask, i)) continue;
		if (i == p) continue;
		if (!eh[i][p]) continue;
		int mask1 = mask;
		mask1 ^= (1 << i);
		mask1 ^= (1 << p);
		st.pb(mp(p, i));
		rech(p + 1, mask1);
		st.pop_back();
	}
}

void recw(int p, int mask) {
	if (p == w + 1) {
		b.pb(st);
		return;
	}
	if (bit(mask, p)) {  
		recw(p + 1, mask);
		return;
	}
	fi(p + 1, w) {
		if (bit(mask, i)) continue;
		if (i == p) continue;
		if (!ew[i][p]) continue;
		int mask1 = mask;
		mask1 ^= (1 << i);
		mask1 ^= (1 << p);
		st.pb(mp(p, i));
		recw(p + 1, mask1);
		st.pop_back();
	}
}

bool check(vpii &hm, vpii &vm) {
	fi(0, sz(hm) - 1) {
		fj(0, sz(vm) - 1) {
			int h1 = hm[i].first;
			int h2 = hm[i].second;
			int v1 = vm[j].first;
			int v2 = vm[j].second;
			if (s[h1][v1] != s[h2][v2]) return false;
		}
	}
	return true;
}

void solve() {
	init();
	if (h % 2 == 0) {
		rech(1, 0);
	} else {
		fi(1, h) {
			st.pb(mp(i, i));
			rech(1, (1 << i));
			st.pop_back();
		}
	}
	if (w % 2 == 0) {
		recw(1, 0);
	} else {
		fi(1, w) {
			st.pb(mp(i, i));
			recw(1, (1 << i));
			st.pop_back();
		}
	}
	/*
	err("a : \n");
	for (vpii z : a) {
		for (pii x : z) {
			err("%d-%d ", x.first, x.second);
		}	
		err("\n");
	}
	err("b : \n");
	for (vpii z : b) {
		for (pii x : z) {
			err("%d-%d ", x.first, x.second);
		}	
		err("\n");
	}
	*/
	random_shuffle(a.begin(), a.end());
	random_shuffle(b.begin(), b.end());
	fi(0, sz(a) - 1) {
		fj(0, sz(b) - 1) {
			if (check(a[i], b[j])) {
				ok();
			}
		}
	}
	bad();
}

int main() {
	srand(time(0) + clock() + 41);
#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

  scanf("%d %d", &h, &w);
	fi(1, h) {
		scanf(" %s", s[i] + 1);
	}
	solve();		

	
#ifdef LOCAL
	err("ELAPSED TIME: %.3Lf\n", (ld) clock() / CLOCKS_PER_SEC);
#endif	
	
	return 0;
}

Measured memory_bytes: 2108