#include <iostream>
    #include <string>
    #include <set>  
    #include <algorithm>
    #include <vector>
    #include <cmath>
    #include <queue>
    #include <deque>
    #include <cstring>
    #include <cstdio>
    #include <map>
    #include <numeric>
    #include <cassert>
    #include <iomanip>
    #include <sstream>
using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(int)(b);++i)
#define REP(i,N) FOR(i,0,N)
#define FORD(i,b,a) for(int i=(int)(b)-1;i>=a;--i)
typedef long long LL;
typedef pair<int,int> PII;
#define st first
#define nd second
#define pb push_back
#define eb emplace_back
#define dprintf(...) printf(__VA_ARGS__)
string S[15];
int n,m,sme[2][15],par[2][15];
string a[15],b[15];
vector<int> ans[2][15];
void defi()
{
	for(int i=0;i<n;i++)
	{
		a[i]=S[i];
		sort(a[i].begin(),a[i].end());
		for(int j=0;j<m;j++)
			b[j].push_back(S[i][j]);
	}
	for(int j=0;j<m;j++)
		sort(b[j].begin(),b[j].end());
}
bool chk(int y,int yy)
{
//	cout<<y<<" "<<yy<<endl;
	for(int i=0;i<n;i++)
	{
	//	cout<<i<<" "<<par[0][i]<<endl;
		if(S[i][y]!=S[par[0][i]][yy]||S[par[0][i]][y]!=S[i][yy])
		{
			return false;
		}
	}
}
void chekrow(int y,bool used)
{
//	cout<<y<<" "<<used<<endl;
	if(y==m&&!used)
	{
		cout<<"YES"<<endl;
		exit(0);
	}
	if(par[1][y]!=-1)
	{
		chekrow(y+1,used);
		return;
	}
//	cout<<y<<" "<<used<<endl;
	for(int i=0;i<ans[1][sme[1][y]].size();i++)
	{
	//	cout<<y<<" "<<used<<" "<<ans[1][sme[1][y]][i]<<endl;
		if(ans[1][sme[1][y]][i]==y&&used)
		{
			par[1][y]=ans[1][sme[1][y]][i];
			par[1][ans[1][sme[1][y]][i]]=y;
	//		cout<<y<<" "<<used<<" "<<ans[1][sme[1][y]][i]<<endl;
			if(chk(y,ans[1][sme[1][y]][i]))chekrow(y+1,!used);
	//		cout<<y<<" "<<used<<" "<<ans[1][sme[1][y]][i]<<endl;
			
			par[1][y]=-1;
			par[1][ans[1][sme[1][y]][i]]=-1;
		}
		if(ans[1][sme[1][y]][i]==y||par[1][ans[1][sme[1][y]][i]]!=-1)continue;
	//	cout<<y<<" "<<used<<" "<<ans[1][sme[1][y]][i]<<endl;
		par[1][y]=ans[1][sme[1][y]][i];
		par[1][ans[1][sme[1][y]][i]]=y;
		if(chk(y,ans[1][sme[1][y]][i]))chekrow(y+1,used);
		par[1][y]=-1;
		par[1][ans[1][sme[1][y]][i]]=-1;
	}
	
}
void getlie(int x,bool used)
{
//	cout<<"begin: "<<x<<" "<<used<<endl;
	if(x==n&&!used)
	{
//		for(int i=0;i<n;i++)
//			cout<<par[0][i]<<" ";
//		cout<<endl;
//		system("pause");
		chekrow(0,m%2);
		return;
	}
	if(par[0][x]!=-1)
	{
		getlie(x+1,used);
		return;
	}
//	cout<<"bbbegin: "<<x<<" "<<used<<endl;
	for(int i=0;i<ans[0][sme[0][x]].size();i++)
	{
//		cout<<"     "<<x<<" "<<used<<" "<<ans[0][sme[0][x]][i]<<endl;
	//	system("pause");
		if(ans[0][sme[0][x]][i]==x&&used)
		{
			par[0][x]=ans[0][sme[0][x]][i];
			par[0][ans[0][sme[0][x]][i]]=x;
			getlie(x+1,!used);
			par[0][x]=-1;
			par[0][ans[0][sme[0][x]][i]]=-1;
		}
		if(ans[0][sme[0][x]][i]==x||par[0][ans[0][sme[0][x]][i]]!=-1)continue;
	//	cout<<"inside"<<" "<<x<<" "<<used<<" "<<ans[0][sme[0][x]][i]<<endl;
		par[0][x]=ans[0][sme[0][x]][i];
		par[0][ans[0][sme[0][x]][i]]=x;
		getlie(x+1,used);
		par[0][x]=-1;
		par[0][ans[0][sme[0][x]][i]]=-1;
	}
}
void finds()
{
	memset(sme,0,sizeof(sme));
	int col=0;
	for(int i=0;i<n;i++)
	{
		if(sme[0][i])continue;
		sme[0][i]=++col;
		ans[0][col].push_back(i);
		for(int j=i+1;j<n;j++)
			if(a[i]==a[j])
			{
				sme[0][j]=col;
				ans[0][col].push_back(j);
			}
	}
	col=0;
	for(int i=0;i<m;i++)
	{
		if(sme[1][i])continue;
		sme[1][i]=++col;
		ans[1][col].push_back(i);
		for(int j=i+1;j<m;j++)
			if(b[i]==b[j])
			{
				sme[1][j]=col;
				ans[1][col].push_back(j);
			}
	}
}
/*void cal(int x,int y,int inc,int inr)
{
	int fa=sme[x][y];
	int num=x*m+y;
	for(int i=0;i<ans[fa].size();i++)
	{
		int ii=ans[fa][i]/m,jj=ans[fa][i]-ii*m;
		if(ii==x||jj==y)continue;
	}
}*/
int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++)
		cin>>S[i];
	defi();
	finds();
	memset(par,-1,sizeof(par));
	getlie(0,n%2);
//	cout<<1<<endl;
	cout<<"NO"<<endl;
	return 0;
}

Measured memory_bytes: 256