import std.algorithm;
import std.array;
import std.conv;
import std.math;
import std.range;
import std.stdio;
import std.string;

void main() {
  auto z = readln.strip.splitter.map! (i => i.to!int).array;
  int h = z[0];
  int w = z[1];
  string [] a = new string[h];
  foreach (t; 0 .. h) {
    a[t] = readln[0 .. w];
  }
  int s = 0;
  auto x = new int[w];
  bool check () {
    int st = 0;
    int t = h;
    while (t > 0) {
      foreach (i; 0 .. h) {
        if (!(st & (1 << i))) {
          bool found = false;
          foreach (j; i + ((t > 1) ? 1 : 0) .. h) {
            if (!(st & (1 << j))) {
              bool eq = true;
              foreach (k; 0 .. w) {
                debug stderr.writeln(k);
                debug stderr.writeln(x[k]);
                debug stderr.writeln(x[w-1-k]);
                if (a[i][x[k]] != a[j][x[w-1-k]]) {
                  eq = false;
                  break;
                }
              }
              if (eq) {
                st |= (1 << i) | (1 << j);
                found  = true;
                break;
              }
            }
          }
          if (!found) return false;
          break;
        }
      }
      t -= 2;
    }
    return true;
  }
  bool go (int k, int st) {
    if (k == w) {
      return check (); 
    }
    foreach (i; 0 .. w) {
      if (!(st & (1 << i))) {
        x[k] = i;
        if (go (k + 1, st | (1 << i))) return true;
      }
    }
    return false;
  }
  if (go (0, 0)) {
    writeln ("YES");
  } else {
    writeln ("NO");
  }
}
