#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxN = 15; 
int siz[1 << maxN], N, M, tot, b[(1 << 13)][15];
pair<int, int> a[maxN];
bool vis[maxN], dp[1 << 13], bad[maxN];
char s[maxN][maxN];
int tt;
inline bool check(int cnt) {
	//tt = 0;
	//cout<<cnt<<endl;
	//cout << cnt << ' ' <<a[1].first <<' ' <<a[1].second<<endl; 
	int t = 0;
	if(N & 1) for(int i = 1; i <= N; ++i) if(!vis[i]) t = i;
	//cout<<t<<endl;
	for(int i = 0; i < (1 << M); ++i) dp[i] = 0;	
	dp[0] = 1;
	for(int i = 1; i < (1 << M); ++i) {
		//tt++;
		//cout << i <<' '<<siz[i]<<endl; 
		if((siz[i] & 1) && (siz[i] != M)) continue;
		//cout << i << endl;
		if(siz[i] & 1) {
			for(int k_ = 1; k_ <= b[i][0]; ++k_) {
				int k = b[i][k_];
				int mask = i ^ (1 << (k - 1));
				if(dp[mask] == 0) continue;
				bool tag = 1;
				for(int j = 1; j <= cnt; ++j) {
					int t1 =  a[j].first, t2 = a[j].second;
					if(s[t1][k] != s[t2][k]) {
						tag = 0; break;
					}
				}
				if(tag) dp[i] = 1;
			}
		} else {
			for(int k1_ = 1; k1_ <= b[i][0]; ++k1_) {
				for(int k2_ = k1_ + 1; k2_ <= b[i][0]; ++k2_) {
					int k1 = b[i][k1_], k2 = b[i][k2_];
					int mask = i ^ (1 << (k2 - 1));
					mask ^= ((1 << (k1 - 1)));
					if(dp[mask] == 0) continue;
					bool tag = 1;
					for(int j = 1; j <= cnt; ++j) {
						int t1 = a[j].first, t2 = a[j].second;
						if(s[t1][k1] != s[t2][k2] || s[t1][k2] != s[t2][k1]) {
							tag = 0; break;
						}
					}
					if(t > 0 && s[t][k1] != s[t][k2]) tag = 0;
					if(tag) dp[i] = 1;
				}
			}
		}
		//cout<<i<<' '<<dp[i]<<"***"<<endl;
	}
	//cout<<dp[(1<<M)-1]<<endl;
	return dp[(1 << M) - 1];
}
bool dfs2(int k, int cnt) { 
	//cout <<bad[k]<<"***"<<endl; 
	if(cnt > N / 2) return check(cnt - 1); 
	if(vis[k] || 0) {
		//cout<<vis[k]<<' '<<bad[k]<<' '<<k<<endl;
		return dfs2(k + 1, cnt);
	}
	vis[k] = 1; a[cnt].first = k;
	for(int i = k + 1; i <= N; ++i) {
		if(vis[i]) continue;
		vis[i] = 1; a[cnt].second = i;
		if(dfs2(k + 1, cnt + 1)) return true;
		vis[i] = 0;
	}
	vis[k] = 0;
	return false;
}
bool dfs1(int k, int cnt) { 
	//cout <<bad[k]<<"***"<<endl; 
	if(cnt > N / 2) return check(cnt - 1); 
	if(vis[k] || bad[k]) {
		//cout<<vis[k]<<' '<<bad[k]<<' '<<k<<endl;
		return dfs1(k + 1, cnt);
	}
	vis[k] = 1; a[cnt].first = k;
	for(int i = k + 1; i <= N; ++i) {
		if(vis[i] || bad[i]) continue;
		vis[i] = 1; a[cnt].second = i;
		if(dfs1(k + 1, cnt + 1)) return true;
		vis[i] = 0;
	}
	vis[k] = 0;
	return false;
}

int main() {
	scanf("%d%d", &N, &M);
	for(int i = 0; i < (1 << M); ++i) {
		//cout<<i<<endl;
		for(int j = 1; j <= M; ++j) {
			if(i & (1 << (j - 1))) b[i][++b[i][0]] = j;
		}
		//cout<<endl;
		//cout<<i<<' '<<b[i][0]<<endl;
	}
	for(int i = 1; i < (1 << M); ++i) siz[i] = siz[i >> 1] + (i & 1);
	for(int i = 1; i <= N; ++i) scanf("%s", s[i] + 1);
	if(N % 2 == 0){
		for(int i = 1; i <= N; ++i) bad[i] = 0;
		//cout<<"****"<<endl;
		if(dfs2(1, 1)) printf("YES\n");
		else printf("NO\n");
	} else {
		bool ok = 0;
		for(int i = 1; i <= N; ++i) {
			bad[i] = 1;
			if(dfs1(1, 1)) {
				ok = 1; break;
			}
			bad[i] = 0;
		}
		if(ok) printf("YES\n");
		else printf("NO\n");
	}
	//cout<<tot*tt*12*12<<endl;
	return 0;
}

Measured memory_bytes: 512