/*
                                                                           __                _________
                                                                          /  \              /  ______/
                                                                         /    \            /  /
                                                                        /  __  \          /  /
                                                                       /  /  \  \         |  |
                                                                      /  /____\  \        \  \
                                                                     /  ________  \        \  \______
                                                                    /__/        \__\        \________\
	
	I_love_Hacked;
	I_hate_pretest past;
	
    coder:xxjAc
    date:2018/4/18 
	    
    I_love_Ac;
    I_hate_WA;
    I_hate_Tle;
    I_hate_RE;
    I_hate_CE;
    I_hate_Mle;
    
    I love Accepts very much;
    
    set
    map
    stack
    queue
    deque
    priority_queue
    vecotr
    
    cd Deskpop
    g++ xxjAc.cpp -o std
    ./std
    
    #prag\
    ma GCC optmize("Ofast")
    (O2,O3,Ofast)

    07MQ7VBY
*/
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#define ll long long
using namespace std;
const int inf=1000000007;
int l[17],c[17],now[17];
string s[17],ps[17];
int h,w;
bool ans=false;
void fz(string &s1){
	string t="";
	for (int i=s1.size()-1;i>=0;i--){
		t+=s1[i];
	}
	s1=t;
}
void check(){
	int c1=0;
	memset(c,-1,sizeof(c));
	for (int i=0;i<h;i++){
		if (c[i]==-1){
			if (l[i]==i){
				now[h/2]=i;
				c[i]=1;
			}
			else{
				now[c1]=i;
				now[h-c1-1]=l[i];
				c[i]=1;
				c[l[i]]=1;
				c1++;
			}
		}
	}
	//cout<<1<<endl;
	map<string,int> cnt;
	string s1,t;
	for (int i=0;i<w;i++){
		s1="";
		//cout<<1<<endl;
		for (int j=0;j<h;j++){
			//cout<<now[j]<<endl;
			s1+=s[now[j]][i];
		}
		//cout<<1<<endl;
		t=s1;
		fz(t);
		cnt[min(s1,t)]++;
	}
	bool f=w%2;
	for (map<string,int>::iterator it=cnt.begin();it!=cnt.end();it++){
		if ((*it).second%2==0){
			continue;
		}
		string s1=(*it).first;
		string t=s1;
		fz(t);
		if (t!=s1){
			return;
		}
		if (!f){
			return;
		}
		f=false;
	}
	ans=true;
	cout<<"YES"<<endl;
}
void dfs(int k,bool f){
	//cout<<k<<endl;
	if (k==h){
		/*
		for (int i=0;i<h;i++){
			cout<<l[i]<<endl;
		}
		*/
	//	cout<<endl;
		check();
		return;
	}
	if (l[k]!=-1){
		dfs(k+1,f);
		return;
	}
	for (int i=k+1;i<h;i++){
		if (l[i]!=-1){
			continue;
		}
		if (ps[k]!=ps[i]){
			continue;
		}
		l[i]=k;
		l[k]=i;
		dfs(k+1,f);
		if (ans){
			return;
		}
		l[i]=-1;
		l[k]=-1;
	}
	if (f==true){
		l[k]=k;
		dfs(k+1,false);
		if (ans){
			return;
		}
		l[k]=-1;
	}
}
int main(){
	memset(l,-1,sizeof(l));
	cin>>h>>w;
	for (int i=0;i<h;i++){
		cin>>s[i];
		ps[i]=s[i];
		sort(ps[i].begin(),ps[i].end());
		//cout<<ps[i]<<endl;
	}
	dfs(0,h%2);
	if (!ans){
		cout<<"NO"<<endl;
	}
	return 0;
}

Measured memory_bytes: 256