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

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 inputs = subtract (2 * n) <$> minCostFlow numV numE vvccs source sink flow0
  where
    numV = m + n + 3
    numE = V.foldl' (\acc (_,b,_)->acc + b) (n + m) inputs
    vvccs = U.concat [srcToKey,keyToBox,boxToDst]
    source = 0
    sink = n + m + 1
    flow0 = n
    srcToKey, keyToBox, boxToDst  :: U.Vector (Vertex, Vertex, Cost, Capacity)
    srcToKey = V.convert $ V.imap (\i (a,b,cs) -> (source, i + 1, 1, b)) inputs
    keyToBox = V.convert
        . V.concatMap (\(i,(a,b,cs)) -> U.convert $ U.map (\c -> (i + 1, m + c, a, 1)) cs)
        $ V.indexed inputs
    boxToDst = U.generate n $ \i ->
        (m + i + 1, sink, 1, 1)

------------------------------------------------------------------------------
data Heap a = Fork !a [Heap a] | Empty

singleton :: a -> Heap a
singleton x = Fork x []
{-# INLINE singleton #-}

isEmpty :: Heap a -> Bool
isEmpty Empty = True
isEmpty _     = False
{-# INLINE isEmpty #-}

insert :: Ord a => a -> Heap a -> Heap a
insert x = merge (Fork x [])
{-# INLINE insert #-}

minElem :: Heap a -> Maybe a
minElem (Fork x _) = Just x
minElem _          = Nothing
{-# INLINE minElem #-}

deleteMin :: Ord a => Heap a -> Maybe (Heap a)
deleteMin (Fork _ hs) = Just $! mergePairs hs
deleteMin _           = Nothing
{-# INLINE deleteMin #-}

deleteFindMin :: Ord a => Heap a -> Maybe (a, Heap a)
deleteFindMin (Fork x hs) = Just (x, mergePairs hs)
deleteFindMin _           = Nothing
{-# INLINE deleteFindMin #-}

merge :: Ord a => Heap a -> Heap a -> Heap a
merge hx@(Fork x hxs) hy@(Fork y hys)
  | x <= y    = Fork x (hy:hxs)
  | otherwise = Fork y (hx:hys)
merge Empty hy = hy
merge hx _ = hx
{-# INLINE merge #-}

mergePairs :: Ord a => [Heap a] -> Heap a
mergePairs (x:y:hs) = merge (merge x y) (mergePairs hs)
mergePairs [x]      = x
mergePairs []       = Empty
{-# INLINE mergePairs #-}

instance Ord a => IsList (Heap a) where
    type Item (Heap a) = a
    fromList xs = mergePairs $ map singleton xs
    toList = L.unfoldr deleteFindMin

instance (Show a, Ord a) => Show (Heap a) where
    show = show . toList

unsafeModify :: (PrimMonad m, GM.MVector mv a)
             => mv (PrimState m) a -> Int -> (a -> a) -> m ()
unsafeModify v i f = GM.unsafeRead v i >>= GM.unsafeWrite v i . f
{-# INLINE unsafeModify #-}


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 #-}

nothing :: Int
nothing = -1

inf :: Int
inf = 0x3f3f3f3f

type Vertex = Int
type Cost = Int
type Capacity = Int

minCostFlow :: Int
            -> Int
            -> U.Vector (Vertex, Vertex, Cost, Capacity)
            -> Vertex
            -> Vertex
            -> Capacity
            -> Maybe Cost
minCostFlow numV numE vvccs source sink flow0 = runST $ do
    gr <- VM.replicate numV ([] :: [Int])
    residual <- UM.replicate (2*numE) 0
    to <- UM.replicate (2*numE) 0
    cost <- UM.replicate (2*numE) 0
    potential <- UM.replicate numV (0 :: Int)
    dist <- UM.replicate numV inf
    prevv <- UM.replicate numV nothing
    preve <- UM.replicate (2*numE) nothing

    U.foldM'_ `flip` 0 `flip` vvccs $ \i (src,dst,c,cap) -> do
        unsafeModify gr src (i:) >> unsafeModify gr dst ((i+1):)
        UM.unsafeWrite to i dst  >> UM.unsafeWrite to (i+1) src
        UM.unsafeWrite cost i c  >> UM.unsafeWrite cost (i+1) (-c)
        UM.unsafeWrite residual i cap
        return $! i + 2

    let dijkstra (Fork (c,v) hs) = do
            dv <- UM.unsafeRead dist v
            if c > dv then dijkstra $ mergePairs hs
            else do
                es <- VM.unsafeRead gr v
                hs' <- forM es $ \e -> do
                    nv   <- UM.unsafeRead to e
                    cap  <- UM.unsafeRead residual e
                    hv   <- UM.unsafeRead potential v
                    hnv  <- UM.unsafeRead potential nv
                    v2nv <- UM.unsafeRead cost e
                    old  <- UM.unsafeRead dist nv
                    let dnv = dv + v2nv + hv - hnv
                    if cap > 0 && dnv < old then do
                        UM.unsafeWrite dist nv dnv
                        UM.unsafeWrite prevv nv v
                        UM.unsafeWrite preve nv e
                        return $ Fork (dnv, nv) []
                    else return Empty
                dijkstra $ mergePairs hs `merge` mergePairs hs'
        dijkstra Empty = UM.unsafeRead dist sink

    let update flow = go sink flow
          where
            go !v !f = do
                pv <- UM.unsafeRead prevv v
                if pv < 0 then return f
                else do
                    pv2v <- UM.unsafeRead preve v
                    nf <- UM.unsafeRead residual pv2v >>= go pv . min f
                    unsafeModify residual pv2v (subtract nf)
                    unsafeModify residual (xor pv2v 1) (nf+)
                    return nf

    let primalDual !flow !res
            | flow == 0 = return $ Just res
            | otherwise = do
                UM.set dist inf
                UM.unsafeWrite dist source 0
                dsink <- dijkstra $ singleton (0, source)
                if dsink == inf then return Nothing
                else do
                    rep numV $ \v-> do
                        dv <- UM.unsafeRead dist v
                        unsafeModify potential v (dv+)
                    f <- update flow
                    hsink <- UM.unsafeRead potential sink
                    primalDual (flow - f) $ hsink * f + res
    primalDual flow0 0

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)