import Control.Monad
import Data.Array
import Data.List
import Data.Tuple (swap)
import Debug.Trace

import Test.QuickCheck

main = do
  [h,w] <- fmap (map read . words) getLine
  wss <- replicateM h getLine
  let tab = listArray ((1,1),(h,w)) (concat wss)
  putStrLn (solve tab)


type Table = Array (IxRow,IxCol) Char
type IxRow = Int
type IxCol = Int


showTable :: Table -> String
showTable tab =
  unlines [[ tab!(r,c) | c<-[ca..cz]] | r<-[ra..rz]]
  where
    ((ra,ca),(rz,cz)) = bounds tab

findElem :: IxRow -> Char -> Table -> [IxRow]
findElem r x tab =
  elemIndices x (elems (ixmap ((r,ca),(r,cz)) id tab))
  where
    ((ra,ca),(rz,cz)) = bounds tab

transposeTable :: Table -> Table
transposeTable tab =
  ixmap ((ca,ra),(cz,rz)) swap tab
  where
    ((ra,ca),(rz,cz)) = bounds tab

swapRow :: IxRow -> IxRow -> Table-> Table
swapRow i j tab =
  ixmap (bounds tab) f tab
  where
    f (r,c) | r == i    = (j,c)
            | r == j    = (i,c)
            | otherwise = (r,c)

swapCol :: IxCol -> IxCol -> Table -> Table
swapCol i j tab =
  ixmap (bounds tab) f tab
  where
    f (r,c) | c == i    = (r,j)
            | c == j    = (r,i)
            | otherwise = (r,c)

solve :: Table -> String
solve tab =
--  trace (unlines $ map showTable rowSolved) $
  if null [t| t<-rowColSolved, checkSymmetric t] then "NO" else "YES"
  where
    ((ra,ca),(rz,cz)) = bounds tab

    rowSolved = concat [solveRow 1 r tab | r<-[ra..rz]]
    rowColSolved = concat [solveRow 1 c t' | t <- rowSolved, let t' = transposeTable t, c<-[ca..cz]]

solveRow :: IxRow -> IxRow -> Table -> [Table]
solveRow r1 r2 tab =
  go ca cz [] tab
  where
    go c1 c2 center t
--      | trace (showTable t ++ show (c1,cz)) False = undefined
      | length center > 1 = []
      | c1 >= c2  = [t]
      | otherwise = let ts = solveRowCol r1 r2 c1 c2 t
                    in if null ts && odd cz
                         then go c1 c2 (c1:center) (swapCol c1 (cz`div`2+1) t)
                         else concatMap (go (c1+1) (c2-1) center) ts

    ((ra,ca),(rz,cz)) = bounds tab

solveRowCol :: IxRow -> IxRow -> IxCol -> IxCol -> Table -> [Table]
solveRowCol r1 r2 c1 c2 tab
  | trace (showTable tab ++ show (r1,r2,c1,c2)) False = undefined
  | c1 == c2  = [tab]
  | otherwise = [swapCol c c2 tab |c<-[c1+1..c2], isSymmetric r1 r2 c1 c tab]

isSymmetric :: IxRow -> IxRow -> IxCol -> IxCol -> Table -> Bool
isSymmetric r1 r2 c1 c2 tab =
  x11 == x22 && x21 == x12
  where
    x11 = tab!(r1,c1)
    x21 = tab!(r2,c1)
    x12 = tab!(r1,c2)
    x22 = tab!(r2,c2)

checkSymmetric :: Table -> Bool
checkSymmetric tab =
  and [isSymmetric r (rz-r+1) c (cz-c+1) tab | r<-[ra..rz], r<=rz-r+1, c<-[ca..cz]]
  where
    ((ra,ca),(rz,cz)) = bounds tab