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.List (sort, sortOn, permutations)
import Data.Char --(toLower, toUpper, isUpper)
import Data.Ord -- Data.Ord.Down 
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

bslen = BS.length -- o(1)
bshd = BS.head -- o(1)
bstl = BS.tail -- o(1)
bslst = BS.last -- o(1)
bsini = BS.init -- o(1)
charToInt n = ord n - ord '0'
readi n = read n :: Int

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

getLinesToInts :: Int -> IO [Int]
getLinesToInts n = replicateM n $ bsToInt <$> BS.getLine

--Vector (one dimensional array)
getLinesToVectorInts :: Int -> IO (V.Vector Int)
getLinesToVectorInts n = V.replicateM n $ bsToInt <$> BS.getLine

getLinesToVector_TupleIntInt :: Int -> IO (V.Vector (Int, Int))
getLinesToVector_TupleIntInt n =
    V.replicateM n $ do
        [a,b] <- getInts
        return (a,b)

mapPutStrLn :: [String] -> IO()
mapPutStrLn = mapM_ putStrLn


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 :: IOArray Int [Int] -> [Int] -> [Int] -> VM.IOVector Int -> Int -> IO ()
-- n-1 rooms is done
bfs _ _ _ _ 1 
    = return ()

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

bfs connects (r:rests) nexts exits k 
    = do
        as <- readArray connects r 
        as' <- filter (/= 0) <$> sequence [ do
                e <- VM.read exits a
                if e == 0 then do
                    VM.write exits a r
                    return a
                else return 0
                | a <- as ]
        bfs connects rests (as' ++ nexts) exits (k - length as') 



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)
    connects <- newArray (1, n) [] :: IO(IOArray Int [Int])
    
    mapM_ (\(a,b) -> effect connects a (b:) >> effect connects b (a:)) abs
    VM.set exits 0
    VM.write exits 1 1
    bfs connects [1] [] exits n 
    putStrLn "Yes"
    mapM_ (\i -> VM.read exits i >>= print) [2..n]









