#include<bits/stdc++.h>
using namespace std;
#define SZ(v) ((int)(v).size())
#define zero(v) memset(v,0,sizeof(v))
#define rep(i,n) for(int i=0;i<(n);i++)
#define foreach(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();it++)
#define all(v) (v).begin(),(v).end()
template<typename T>inline bool chkmin(T &a,const T &b){return a>b?a=b,1:0;}
template<typename T>inline bool chkmax(T &a,const T &b){return a<b?a=b,1:0;}
typedef long long ll;
typedef unsigned uint;
const int INF=0x3f3f3f3f;
const double EPS=1e-10;
typedef pair<int,int> pii;
int inline in(){int x=0,c;for(;(uint)((c=getchar())-'0')>=10;)
{if(c=='-')return -in();if(!~c)throw ~0;}do{x=(x<<3)+(x<<1)+(c-'0');}
while((uint)((c=getchar())-'0')<10);return x;}

void nope(int num){
//	cerr<<num<<endl;
	cout<<"NO"<<endl;
	exit(0);
}

int n,m;
const int Maxn=15;

string s[Maxn];

pair<string,string> vec[Maxn];int kvec;

bool used[Maxn],vis[Maxn];

int mp[Maxn];

inline bool check(const string &s1,const string &s2){
	memset(vis,0,sizeof(vis));
	for(int i=0;i<m;i++){
		if(vis[i])continue;
		for(int j=i+1;j<m;j++){
			if((!vis[i])&&(!vis[j])&&s1[i]==s2[j]&&s1[j]==s2[i]){
				vis[i]=true;
				vis[j]=true;
				break;
			}
		}
	}
	
	int cnt=0;
	for(int i=0;i<m;i++){
		if(!vis[i])cnt++;
	}
	
	if(m%2==0){
		if(cnt>0)return false;
		return true;
	}
	
	if(cnt!=1)return false;
	for(int i=0;i<m;i++){
		if(!vis[i]){
			if(s1[i]==s2[i]){
				return true;
			}else{
				return false;
			}
		}
	}
	return false;
}


void match(){
	memset(used,0,sizeof(used));
	
	for(int i=0;i<n;i++){
		if(used[i])continue;
		for(int j=i+1;j<n;j++){
			if((!used[i])&&(!used[j])&&check(s[i],s[j])){
				used[i]=true;
				used[j]=true;
				vec[kvec++]=make_pair(s[i],s[j]);
				break;
			}
		}
	}
	
	int cnt=0;
	for(int i=0;i<n;i++){
		if(!used[i]){
			cnt++;
//			cerr<<s[i]<<endl;
		}
	}
//	cerr<<"cnt:"<<cnt<<endl;
	if(n%2==0){
		if(cnt>0)nope(3);
		return;
	}
	if(cnt!=1)nope(4);
	for(int i=0;i<n;i++){
		if(!used[i]){
			if(check(s[i],s[i])){
				vec[kvec++]=make_pair(s[i],s[i]);
				return;
			}else nope(5);
		}
	}
}

bool ok=false;
void calc(){
//	cerr<<"mp:";for(int i=0;i<m;i++)cerr<<mp[i]<<' ';cerr<<endl;
	bool flag=true;
	for(int i=0;i<kvec;i++){
		string s1=vec[i].first;
		string s2=vec[i].second;
		for(int j=0;j<m;j++){
			if(s1[j]==s2[mp[j]]&&s1[mp[j]]==s2[j]);
			else {
				flag=false;
				break;
			}
		}
	}
	if(flag){
		ok=true;
	}
}

bool dfs(int i,const string &s1,const string &s2){
	if(i==m){
		calc();
		if(ok)return true;
		return false;
	}
	if(mp[i]!=-1){
		if(dfs(i+1,s1,s2))return true;
		return false;
	}
	for(int j=i+1;j<m;j++){
		if(mp[i]==-1&&mp[j]==-1&&s1[i]==s2[j]&&s1[j]==s2[i]){
			mp[i]=j;
			mp[j]=i;
			if(dfs(i+1,s1,s2))return true;
			mp[i]=0;
			mp[j]=0;
		}
	}
	return false;
}


void solve(const string &s1,const string &s2){
	memset(mp,-1,sizeof(mp));
	if(m%2==1){
		int ppp=-1;
		memset(vis,0,sizeof(vis));
		for(int i=0;i<m;i++){
			if(vis[i])continue;
			for(int j=i+1;j<m;j++){
				if((!vis[i])&&(!vis[j])&&s1[i]==s2[j]&&s1[j]==s2[i]){
					vis[i]=true;
					vis[j]=true;
					break;
				}
			}
		}
		for(int i=0;i<m;i++){
			if(!vis[i]){
				ppp=i;
				break;
			}
		}
		mp[ppp]=ppp;
	}
	
	
//	cerr<<s1<<' '<<s2<<endl;
	if(dfs(0,s1,s2))cout<<"YES"<<endl;
	else cout<<"NO"<<endl;
}

int main(){
	n=in();m=in();
	for(int i=0;i<n;i++)cin>>s[i];
	
	match();
//	for(int i=0;i<kvec;i++){
//		cerr<<vec[i].first<<' '<<vec[i].second<<endl;
//	}
//	cerr<<endl;
	solve(vec[0].first,vec[0].second);
	return 0;
}

Measured memory_bytes: 3648