import qualified Data.ByteString.Char8 as B
import Control.Monad
import Data.List
import qualified Data.Vector as V

import Control.Monad.Trans.State.Strict
import Data.Char (isSpace)
import Data.Maybe (fromJust)

type Parser a = StateT B.ByteString Maybe a

parseInt :: Parser Int
parseInt = StateT (B.readInt . B.dropWhile isSpace)

parseInt2 :: Parser (Int,Int)
parseInt2 = liftM2 (,) ((+(-1))<$>parseInt) ((+(-1))<$>parseInt)

parse :: Parser (Int, V.Vector (Int,Int))
parse = do
    n <- parseInt
    m <- parseInt
    fmap ((,) n) (V.replicateM m parseInt2)

t2 [a,b]=(a-1,b-1)
main=do
    (n,xys) <- fromJust.evalStateT parse <$> B.getContents
    print $ g n xys

g n xys = V.maximum v where
    ve = V.accumulate (flip (:)) (V.replicate n []) xys
    v = V.generate n m
    m i = (+1) $ maximum $ ((-1):) $ map (v V.!) (ve V.! i) 