#pragma GCC optimize("O3")
#include <stdio.h>
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <deque>
#include <set>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <chrono>
#include <random>
#include <time.h>
#include <fstream>
#define ll long long
#define rep2(i,a,b) for(ll i=a;i<=b;++i)
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep3(i,a,b) for(ll i=a;i>=b;i--)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pq priority_queue<int>
#define pb push_back
#define eb emplace_back
#define vec vector<int>
#define vecll vector<ll>
#define vecpii vector<pii>
#define vec2 vector<vec>
#define vecll2 vector<vecll>
#define vec3 vector<vec2d>
#define vecll3 vector<vecll2d>
#define fi first
#define se second
#define endl "\n"
#define all(c) begin(c),end(c)
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
int in() {int x;cin>>x;return x;}
ll lin() {ll x;cin>>x;return x;}
template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
template<class T> inline void print(vector<T> v){for(T e:v)cout<<e<<" ";cout<<endl;}
template<class T> inline void print(pair<T,T> p){cout<<"("<<p.first<<","<<p.second<<") ";}
template<class T> inline void print(vector<pair<T,T>> v){for(auto e:v)print(e); cout<<endl;}
void print(vector<vec> v){for(auto e:v){for(auto ee:e)cout<<ee<<" ";cout<<endl;}}
void print(map<int,int> mp){for(auto e:mp)cout<<e.first<<" "<<e.second<<endl;cout<<endl;}

main(){
    ios
    int h=in(),w=in();
    vector<string> s;
    rep(i,h){
        string t;cin>>t;
        s.pb(t);
    }
    vec id;
    rep(i,(h+1)/2){
        id.pb(i);
    }
    while(1){
        vec now=id;
        vector<string> a;
        vec used_(h);
        rep(i,(h+1)/2){
            a.pb(s[now[i]]);used_[now[i]]=1;
        }
        rep(i,h)if(!used_[i])a.pb(s[i]);
        vec cnt(26);
        rep(i,(h+1)/2)rep(j,w)cnt[a[i][j]-'a']++;
        rep2(i,(h+1)/2,h-1)rep(j,w)cnt[a[i][j]-'a']--;
        bool ff=1;
        rep(i,26)if(cnt[i]!=0)ff=0;
        if((h&1) && !ff)
        rep(i,(h+1)/2){
            vec tcnt=cnt;
            rep(j,w)tcnt[a[i][j]-'a']--;
            bool fff=1;
            rep(j,26)if(tcnt[j]!=0)fff=0;
            if(fff){ff=1;break;}
        }
        if(ff)
        do{
            vector<string> c;
            vec used(h);
            rep(i,(h+1)/2){
                c.pb(s[now[i]]);
                used[now[i]]=1;
            }
            rep(i,h){
                if(!used[i])c.pb(s[i]);
            }
            map<string,int> mp,tai;
            rep(i,w){
                string res;
                rep(j,h){
                    res.pb(c[j][i]);
                }
                string rres=res;
                reverse(all(rres));
                if(rres==res){
                    tai[res]++;
                }
                else
                mp[res]++;
            }
            bool flag=1;
            rep(i,w){
                string res;
                rep(j,h){
                    res.pb(c[j][i]);
                }
                string rres=res;
                reverse(all(res));
                if(rres!=res){
                    if(mp[res]==0){
                        flag=0;break;
                    }
                    else mp[res]--;
                }
            }
            if(!flag){
                continue;
            }
            bool f=0;
            if(w&1)f=1;
            for(auto e:tai){
                if(e.second&1){
                    if(f)f=0;
                    else{
                        flag=0;break;
                    }
                }
            }
            if(flag){
                cout<<"YES\n";return 0;
            }
        }while(next_permutation(all(now)));
        int t=1;
        while(t <= (h+1)/2 && id[(h+1)/2-t]==h-t)t++;
        if(t==(h+1)/2 + 1) break;
        id[(h+1)/2-t]++;
        rep2(i,(h+1)/2-t+1,(h+1)/2-1){
            id[i]=id[i-1]+1;
        }
    }
    cout<<"NO\n";
}


Measured memory_bytes: 384