import Control.Monad
import Data.Maybe
import qualified Data.ByteString.Char8 as BS --(ByteString, getLine, readInt, words)
import qualified  Data.ByteString as B
import Data.Array.Unboxed (UArray)
import Data.Array (Array, listArray, array, (!), (//), indices, elems, assocs)
import Data.Array.IArray (IArray) 

import Data.Array.ST  --(newListArray, runSTUArray, newArray, writeArray, readArray)
import Data.Array.IO 
import Control.Monad.ST (ST)

import qualified Data.Vector.Unboxed         as V --(fromList, !, replicateM)
import qualified Data.Vector.Unboxed.Mutable as VM --(new, read, write, swap, modify, unsafeWrite, unsafeRead, STVector, IOVector)


-- example: putStrLn show 123 ++ "and" ~~ 456 ++ "or" ~~ 789
(~~) :: Show a => String -> a -> String
a ~~ b = a ++ show b

bsToInt :: BS.ByteString -> Int
bsToInt = fst . fromJust . BS.readInt
getInt = bsToInt <$> BS.getLine

bsToInts :: BS.ByteString -> [Int]
bsToInts = map bsToInt . BS.words 
getInts = bsToInts <$> BS.getLine

getLines :: Int -> IO [BS.ByteString]
getLines n = replicateM n BS.getLine


effect :: (MArray a e m, Ix i) => a i e -> i -> (e -> e) -> m ()
effect ary i operator = (operator <$> readArray ary i) >>= writeArray ary i

-------------------------------------------------------------------------------
-------------------------------------------------------------------------------

bfs :: Array Int [Int] -> [Int] -> [Int] -> VM.IOVector Int -> Int -> IO ()
-- n-1 rooms is done
bfs _ _ _ _ 1 
    = return ()

-- go to next depth
bfs neighborsAry [] nexts exits k 
    = bfs neighborsAry nexts [] exits k

--transcribe current room's neighbors onto "exits"
bfs neighborsAry (c:currents) nexts exits k 
    = do
        let neighbors = neighborsAry ! c 
        newNexts <- filter (/= 0) <$> sequence [ do
                exit <- VM.read exits nb
                if exit == 0 then do
                    VM.write exits nb c
                    return nb
                else return 0
                | nb <- neighbors ]
        bfs neighborsAry currents (newNexts ++ nexts) exits (k - length newNexts) 



main :: IO ()
main = do
    [n,m] <- getInts
    abs <- replicateM m $ do 
        [a,b] <- getInts
        return (a,b)

    exits <- VM.new (n+1) :: IO(VM.IOVector Int)
    VM.set exits 0
    VM.write exits 1 1

    neighborsMAry <- newArray (1, n) [] :: IO(IOArray Int [Int])
    mapM_ (\(a,b) -> effect neighborsMAry a (b:) >> effect neighborsMAry b (a:)) abs
    neighborsAry <- freeze neighborsMAry
    bfs neighborsAry [1] [] exits n 

    putStrLn "Yes"
    mapM_ (\i -> VM.read exits i >>= print) [2..n]
