fun main(args: Array<String>) {
  val (h, w) = readLine()!!.split(" ").map { it.toInt() }
  val board = Array(h, { readLine()!! })

  var ans = false

  val rowPairs = IntArray(h, { -1 })
  var remainingRows = h

  val colPairs = IntArray(w, { -1 })
  var remainingCols = w

  fun isSymmetryRow(r: Int): Boolean {
    return (0 until w).all { c -> board[r][c] == board[r][colPairs[c]] }
  }

  fun areReverseRows(r1: Int, r2: Int): Boolean {
    return (0 until w).all { c -> board[r1][c] == board[r2][colPairs[c]] }
  }

  fun searchRowPairs() {
    if (remainingRows == 0) {
      ans = true
    } else if (remainingRows == h && h % 2 == 1) {
      for (r in 0 until h) {
        if (isSymmetryRow(r)) {
          rowPairs[r] = r
          remainingRows -= 1
          searchRowPairs()
          rowPairs[r] = -1
          remainingRows += 1
        }
      }
    } else {
      val r1 = rowPairs.indexOfFirst { it == -1 }
      for (r2 in r1 + 1 until h) {
        if (areReverseRows(r1, r2)) {
          rowPairs[r1] = r2
          rowPairs[r2] = r1
          remainingRows -= 2
          searchRowPairs()
          rowPairs[r1] = -1
          rowPairs[r2] = -1
          remainingRows += 2
          break
        }
      }
    }
  }

  fun searchColPairs() {
    if (remainingCols == 0) {
      searchRowPairs()
    } else if (remainingCols == w && w % 2 == 1) {
      for (c in 0 until w) {
        colPairs[c] = c
        remainingCols -= 1
        searchColPairs()
        colPairs[c] = -1
        remainingCols += 1
      }
    } else {
      val c1 = colPairs.indexOfFirst { it == -1 }
      for (c2 in c1 + 1 until w) {
        if (colPairs[c2] == -1) {
          colPairs[c1] = c2
          colPairs[c2] = c1
          remainingCols -= 2
          searchColPairs()
          colPairs[c1] = -1
          colPairs[c2] = -1
          remainingCols += 2
        }
      }
    }
  }

  searchColPairs()

  println(if (ans) "YES" else "NO")
}
