#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>

using namespace std;

#ifdef __DEBUG__
    void debug_out() { cerr << endl; } 
    template <typename Head, typename... Tail>
    void debug_out(Head H, Tail... T) {cerr << " " << H; debug_out(T...);}
    #define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
    #define debug(...) 
#endif

inline void fast_io() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); };
template<typename T> inline ostream& operator<<(ostream& os, const vector<T>& v) { for (auto el : v) cout << el << " "; return os; }

vector<string> S;
int H, W;
inline void input(){
    fast_io();
    cin >> H >> W;
    for (int i = 0; i < H; i++)
    {
        string s; cin >> s;
        S.push_back(s);
    }
}

bool rev_same(string s, string t){
    if(s.length()!=t.length()) return false;
    for (int i = 0; i < (int)s.length(); i++)
    {
        if(s[i]!=t[s.length()-1-i]) return false;
    }
    return true;
}

bool is_column_ok(vector<string> T){
    vector<string> R;
    for (int j = 0; j < W; j++)
    {
        string r = "";
        for (int i = 0; i < H; i++)
        {
            r += T[i][j];
        }
        R.push_back(r);
    }

    vector<bool> used(W,false);    
    int center = (W % 2) ? 0 : 1;

    for (int j = 0; j < W; j++)
    {
        if(used[j]) continue;
        used[j] = true;
        bool pair = false;
        for (int k = 0; k < W; k++)
        {
            if(used[k]) continue;
            if(rev_same(R[j], R[k])){
                used[k] = true;
                pair = true;
                break;
            }
        }
        if(!pair){
            if(rev_same(R[j],R[j]) && center==0){
                center = 1;
            }
            else{
                return false;
            }
        }
    }
    return true;
}

bool is_pair_row(string s, string t){
    sort(s.begin(),s.end());
    sort(t.begin(),t.end());
    return (s == t);
}

bool is_same_cnt(string s, string t){
    map<char, int> cnt_s, cnt_t;
    for (int i = 0; i < (int)s.length(); i++) cnt_s[s[i]]++;
    for (int i = 0; i < (int)t.length(); i++) cnt_t[t[i]]++;
    return (cnt_s==cnt_t);    
}

bool is_row_center(string const& s){
    map<char, int> cnt_s;
    int w = W % 2 ? 0 : 1;
    for (int i = 0; i < (int)s.length(); i++) cnt_s[s[i]]++;
    for(auto [ch,cnt]:cnt_s){
        if(cnt % 2 && w) return false; 
        else if(cnt % 2) w = 1;
    }
    return true;
}

bool is_row_ok(vector<string> T){
    vector<bool> used(W,false);    
    int center = (H % 2) ? 0 : 1;

    for (int i = 0; i < H; i++)
    {
        if(used[i]) continue;
        used[i] = true;
        bool pair = false;
        for (int k = 0; k < H; k++)
        {
            if(used[k]) continue;
            if(is_same_cnt(T[i], T[k])){
                used[k] = true;
                pair = true;
                break;
            }
        }
        if(!pair){
            if(is_row_center(T[i]) && center==0){
                center = 1;
            }
            else{
                return false;
            }
        }
    }
    return true;
}


bool solve(){
    if(!is_row_ok(S)) return false;
    for (int bit = 1; bit < (1<<H); bit++)
    {
        if(__builtin_popcount(bit) != (H+1)/2) continue;
        vector<int> P,Q;
        for (int i = 0; i < H; i++)
        {
            if((bit>>i)&1) P.push_back(i);
            else Q.push_back(i);
        }
        do
        {
            vector<string> T = S;
            bool ispair = true;
            for (int i = 0; i < H/2; i++)
            {
                T[i] = S[P[i]];
                T[H-1-i] = S[Q[i]];
                if(!is_pair_row(T[i], T[H-1-i])){
                    ispair = false;
                    break;
                }
            }
            if(H % 2) {
                int mid = H/2;
                T[mid] = S[P[mid]];
                if(!is_row_center(T[mid])) ispair = false;
            }
            if(!ispair) continue;
            if(is_column_ok(T)) return true;
        } while (next_permutation(P.begin(),P.end()));
    }
    return false;
}   

int main()
{
    input();
    string ans = solve()?"YES":"NO";
    cout << ans << endl;
    return 0;
}


Measured memory_bytes: 3652