{-# LANGUAGE BangPatterns #-} import Control.Monad import Data.Bits import Data.Maybe import Data.IORef import qualified Data.ByteString.Char8 as BSC8 import qualified Data.Vector.Fusion.Stream.Monadic as VFSM import qualified Data.Vector.Unboxed.Mutable as VUM main :: IO () main = do [n, m] <- map (read :: String -> Int) . words <$> getLine score <- VUM.replicate (n * n) (0 :: Int) rep m $ \_ -> do [a, b, s] <- getIntList VUM.unsafeWrite score (a * n + b) s dp <- VUM.replicate (1 .<<. n) (0 :: Int) rep (1 .<<. n) $ \bit -> rep n $ \v -> do when (bit .&. (1 .<<. v) == 0) $ do su <- newIORef (0 :: Int) rep n $ \i -> do when (bit .&. (1 .<<. i) /= 0) $ do item <- VUM.unsafeRead score (i * n + v) modifyIORef' su (+ item) item1 <- VUM.unsafeRead dp bit item2 <- readIORef su VUM.unsafeModify dp (max (item1 + item2)) (bit .|. (1 .<<. v)) print =<< VUM.unsafeRead dp ((1 .<<. n) - 1) stream :: Monad m => Int -> Int -> VFSM.Stream m Int stream !l !r = VFSM.Stream step l where step x | x < r = return $ VFSM.Yield x (x + 1) | otherwise = return $ VFSM.Done {-# INLINE [0] step #-} {-# INLINE [1] stream #-} rep :: Monad m => Int -> (Int -> m ()) -> m () rep n = flip VFSM.mapM_ (stream 0 n) {-# INLINE rep #-} readInt :: BSC8.ByteString -> Int readInt = fst . fromJust . BSC8.readInt {-# INLINE readInt #-} getInt :: IO Int getInt = readInt <$> BSC8.getLine {-# INLINE getInt #-} readIntList :: BSC8.ByteString -> [Int] readIntList = map readInt . BSC8.words {-# INLINE readIntList #-} getIntList :: IO [Int] getIntList = readIntList <$> BSC8.getLine {-# INLINE getIntList #-} infixl 8 .<<. (.<<.) :: Bits b => b -> Int -> b (.<<.) = unsafeShiftL {-# INLINE (.<<.) #-}