#ifdef DBG1
//  #define LOCAL
#endif

#ifdef LOCAL
  #define _GLIBCXX_DEBUG
#endif

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <set>

#ifdef DBG12
    #define dbg(...) fprintf(stderr, __VA_ARGS__)
#else
    #define dbg(...)
#endif

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;

char s[20][20];

const int P = int(1e9) + 7;

vector<pair<ll, vector<int>>> gen(int n, int m, int mid, int mask, int num) {
  vector <int> perm;
  for (int i = 0; i < n; ++i) {
    if (i == mid) { continue; }
    if (((mask >> i) & 1) != num) {
      perm.push_back(i);
    }
  }
  int k = int(perm.size());
  if (mid != -1) {
    perm.push_back(mid);
  }

  vector <pair<ll, vector<int>>> res;
  do {
    vector <int> cur(m, 0);
    for (int i = 0; i < m; ++i) {
      int curX = 0;
      for (int x : perm) {
        curX <<= 5;
        curX += (s[x][i] - 'a');
      }
      cur[i] = curX;
    }
    dbg("mid %d mask %d num %d perm = ", mid, mask, num);
    for (int x : perm) {
      dbg(" %d", x);
    }
    dbg(" res ");
    for (int x : cur) {
      dbg(" %d", x);
    }
    vector <int> cur2 = cur;
    sort(cur2.begin(), cur2.end());
    ll hash = 0;
    for (int x : cur2) {
      hash = hash * P + x;
    }
    dbg(" hash %lld\n", hash);
    res.push_back(make_pair(hash, cur));
  } while (next_permutation(perm.begin(), perm.begin() + k));
  sort(res.begin(), res.end());
  return res;
}

bool check(const vector<int> & a, const vector<int> & b) {
  for (int x : a) {
    dbg("%d ", x);
  }
  dbg(" | ");
  for (int x : b) {
    dbg("%d ", x);
  }
  dbg("\n");
  int n = int(a.size());
  vector <bool> used(n, false);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < i; ++j) {
      if (used[j]) { continue; }
      if (a[j] == b[i] && b[j] == a[i]) {
        used[j] = true;
        used[i] = true;
        break;
      }
    }
  }
  int cnt = 0;
  for (int i = 0; i < n; ++i) {
    if (!used[i]) {
      if (a[i] != b[i] || cnt != 0) {
        return false;
      }
      cnt += 1;
    }
  }
  return true;
}

bool check(const vector<pair<ll, vector<int>>> & a,
           const vector<pair<ll, vector<int>>> & b,
           int i0, int i1,
           int j0, int j1) {
  dbg("check %d %d , %d %d\n", i0, i1, j0, j1);
  for (int i = i0; i < i1; ++i) {
    for (int j = j0; j < j1; ++j) {
      if (check(a[i].second, b[j].second)) {
        return true;
      }
    }
  }
  return false;
}

bool solve(int n, int m, int mid, int mask0) {
  //dbg("mid %d mask %d\n", mid, mask0);
  vector <pair<ll, vector<int>>> a = gen(n, m, mid, mask0, 0);
  vector <pair<ll, vector<int>>> b = gen(n, m, mid, mask0, 1);
  for (int i = 0, j = 0; i < int(a.size()) && j < int(b.size()); ) {
    if (a[i].first == b[j].first) {
      int i0 = i;
      while (i < int(a.size()) && a[i0].first == a[i].first) {
          ++i;
      }
      int j0 = j;
      while (j < int(b.size()) && b[j0].first == b[j].first) {
          ++j;
      }
      if (check(a, b, i0, i, j0, j)) {
        return true;
      }
    } else if (a[i].first < b[j].first) {
      ++i;
    } else {
      ++j;
    }
  }
  return false;
}

bool solve(int n, int m, int mid) {
  for (int mask = 0; mask < (1 << n); ++mask) {
    if (mid != -1 && (mask & (1 << mid))) {
      continue;
    }
    if (mid == 0 && n != 1 && (mask & 2) == 0) { continue; }
    if (mid != 0 && (mask & 1) == 0) { continue; }
    if (__builtin_popcount(mask) != n / 2) {
      continue;
    }

    if (solve(n, m, mid, mask)) {
      return true;
    }
  }
  return false;
}

bool solve(int n, int m) {
  if (n % 2 == 1) {
    for (int i = 0; i < n; ++i) {
      if (solve(n, m, i)) {
        return true;
      }
    }
    return false;
  } else {
    return solve(n, m, -1);
  }
}

bool solve() {
  int n, m;
  if (scanf("%d%d", &n, &m) != 2 || !n) { return false; }

  for (int i = 0; i < n; ++i) {
    scanf("%s", s[i]);
  }

  printf("%s\n", solve(n, m) ? "YES" : "NO");

  return true;
}

int main() {
  while (solve());
  return 0;
}

Measured memory_bytes: 480