{-# OPTIONS_GHC -O2 #-}
{-# LANGUAGE BangPatterns          #-}
{-# LANGUAGE CPP                   #-}
{-# LANGUAGE LambdaCase            #-}
{-# LANGUAGE MagicHash             #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE MultiWayIf            #-}
{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE TupleSections         #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE ViewPatterns          #-}
{-# LANGUAGE RecordWildCards       #-}

import           Control.Applicative
import           Control.Exception
import           Control.Monad
import           Control.Monad.Primitive
import           Control.Monad.ST
import           Control.Monad.State.Strict
import           Data.Bool
import qualified Data.ByteString             as B
import qualified Data.ByteString.Builder     as B
import qualified Data.ByteString.Char8       as C
import qualified Data.ByteString.Internal    as B
import qualified Data.ByteString.Unsafe      as B
import           Data.Char
import qualified Data.Foldable               as F
import           Data.Function
import qualified Data.IntMap.Strict          as IM
import qualified Data.IntSet                 as IS
import qualified Data.List                   as L
import qualified Data.Map.Strict             as M
import           Data.Monoid
import           Data.Ord
import           Data.Primitive.MutVar
import qualified Data.Set                    as S
import           Data.Tuple
import qualified Data.Vector                 as V
import qualified Data.Vector.Mutable         as VM
import qualified Data.Vector.Generic         as G
import qualified Data.Vector.Generic.Mutable as GM
import qualified Data.Vector.Unboxed         as U
import qualified Data.Vector.Unboxed.Mutable as UM
import           Debug.Trace
import           Foreign                     hiding (void)
import           GHC.Exts
import qualified System.IO                   as IO
import           Unsafe.Coerce

main :: IO ()
main = do
    [n, m] <- map read.words <$> getLine :: IO [Int]
    edges <- V.replicateM m $ do
        [!a, !b] <- map read.words <$> getLine :: IO [Int]
        xs <- U.unfoldrN b parseInt <$> C.getLine
        return (a, b, xs)
    print . maybe (-1) id $ solve n m edges

solve :: Int -> Int -> V.Vector (Int, Int, U.Vector Int) -> Maybe Int
solve n m keys
    | dist U.! dst == inf = Nothing
    | otherwise = Just $ dist U.! dst
  where
    src = 0
    dst = shiftL 1 n - 1
    dist = dijkstraDense src gr
    inf = 0x3f3f3f3f
    gr = runST $ do
        let ix i j = unsafeShiftL i n .|. j
        m <- UM.replicate (shiftL 1 $ 2 * n) inf
        rep (shiftL 1 n) $ \i -> do
            rep (shiftL 1 n) $ \j -> do
                when (i >= j) $ do
                    UM.unsafeWrite m (ix i j) 0
        V.forM_ keys $ \(cost, _, boxes) -> do
            let !key = U.foldl' (\acc i -> setBit acc (i - 1)) 0 boxes
            rep (shiftL 1 n) $ \s -> do
                let s' = s .|. key
                c <- UM.unsafeRead m (ix s s')
                when (cost < c) $ do
                    UM.unsafeWrite m (ix s s') cost
        DenseGraph (shiftL 1 n) <$> U.unsafeFreeze m

type Vertex = Int
type Cost = Int
data DenseGraph a = DenseGraph
    { numVerticesDG :: !Int
    , adjDG :: U.Vector a
    }
instance (U.Unbox a, Show a) => Show (DenseGraph a) where
    show DenseGraph{..} = unlines
        . V.toList
        . V.map (show . U.toList)
        $ V.unfoldrN numVerticesDG (\vec ->
            if U.null vec
            then Nothing
            else Just $ U.splitAt numVerticesDG vec
            ) adjDG

dijkstraDense :: Vertex -> DenseGraph Cost -> U.Vector Cost
dijkstraDense src DenseGraph{..} = U.create $ do
    let n = numVerticesDG
    dist <- UM.replicate (n + 1) maxBound
    used <- UM.replicate n False
    UM.write dist src 0
    let nothing = n
    vars <- UM.replicate 2 0
    let [_v, _dv] = [0..1]
    fix $ \loop -> do
        UM.unsafeWrite vars _v nothing
        UM.unsafeWrite vars _dv maxBound
        rep n $ \i -> do
            UM.unsafeRead used i >>= \case
                False -> do
                    di <- UM.unsafeRead dist i
                    dv <- UM.unsafeRead vars _dv
                    when (di < dv) $ do
                        UM.unsafeWrite vars _v i
                        UM.unsafeWrite vars _dv di
                True -> return ()
        v <- UM.unsafeRead vars _v
        when (v /= nothing) $ do
            UM.unsafeWrite used v True
            dv <- UM.unsafeRead vars _dv
            rep n $ \i -> do
                di <- UM.unsafeRead dist i
                let di' = dv + U.unsafeIndex adjDG (v * n + i)
                when (di' < di) $ do
                    UM.unsafeWrite dist i di'
            loop
    return dist


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

rep :: Monad m => Int -> (Int -> m ()) -> m ()
rep !n = U.forM_ $ U.generate n id
{-# INLINE rep #-}

rev :: Monad m => Int -> (Int -> m ()) -> m ()
rev !n = U.forM_ $ U.iterateN n (subtract 1) (n - 1)
{-# INLINE rev #-}


type Parser a = C.ByteString -> Maybe (a, C.ByteString)

parseInt :: Parser Int
parseInt = C.readInt . C.dropWhile isSpace

parseInt2 :: Parser (Int, Int)
parseInt2 = runStateT $
    (,) <$> StateT (C.readInt . C.dropWhile isSpace)
        <*> StateT (C.readInt . B.unsafeTail)

parseInt3 :: Parser (Int, Int, Int)
parseInt3 = runStateT $
    (,,) <$> StateT (C.readInt . C.dropWhile isSpace)
        <*> StateT (C.readInt . B.unsafeTail)
        <*> StateT (C.readInt . B.unsafeTail)

parseInt4 :: Parser (Int, Int, Int, Int)
parseInt4 = runStateT $
    (,,,) <$> StateT (C.readInt . C.dropWhile isSpace)
        <*> StateT (C.readInt . B.unsafeTail)
        <*> StateT (C.readInt . B.unsafeTail)
        <*> StateT (C.readInt . B.unsafeTail)