#include <iostream>
#include <algorithm>
#include <bitset>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <cstring>
#include <utility>
#include <vector>
#include <complex>
#include <valarray>
#include <fstream>
#include <cassert>
#include <cmath>
#include <functional>
#include <iomanip>
#include <numeric>
#include <climits>
#include <random>

#define _overload(a, b, c, d, ...) d
#define _rep1(X, A, Y) for (int (X) = (A);(X) <= (Y);++(X))
#define _rep2(X, Y) for (int (X) = 0;(X) < (Y);++(X))
#define rep(...) _overload(__VA_ARGS__, _rep1, _rep2)(__VA_ARGS__)
#define rrep(X,Y) for (int (X) = Y-1;(X) >= 0;--(X))
#define all(X) (X).begin(),(X).end()
#define len(X) ((int)(X).size())
#define mod(n, m) (((n)%(m)+(m))%m)
#define fi first
#define sc second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> Pii;
typedef pair<ll,ll> Pll;
const int INFINT = 1 << 30;                          // 1.07x10^ 9
const ll INFLL = 1LL << 60;                          // 1.15x10^18
const double EPS = 1e-10;
const int MOD = 1000000007;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

const int MAX_H = 12, MAX_W = 12;
int H, W;
string matrix[MAX_H];

bool isPairable[MAX_H][MAX_H];

int rPair[MAX_H];
int cPair[MAX_W];

bool judge() {
    for (int i = 0; i < H; ++i) {
        int r1 = i, r2 = rPair[i];
        for (int j = 0; j < W; ++j) {
            int c1 = j, c2 = cPair[j];
            if (matrix[r1][c1] != matrix[r2][c2]) {
                return false;
            }
        }
    }
    return true;
}
bool rec2(int r1, int r2, int c, int pairCount) {
    while (c < W && cPair[c] != -1) ++c;

    if (c == W) {
        return judge();
    }

    for (int i = c+1; i < W; ++i) {
        if (cPair[i] == -1 && matrix[r1][c] == matrix[r2][i]) {
            cPair[c] = i;
            cPair[i] = c;
            pairCount += 2;
            if (rec2(r1, r2, c+1, pairCount)) return true;
            cPair[c] = -1;
            cPair[i] = -1;
            pairCount -= 2;
        }
    }

    if (W%2 == 1 && pairCount%2 == 0) {
        cPair[c] = c;
        pairCount += 1;
        if (rec2(r1, r2, c+1, pairCount)) return true;
        cPair[c] = -1;
        pairCount -= -1;
    }

    return false;
}

bool rec1(int r, int& pairCount) {
    while (r < H && rPair[r] != -1) ++r;

    if (r == H) {
        int _pc = 0;
        return rec2(0, rPair[0], 0, _pc);
    }

    for (int i = r+1; i < H; ++i) {
        if (isPairable[r][i] && rPair[i] == -1) {
            rPair[i] = r;
            rPair[r] = i;
            pairCount += 2;
            if (rec1(r+1, pairCount)) return true;
            rPair[i] = -1;
            rPair[r] = -1;
            pairCount -= 2;
        }
    }

    if (H%2 == 1 && pairCount%2 == 0) {
        rPair[r] = r;
        pairCount += 1;
        if (rec1(r+1, pairCount)) return true;
        rPair[r] = -1;
        pairCount -= 1;
    }

    return false;
}


int main() {
  std::ios::sync_with_stdio(false);std::cin.tie(0);

  cin >> H >> W;
  rep(i, H) cin >> matrix[i];

  for (int i = 0; i < H; ++i) {
      for (int j = i+1; j < H; ++j) {
          string str1 = matrix[i];
          string str2 = matrix[j];
          sort(all(str1));
          sort(all(str2));
          if (str1 == str2) {
              isPairable[i][j] = true;
          }
      }
  }

  memset(rPair, -1, sizeof(rPair));
  memset(cPair, -1, sizeof(cPair));

  int _pc = 0;
  if (rec1(0, _pc)) {
      cout << "YES" << endl;
  } else {
      cout << "NO" << endl;
  }

  return 0;
}


Measured memory_bytes: 256