Submission #44235183


Source Code Expand

#!/usr/bin/env stack
{- stack script --resolver lts-16.31 --package array --package bytestring --package containers --package extra --package hashable --package unordered-containers --package heaps --package utility-ht --package vector --package vector-th-unbox --package vector-algorithms --package primitive --package transformers --ghc-options "-D DEBUG" -}

{-# OPTIONS_GHC -Wno-unused-imports -Wno-unused-top-binds #-}

-- {{{ toy-lib: https://github.com/toyboot4e/toy-lib
{- ORMOLU_DISABLE -}
{-# LANGUAGE BangPatterns, BlockArguments, CPP, DefaultSignatures, FlexibleContexts, FlexibleInstances, InstanceSigs, LambdaCase, MultiParamTypeClasses, MultiWayIf, NamedFieldPuns, NumDecimals, NumericUnderscores, PatternGuards, QuantifiedConstraints, RankNTypes, RecordWildCards, ScopedTypeVariables, StrictData, TemplateHaskell, TupleSections, TypeApplications, TypeFamilies #-}
import Control.Applicative;import Control.Exception (assert);import Control.Monad;import Control.Monad.Fix;import Control.Monad.Primitive;import Control.Monad.ST;import Control.Monad.Trans.State.Strict;import Data.Bifunctor;import Data.Bits;import Data.Bool (bool);import Data.Char;import Data.Coerce;import Data.Either;import Data.Foldable;import Data.Function (on);import Data.Functor;import Data.Functor.Identity;import Data.IORef;import Data.List;import Data.Maybe;import Data.Ord;import Data.Proxy;import Data.STRef;import Data.Semigroup;import Data.Word;import Debug.Trace;import GHC.Exts;import GHC.Float (int2Float);import System.Exit (exitSuccess);import System.IO;import Text.Printf;import qualified Data.Ratio as Ratio;import Data.Array.IArray;import Data.Array.IO;import Data.Array.MArray;import Data.Array.ST;import Data.Array.Unboxed (UArray);import Data.Array.Unsafe;import qualified Data.Array as A;import qualified Data.ByteString.Builder as BSB;import qualified Data.ByteString.Char8 as BS;import Control.Monad.Extra hiding (loop);import Data.IORef.Extra;import Data.List.Extra hiding (merge);import Data.Tuple.Extra hiding (first, second);import Numeric.Extra;import Data.Bool.HT;import qualified Data.Ix.Enum as HT;import qualified Data.List.HT as HT;import qualified Data.Vector.Fusion.Bundle as VFB;import qualified Data.Vector.Generic as VG;import qualified Data.Vector.Generic.Mutable as VGM;import qualified Data.Vector.Unboxed as VU;import qualified Data.Vector.Unboxed.Mutable as VUM;import qualified Data.Vector as V;import qualified Data.Vector.Mutable as VM;import qualified Data.Vector.Fusion.Bundle.Monadic as MB;import qualified Data.Vector.Fusion.Bundle.Size as MB;import qualified Data.Vector.Fusion.Stream.Monadic as MS;import qualified Data.Vector.Algorithms.Intro as VAI;import qualified Data.Vector.Algorithms.Search as VAS;import Data.Vector.Unboxed.Deriving (derivingUnbox);import qualified Data.Graph as G;import qualified Data.IntMap.Strict as IM;import qualified Data.Map.Strict as M;import qualified Data.IntSet as IS;import qualified Data.Set as S;import qualified Data.Sequence as Seq;import qualified Data.Heap as H;import Data.Hashable;import qualified Data.HashMap.Strict as HM;import qualified Data.HashSet as HS

#ifdef DEBUG
dbg :: Show a => a -> () ; dbg !x = let !_ = traceShow x () in () ; dbgAssert :: Bool -> String -> () ; dbgAssert False !s = error $ "assertion failed!: " ++ s ; dbgAssert True _ = () ; dbgS :: String -> () ; dbgS !s = let !_ = trace s () in () ;
#else
dbg :: Show a => a -> () ; dbg _ = () ; dbgAssert :: Bool -> a -> a ; dbgAssert = flip const ; dbgS :: String -> () ; dbgS _ = () ;
#endif

type SparseUnionFind = IM.IntMap Int;newSUF :: SparseUnionFind;newSUF = IM.empty;fromListSUF :: [(Int, Int)] -> SparseUnionFind;fromListSUF = foldl' (uncurry . uniteSUF) newSUF;rootSUF :: SparseUnionFind -> Int -> (Int, Int);rootSUF !uf !i | IM.notMember i uf = (i, 1) | j < 0 = (i, -j) | otherwise = rootSUF uf j where { j = uf IM.! i};sameSUF :: SparseUnionFind -> Int -> Int -> Bool;sameSUF !uf !i !j = fst (rootSUF uf i) == fst (rootSUF uf j);uniteSUF :: SparseUnionFind -> Int -> Int -> SparseUnionFind;uniteSUF !uf !i !j | a == b = uf | r >= s = IM.insert a (negate $! r + s) $ IM.insert b a uf | otherwise = IM.insert b (negate $! r + s) $ IM.insert a b uf where { (!a, !r) = rootSUF uf i; (!b, !s) = rootSUF uf j};newtype MUnionFind s = MUnionFind (VUM.MVector s MUFNode);type IOUnionFind = MUnionFind RealWorld;type STUnionFind s = MUnionFind s;data MUFNode = MUFChild {-# UNPACK #-} !Int | MUFRoot {-# UNPACK #-} !Int;derivingUnbox "MUFNode" [t| MUFNode -> (Bool, Int) |] [| \case { (MUFChild !x) -> (True, x); (MUFRoot !x) -> (False, x)} |] [| \case { (True, !x) -> MUFChild x; (False, !x) -> MUFRoot x} |];{-# INLINE newMUF #-};newMUF :: (PrimMonad m) => Int -> m (MUnionFind (PrimState m));newMUF !n = MUnionFind <$> VUM.replicate n (MUFRoot 1);{-# INLINE rootMUF #-};rootMUF :: (PrimMonad m) => MUnionFind (PrimState m) -> Int -> m Int;rootMUF uf@(MUnionFind !vec) i = do { !node <- VUM.unsafeRead vec i; case node of { MUFRoot _ -> return i; MUFChild p -> do { !r <- rootMUF uf p; VUM.unsafeWrite vec i (MUFChild r); return r}}};{-# INLINE groupsMUF #-};groupsMUF :: (PrimMonad m) => MUnionFind (PrimState m) -> m IS.IntSet;groupsMUF uf@(MUnionFind !vec) = foldM step IS.empty [0 .. pred (VGM.length vec)] where { step !is !i = do { !root <- rootMUF uf i; return $ IS.insert root is}};{-# INLINE sameMUF #-};sameMUF :: (PrimMonad m) => MUnionFind (PrimState m) -> Int -> Int -> m Bool;sameMUF !uf !x !y = liftM2 (==) (rootMUF uf x) (rootMUF uf y);_unwrapMUFRoot :: MUFNode -> Int;_unwrapMUFRoot (MUFRoot !s) = s; _unwrapMUFRoot (MUFChild !_) = error "tried to unwrap child as UF root";{-# INLINE uniteMUF #-};uniteMUF :: (PrimMonad m) => MUnionFind (PrimState m) -> Int -> Int -> m ();uniteMUF uf@(MUnionFind !vec) !x !y = do { !px <- rootMUF uf x; !py <- rootMUF uf y; when (px /= py) $ do { !sx <- _unwrapMUFRoot <$> VUM.unsafeRead vec px; !sy <- _unwrapMUFRoot <$> VUM.unsafeRead vec py; let { (!par, !chld) = if sx < sy then (px, py) else (py, px)}; VUM.unsafeWrite vec chld (MUFChild par); VUM.unsafeWrite vec par (MUFRoot $! sx + sy)}};{-# INLINE sizeMUF #-};sizeMUF :: (PrimMonad m) => MUnionFind (PrimState m) -> Int -> m Int;sizeMUF uf@(MUnionFind !vec) !x = do { !px <- rootMUF uf x; _unwrapMUFRoot <$> VUM.unsafeRead vec px};data SegmentTree v s a = SegmentTree (a -> a -> a) (v s a);{-# INLINE newSTreeVG #-};newSTreeVG :: (VGM.MVector v a, PrimMonad m) => (a -> a -> a) -> Int -> a -> m (SegmentTree v (PrimState m) a);newSTreeVG !f !n !zero = SegmentTree f <$> VGM.replicate n' zero where { !n' = until (>= 2 * n) (* 2) 2};{-# INLINE newSTreeV #-};newSTreeV :: PrimMonad m => (a -> a -> a) -> Int -> a -> m (SegmentTree VM.MVector (PrimState m) a);newSTreeV = newSTreeVG;{-# INLINE newSTreeVU #-};newSTreeVU :: (VU.Unbox a, PrimMonad m) => (a -> a -> a) -> Int -> a -> m (SegmentTree VUM.MVector (PrimState m) a);newSTreeVU = newSTreeVG;resetSTree :: (VGM.MVector v a, PrimMonad m) => (SegmentTree v (PrimState m) a) -> a -> m ();resetSTree (SegmentTree !_ !vec) !zero = VGM.set vec zero;{-# INLINE insertSTree #-};insertSTree :: (VGM.MVector v a, PrimMonad m) => SegmentTree v (PrimState m) a -> Int -> a -> m ();insertSTree tree@(SegmentTree !_ !vec) !i !value = _updateElement tree i' value where { !offset = VGM.length vec `div` 2 - 1; !i' = i + offset};{-# INLINE modifySTree #-};modifySTree :: (VGM.MVector v a, PrimMonad m) => SegmentTree v (PrimState m) a -> (a -> a) -> Int -> m ();modifySTree tree@(SegmentTree !_ !vec) !f !i = do { !v <- f <$> VGM.unsafeRead vec i'; _updateElement tree i' v} where { !offset = VGM.length vec `div` 2 - 1; !i' = i + offset};_updateElement :: (VGM.MVector v a, PrimMonad m) => SegmentTree v (PrimState m) a -> Int -> a -> m ();_updateElement (SegmentTree !_ !vec) 0 !value = do { VGM.unsafeWrite vec 0 value}; _updateElement tree@(SegmentTree !f !vec) !i !value = do { VGM.unsafeWrite vec i value; case ((i - 1) `div` 2) of { (-1) -> return (); !iParent -> do { !c1 <- VGM.unsafeRead vec $! iParent * 2 + 1; !c2 <- VGM.unsafeRead vec $! iParent * 2 + 2; _updateElement tree iParent $! f c1 c2}}};{-# INLINE querySTree #-};querySTree :: forall v a m . (VGM.MVector v a, PrimMonad m) => SegmentTree v (PrimState m) a -> (Int, Int) -> m (Maybe a);querySTree (SegmentTree !f !vec) (!lo, !hi) | lo > hi = return Nothing | otherwise = inner 0 (0, initialHi) where { !initialHi = VGM.length vec `div` 2 - 1; inner :: Int -> (Int, Int) -> m (Maybe a); inner !i (!l, !h) | lo <= l && h <= hi = Just <$> VGM.unsafeRead vec i | h < lo || hi < l = return Nothing | otherwise = do { let { !d = (h - l) `div` 2}; !ansL <- inner (2 * i + 1) (l, l + d); !ansH <- inner (2 * i + 2) (l + d + 1, h); pure . Just $ case (ansL, ansH) of { (Just !a, Just !b) -> f a b; (Just !a, _) -> a; (_, Just !b) -> b; (_, _) -> error $ "query error (segment tree): " ++ show (i, (l, h), (lo, hi))}}};topSort :: Array Int [Int] -> [Int];topSort !graph = runST $ do { let { !bounds_ = bounds graph}; !vis <- VUM.replicate (succ $ rangeSize bounds_) False; let { dfsM !acc !v = do { !b <- VUM.unsafeRead vis (index bounds_ v); if b then return acc else do { VUM.unsafeWrite vis (index bounds_ v) True; !vs <- filterM (fmap not . VUM.unsafeRead vis . index bounds_) $ graph ! v; (v :) <$> foldM dfsM acc vs}}}; foldM dfsM [] $ range bounds_};topScc1 :: forall m . (PrimMonad m) => Array Int [Int] -> VUM.MVector (PrimState m) Bool -> Int -> m [Int];topScc1 !graph' !vis !v0 = do { let { !bounds_ = bounds graph'}; let { dfsM !acc !v = do { !b <- VUM.unsafeRead vis (index bounds_ v); if b then return acc else do { VUM.unsafeWrite vis (index bounds_ v) True; !vs <- filterM (fmap not . VUM.unsafeRead vis . index bounds_) $ graph' ! v; (v :) <$> foldM dfsM acc vs}}}; dfsM [] v0};revGraph :: Array Int [Int] -> Array Int [Int];revGraph graph = accumArray (flip (:)) [] (bounds graph) input where { input :: [(Int, Int)]; input = foldl' (\ !acc (!v2, !v1s) -> foldl' (\ !acc' !v1 -> (v1, v2) : acc') acc v1s) [] $ assocs graph};topScc :: Array Int [Int] -> [[Int]];topScc graph = collectSccPreorder $ topSort graph where { graph' = revGraph graph; collectSccPreorder :: [Int] -> [[Int]]; collectSccPreorder !topVerts = runST $ do { let { !bounds_ = bounds graph'}; !vis <- VUM.replicate (succ $ rangeSize bounds_) False; filter (not . null) <$> mapM (topScc1 graph' vis) topVerts}};topSccCycles :: Array Int [Int] -> [[Int]];topSccCycles graph = filter f $ topScc graph where { f [!v] = [v] == graph ! v; f !_ = True};downScc :: Array Int [Int] -> [[Int]];downScc = reverse . map reverse . topScc;data IxVector i v = IxVector{boundsIV :: !(i, i), vecIV :: !v} deriving (Show, Eq);(@!) :: (Ix i, VG.Vector v a) => IxVector i (v a) -> i -> a;(@!) IxVector{..} i = vecIV VG.! index boundsIV i;(@!?) :: (Ix i, VG.Vector v a) => IxVector i (v a) -> i -> Maybe a;(@!?) IxVector{..} i | inRange boundsIV i = Just (vecIV VG.! (index boundsIV i)) | otherwise = Nothing;{-# INLINE readIV #-};readIV :: (Ix i, PrimMonad m, VGM.MVector v a) => IxVector i (v (PrimState m) a) -> i -> m a;readIV IxVector{..} i = VGM.read vecIV (index boundsIV i);{-# INLINE writeIV #-};writeIV :: (Ix i, PrimMonad m, VGM.MVector v a) => IxVector i (v (PrimState m) a) -> i -> a -> m ();writeIV IxVector{..} i a = VGM.write vecIV (index boundsIV i) a;{-# INLINE modifyIV #-};modifyIV :: (Ix i, PrimMonad m, VGM.MVector v a) => IxVector i (v (PrimState m) a) -> (a -> a) -> i -> m ();modifyIV IxVector{..} !alter i = VGM.modify vecIV alter (index boundsIV i);{-# INLINE swapIV #-};swapIV :: (Ix i, PrimMonad m, VGM.MVector v a) => IxVector i (v (PrimState m) a) -> i -> i -> m ();swapIV IxVector{..} !i1 !i2 = VGM.swap vecIV (index boundsIV i1) (index boundsIV i2);imos2DIV :: IxVector (Int, Int) (VU.Vector Int) -> IxVector (Int, Int) (VU.Vector Int);imos2DIV !seeds@IxVector{boundsIV} = IxVector boundsIV $ VU.create $ do { !vec <- IxVector boundsIV <$> VU.thaw (vecIV seeds); let { (!minY, !minX) = fst boundsIV}; forM_ (range boundsIV) $ \ (!y, !x) -> do { !v <- if x == minX then return 0 else readIV vec (y, x - 1); modifyIV vec (+ v) (y, x)}; forM_ (range boundsIV) $ \ (!x, !y) -> do { !v <- if y == minY then return 0 else readIV vec (y - 1, x); modifyIV vec (+ v) (y, x)}; return $ vecIV vec};class SemigroupAction s a where { sact :: s -> a -> a};class (SemigroupAction m a, Monoid m) => MonoidAction m a where { mact :: m -> a -> a; mact = sact};instance SemigroupAction (Product Int) Int where { sact (Product !x1) !x2 = x1 * x2};newtype Permutation = Permutation (VU.Vector Int) deriving (Show, Eq);instance Semigroup Permutation where { (Permutation vec1) <> (Permutation vec2) = Permutation $! VU.map (vec1 VU.!) vec2 where { !_ = dbgAssert (VG.length vec1 == VG.length vec2)}};instance SemigroupAction Permutation Int where { sact (Permutation !vec) !i = vec VU.! i};powersetM_ :: (Bits a, Num a, Monad m) => a -> (a -> m ()) -> m ();powersetM_ !is0 !act = act2 is0 where { act2 !is = do { act is; unless (is == 0) (act2 (is0 .&. (is - 1)))}};powerset :: (Bits a, Num a) => a -> [a];powerset !a = a : unfoldr f a where { f 0 = Nothing; f !x = Just . dupe $! a .&. (x - 1)};powersetVU :: (Bits a, Num a, VU.Unbox a) => a -> VU.Vector a;powersetVU !a = VU.unfoldr f a where { f (-1) = Nothing; f 0 = Just (0, -1); f !x = let { !x' = a .&. (x - 1)} in Just (x, x')};type MultiSet = (Int, IM.IntMap Int);emptyMS :: MultiSet;emptyMS = (0, IM.empty);singletonMS :: Int -> MultiSet;singletonMS !x = (1, IM.singleton x 1);fromListMS :: [Int] -> MultiSet;fromListMS = foldl' (flip incMS) emptyMS;incMS :: Int -> MultiSet -> MultiSet;incMS !k (!n, !im) = if IM.member k im then (n, IM.insertWith (+) k 1 im) else (n + 1, IM.insert k 1 im);decMS :: Int -> MultiSet -> MultiSet;decMS !k (!n, !im) = case IM.lookup k im of { Just 1 -> (n - 1, IM.delete k im); Just _ -> (n, IM.insertWith (+) k (-1) im); Nothing -> (n, im)};memberMS :: Int -> MultiSet -> Bool;memberMS !k (!_, !im) = IM.member k im;notMemberMS :: Int -> MultiSet -> Bool;notMemberMS !k (!_, !im) = IM.notMember k im;deleteFindMinMS :: MultiSet -> (Int, MultiSet);deleteFindMinMS ms@(!_, !im) = let { !key = fst $ IM.findMin im} in (key, decMS key ms);innerMS :: MultiSet -> IM.IntMap Int;innerMS (!_, !im) = im;data Buffer s a = Buffer{bufferVars :: !(VUM.MVector s Int), internalBuffer :: !(VUM.MVector s a), internalBufferSize :: !Int};_bufferFrontPos :: Int;_bufferFrontPos = 0;_bufferBackPos :: Int;_bufferBackPos = 1;newBuffer :: (VU.Unbox a, PrimMonad m) => Int -> m (Buffer (PrimState m) a);newBuffer n = Buffer <$> VUM.replicate 2 0 <*> VUM.unsafeNew n <*> pure n;type Stack s a = Buffer s a;newBufferAsStack :: (VU.Unbox a, PrimMonad m) => Int -> m (Buffer (PrimState m) a);newBufferAsStack n = Buffer <$> VUM.replicate 2 0 <*> VUM.unsafeNew n <*> pure n;type Queue s a = Buffer s a;newBufferAsQueue :: (VU.Unbox a, PrimMonad m) => Int -> m (Buffer (PrimState m) a);newBufferAsQueue n = Buffer <$> VUM.replicate 2 0 <*> VUM.unsafeNew n <*> pure n;type Deque s a = Buffer s a;newBufferAsDeque :: (VU.Unbox a, PrimMonad m) => Int -> m (Buffer (PrimState m) a);newBufferAsDeque n = Buffer <$> VUM.replicate 2 n <*> VUM.unsafeNew (2 * n) <*> pure (2 * n);lengthBuffer :: (PrimMonad m) => Buffer (PrimState m) a -> m Int;lengthBuffer Buffer{bufferVars} = liftA2 (-) (VUM.unsafeRead bufferVars _bufferBackPos) (VUM.unsafeRead bufferVars _bufferFrontPos);{-# INLINE lengthBuffer #-};clearBuffer :: (PrimMonad m) => Buffer (PrimState m) a -> m ();clearBuffer Buffer{bufferVars} = do { VUM.unsafeWrite bufferVars _bufferFrontPos 0; VUM.unsafeWrite bufferVars _bufferBackPos 0};freezeBuffer :: (VU.Unbox a, PrimMonad m) => Buffer (PrimState m) a -> m (VU.Vector a);freezeBuffer Buffer{bufferVars, internalBuffer} = do { f <- VUM.unsafeRead bufferVars _bufferFrontPos; b <- VUM.unsafeRead bufferVars _bufferBackPos; VU.freeze $ VUM.unsafeSlice f (b - f) internalBuffer};unsafeFreezeBuffer :: (VU.Unbox a, PrimMonad m) => Buffer (PrimState m) a -> m (VU.Vector a);unsafeFreezeBuffer Buffer{bufferVars, internalBuffer} = do { f <- VUM.unsafeRead bufferVars _bufferFrontPos; b <- VUM.unsafeRead bufferVars _bufferBackPos; VU.unsafeFreeze $ VUM.unsafeSlice f (b - f) internalBuffer};freezeInternalBuffer :: (VU.Unbox a, PrimMonad m) => Buffer (PrimState m) a -> m (VU.Vector a);freezeInternalBuffer Buffer{bufferVars, internalBuffer} = do { b <- VUM.unsafeRead bufferVars _bufferBackPos; VU.freeze $ VUM.unsafeSlice 0 b internalBuffer};unsafeFreezeInternalBuffer :: (VU.Unbox a, PrimMonad m) => Buffer (PrimState m) a -> m (VU.Vector a);unsafeFreezeInternalBuffer Buffer{bufferVars, internalBuffer} = do { b <- VUM.unsafeRead bufferVars _bufferBackPos; VU.unsafeFreeze $ VUM.unsafeSlice 0 b internalBuffer};popFront :: (VU.Unbox a, PrimMonad m) => Buffer (PrimState m) a -> m (Maybe a);popFront Buffer{bufferVars, internalBuffer} = do { f <- VUM.unsafeRead bufferVars _bufferFrontPos; b <- VUM.unsafeRead bufferVars _bufferBackPos; if f < b then do { VUM.unsafeWrite bufferVars _bufferFrontPos (f + 1); pure <$> VUM.unsafeRead internalBuffer f} else return Nothing};{-# INLINE popFront #-};viewFront :: (VU.Unbox a, PrimMonad m) => Buffer (PrimState m) a -> m (Maybe a);viewFront Buffer{bufferVars, internalBuffer} = do { f <- VUM.unsafeRead bufferVars _bufferFrontPos; b <- VUM.unsafeRead bufferVars _bufferBackPos; if f < b then pure <$> VUM.unsafeRead internalBuffer f else return Nothing};{-# INLINE viewFront #-};popBack :: (VU.Unbox a, PrimMonad m) => Buffer (PrimState m) a -> m (Maybe a);popBack Buffer{bufferVars, internalBuffer} = do { f <- VUM.unsafeRead bufferVars _bufferFrontPos; b <- VUM.unsafeRead bufferVars _bufferBackPos; if f < b then do { VUM.unsafeWrite bufferVars _bufferBackPos (b - 1); pure <$> VUM.unsafeRead internalBuffer (b - 1)} else return Nothing};{-# INLINE popBack #-};viewBack :: (VU.Unbox a, PrimMonad m) => Buffer (PrimState m) a -> m (Maybe a);viewBack Buffer{bufferVars, internalBuffer} = do { f <- VUM.unsafeRead bufferVars _bufferFrontPos; b <- VUM.unsafeRead bufferVars _bufferBackPos; if f < b then pure <$> VUM.unsafeRead internalBuffer (b - 1) else return Nothing};{-# INLINE viewBack #-};pushFront :: (VU.Unbox a, PrimMonad m) => a -> Buffer (PrimState m) a -> m ();pushFront x Buffer{bufferVars, internalBuffer} = do { f <- VUM.unsafeRead bufferVars _bufferFrontPos; VUM.unsafeWrite bufferVars _bufferFrontPos (f - 1); assert (f > 0) $ do { VUM.unsafeWrite internalBuffer (f - 1) x}};{-# INLINE pushFront #-};pushBack :: (VU.Unbox a, PrimMonad m) => a -> Buffer (PrimState m) a -> m ();pushBack x Buffer{bufferVars, internalBuffer, internalBufferSize} = do { b <- VUM.unsafeRead bufferVars _bufferBackPos; VUM.unsafeWrite bufferVars _bufferBackPos (b + 1); assert (b < internalBufferSize) $ do { VUM.unsafeWrite internalBuffer b x}};{-# INLINE pushBack #-};pushFronts :: (VU.Unbox a, PrimMonad m) => VU.Vector a -> Buffer (PrimState m) a -> m ();pushFronts vec Buffer{bufferVars, internalBuffer} = do { let { n = VU.length vec}; f <- VUM.unsafeRead bufferVars _bufferFrontPos; VUM.unsafeWrite bufferVars _bufferFrontPos (f - n); assert (n <= f) $ do { VU.unsafeCopy (VUM.unsafeSlice (f - n) n internalBuffer) vec}};{-# INLINE pushFronts #-};pushBacks :: (VU.Unbox a, PrimMonad m) => VU.Vector a -> Buffer (PrimState m) a -> m ();pushBacks vec Buffer{bufferVars, internalBuffer, internalBufferSize} = do { let { n = VU.length vec}; b <- VUM.unsafeRead bufferVars _bufferBackPos; VUM.unsafeWrite bufferVars _bufferBackPos (b + n); assert (b + n - 1 < internalBufferSize) $ do { VU.unsafeCopy (VUM.unsafeSlice b n internalBuffer) vec}};{-# INLINE pushBacks #-};class ShowGrid a where { showGrid :: a -> String};instance (VG.Vector v a, Show a) => ShowGrid (IxVector (Int, Int) (v a)) where { showGrid !grid = unlines $ map f [y0 .. y1] where { ((!y0, !x0), (!y1, !x1)) = boundsIV grid; f !y = unwords $ map (show . (grid @!) . (y,)) [x0 .. x1]}};clamp :: (Ord a) => (a, a) -> a -> a;clamp (!low, !high) !a = min high (max a low);flipOrder :: Ordering -> Ordering;flipOrder = \case { GT -> LT; LT -> GT; EQ -> EQ};square :: Num a => a -> a;square !x = x * x;chunks :: Int -> [a] -> [[a]];chunks n = inner where { inner [] = []; inner xs = let { (!g, !rest) = splitAt n xs} in g : inner rest};(.:) :: (b -> c) -> (a1 -> a2 -> b) -> (a1 -> a2 -> c);(.:) = (.) . (.);(.:.) :: (b -> c) -> (a1 -> a2 -> a3 -> b) -> (a1 -> a2 -> a3 -> c);(.:.) = (.) . (.) . (.);{-# INLINE (.!) #-};(.!) :: (b -> c) -> (a -> b) -> a -> c;(.!) = (.) . ($!);infixr 9 .!;foldFor :: (Foldable t) => b -> t a -> (b -> a -> b) -> b;foldFor !s0 !xs !f = foldl' f s0 xs;foldForVG :: (VG.Vector v a) => b -> v a -> (b -> a -> b) -> b;foldForVG !s0 !xs !f = VG.foldl' f s0 xs;foldForM :: (Foldable t, Monad m) => b -> t a -> (b -> a -> m b) -> m b;foldForM !s0 !xs !m = foldM m s0 xs;foldForMVG :: (PrimMonad m, VG.Vector v a) => b -> v a -> (b -> a -> m b) -> m b;foldForMVG !s0 !xs !m = VG.foldM' m s0 xs;foldForMMS :: Monad m => a -> MS.Stream m b -> (a -> b -> m a) -> m a;foldForMMS !s0 !xs !f = MS.foldM' f s0 xs;minimumOr :: (Ord a, VU.Unbox a) => a -> VU.Vector a -> a;minimumOr !orValue !xs = if VU.null xs then orValue else VU.minimum xs;maximumOr :: (Ord a, VU.Unbox a) => a -> VU.Vector a -> a;maximumOr !orValue !xs = if VU.null xs then orValue else VU.maximum xs;{-# INLINE unconsVG #-};unconsVG :: VG.Vector v a => v a -> Maybe (a, v a);unconsVG v | VG.null v = Nothing | otherwise = Just (VG.unsafeHead v, VG.unsafeTail v);{-# INLINE groupByVG #-};groupByVG :: (VG.Vector v a) => (a -> a -> Bool) -> v a -> [v a];groupByVG _ !v | VG.null v = []; groupByVG !f !v = let { !h = VG.unsafeHead v; !tl = VG.unsafeTail v} in case VG.findIndex (not . f h) tl of { Nothing -> [v]; Just !n -> VG.unsafeTake (n + 1) v : groupByVG f (VG.unsafeDrop (n + 1) v)};{-# INLINE groupVG #-};groupVG :: (VG.Vector v a, Eq a) => v a -> [v a];groupVG = groupByVG (==);safeHead :: (VU.Unbox a) => VU.Vector a -> Maybe a;safeHead vec = if VU.null vec then Nothing else Just $! VU.head vec;safeLast :: (VU.Unbox a) => VU.Vector a -> Maybe a;safeLast vec = if VU.null vec then Nothing else Just $! VU.last vec;{-# INLINE modifyArray #-};modifyArray :: (MArray a e m, Ix i) => a i e -> (e -> e) -> i -> m ();modifyArray !ary !f !i = do { !v <- f <$> readArray ary i; writeArray ary i v};{-# INLINE vLength #-};vLength :: (VG.Vector v e) => v e -> Int;vLength = VFB.length . VG.stream;{-# INLINE rangeVG #-};rangeVG :: (VG.Vector v Int) => Int -> Int -> v Int;rangeVG !i !j = VG.enumFromN i (succ j - i);{-# INLINE rangeV #-};rangeV :: Int -> Int -> V.Vector Int;rangeV = rangeVG;{-# INLINE rangeVU #-};rangeVU :: Int -> Int -> VU.Vector Int;rangeVU = rangeVG;{-# INLINE rangeVGR #-};rangeVGR :: (VG.Vector v Int) => Int -> Int -> v Int;rangeVGR !i !j = VG.enumFromStepN (pred j) (-1) (succ j - i);{-# INLINE rangeVR #-};rangeVR :: Int -> Int -> V.Vector Int;rangeVR = rangeVGR;{-# INLINE rangeVUR #-};rangeVUR :: Int -> Int -> VU.Vector Int;rangeVUR = rangeVGR;{-# INLINE [1] rangeMS #-};rangeMS :: (Monad m) => Int -> Int -> MS.Stream m Int;rangeMS !l !r = MS.Stream step l where { {-# INLINE [0] step #-}; step x | x <= r = return $ MS.Yield x (x + 1) | otherwise = return MS.Done};{-# INLINE [1] rangeMSR #-};rangeMSR :: (Monad m) => Int -> Int -> MS.Stream m Int;rangeMSR !l !r = MS.Stream step r where { {-# INLINE [0] step #-}; step x | x >= l = return $ MS.Yield x (x - 1) | otherwise = return MS.Done};{-# INLINE forMS_ #-};forMS_ :: (Monad m) => MS.Stream m Int -> (Int -> m ()) -> m ();forMS_ = flip MS.mapM_;{-# INLINE repM_ #-};repM_ :: Monad m => Int -> Int -> (Int -> m ()) -> m ();repM_ !l !r !act = inner l where { inner !i | i > r = return () | otherwise = act i >> inner (succ i)};{-# INLINE repRM_ #-};repRM_ :: Monad m => Int -> Int -> (Int -> m ()) -> m ();repRM_ !l !r !act = inner r where { inner !i | i < l = return () | otherwise = act i >> inner (pred i)};constructN0 :: (VU.Unbox a) => a -> Int -> (VU.Vector a -> a) -> VU.Vector a;constructN0 !x0 !n !f = VU.constructN n $ \ vec -> if VU.null vec then x0 else f vec;compress :: Eq a => [a] -> [a];compress [] = []; compress (x : xs) = x : compress (dropWhile (== x) xs);{-# INLINE times #-};times :: Int -> (a -> a) -> a -> a;times !n !f !s0 = snd $! until ((== n) . fst) (bimap succ f) (0 :: Int, s0);combs :: Int -> [a] -> [[a]];combs _ [] = error "given empty list"; combs k as@(!(x : xs)) | k == 0 = [[]] | k == 1 = map pure as | k == l = pure as | k > l = [] | otherwise = run (l - 1) (k - 1) as $ combs (k - 1) xs where { l = length as; run :: Int -> Int -> [a] -> [[a]] -> [[a]]; run n k ys cs | n == k = map (ys ++) cs | otherwise = map (q :) cs ++ run (n - 1) k qs (drop dc cs) where { (!(q : qs)) = take (n - k + 1) ys; dc = product [(n - k + 1) .. (n - 1)] `div` product [1 .. (k - 1)]}};twoPointers :: Int -> ((Int, Int) -> Bool) -> [(Int, Int)];twoPointers !n !check = inner (0, 0) where { inner (!l, !_) | l >= n = []; inner (!l, !r) | check (l, r) = let { (!l', !r') = until (not . peekCheck) (second succ) (l, r)} in (l', r') : inner (succ l', max l' r') | otherwise = inner (succ l, max (succ l) r); peekCheck (!_, !r) | r == pred n = False; peekCheck (!l, !r) = check (l, succ r)};tuple2 :: [a] -> (a, a);tuple2 [!a1, !a2] = (a1, a2); tuple2 _ = error "not a two-item list";tuple3 :: [a] -> (a, a, a);tuple3 [!a1, !a2, !a3] = (a1, a2, a3); tuple3 _ = error "not a three-item list";tuple4 :: [a] -> (a, a, a, a);tuple4 [!a1, !a2, !a3, !a4] = (a1, a2, a3, a4); tuple4 _ = error "not a four-item list";tuple5 :: [a] -> (a, a, a, a, a);tuple5 [!a1, !a2, !a3, !a4, !a5] = (a1, a2, a3, a4, a5); tuple5 _ = error "not a five-item list";tuple6 :: [a] -> (a, a, a, a, a, a);tuple6 [!a1, !a2, !a3, !a4, !a5, !a6] = (a1, a2, a3, a4, a5, a6); tuple6 _ = error "not a six-item list";ints2 :: IO (Int, Int);ints2 = tuple2 <$> ints;ints3 :: IO (Int, Int, Int);ints3 = tuple3 <$> ints;ints4 :: IO (Int, Int, Int, Int);ints4 = tuple4 <$> ints;ints5 :: IO (Int, Int, Int, Int, Int);ints5 = tuple5 <$> ints;ints6 :: IO (Int, Int, Int, Int, Int, Int);ints6 = tuple6 <$> ints;yn :: Bool -> String;yn b = if b then "Yes" else "No";printYn :: Bool -> IO ();printYn = putStrLn . yn;concat2 :: [(a, a)] -> [a];concat2 [] = []; concat2 ((!x, !y) : xys) = x : y : concat2 xys;concatMap2 :: (a -> (b, b)) -> [a] -> [b];concatMap2 !f = concat2 . map f;swapDupe :: (a, a) -> ((a, a), (a, a));swapDupe = second swap . dupe;add2 :: (Int, Int) -> (Int, Int) -> (Int, Int);add2 (!y, !x) = bimap (y +) (x +);sub2 :: (Int, Int) -> (Int, Int) -> (Int, Int);sub2 (!y, !x) = bimap (y -) (x -);mul2 :: Int -> (Int, Int) -> (Int, Int);mul2 !m = both (m *);add3 :: (Int, Int, Int) -> (Int, Int, Int) -> (Int, Int, Int);add3 (!z1, !y1, !x1) (!z2, !y2, !x2) = (z1 + z2, y1 + y2, x1 + x2);sub3 :: (Int, Int, Int) -> (Int, Int, Int) -> (Int, Int, Int);sub3 (!z1, !y1, !x1) (!z2, !y2, !x2) = (z1 - z2, y1 - y2, x1 - x2);mul3 :: (Int, Int, Int) -> (Int, Int, Int) -> (Int, Int, Int);mul3 (!z1, !y1, !x1) (!z2, !y2, !x2) = (z1 - z2, y1 - y2, x1 - x2);toRadian :: Double -> Double;toRadian degree = degree / 180.0 * pi;toDegree :: Double -> Double;toDegree rad = rad / pi * 180.0;fst4 :: (a, b, c, d) -> a;fst4 (!a, !_, !_, !_) = a;snd4 :: (a, b, c, d) -> b;snd4 (!_, !b, !_, !_) = b;thd4 :: (a, b, c, d) -> c;thd4 (!_, !_, !c, !_) = c;fth4 :: (a, b, c, d) -> d;fth4 (!_, !_, !_, !d) = d;int :: IO Int;int = readLn;ints :: IO [Int];ints = unfoldr (BS.readInt . BS.dropWhile isSpace) <$> BS.getLine;intsVG :: VG.Vector v Int => IO (v Int);intsVG = VG.unfoldr (BS.readInt . BS.dropWhile isSpace) <$> BS.getLine;intsV :: IO (V.Vector Int);intsV = intsVG;intsVU :: IO (VU.Vector Int);intsVU = intsVG;digitsVU :: IO (VU.Vector Int);digitsVU = VU.unfoldr (fmap (first digitToInt) . BS.uncons) <$> BS.getLine;intsN :: Int -> IO [Int];intsN n = concat <$> replicateM n ints;intsNVU :: Int -> IO (VU.Vector Int);intsNVU n = VU.fromList . concat <$> replicateM n ints;intsGrid :: Int -> Int -> IO (IxVector (Int, Int) (VU.Vector Int));intsGrid h w = IxVector ((0, 0), (h - 1, w - 1)) <$> intsNVU h;intsRestVG :: VG.Vector v Int => IO (v Int);intsRestVG = VG.unfoldr (BS.readInt . BS.dropWhile isSpace) <$> BS.getContents;intsRestVU :: IO (VU.Vector Int);intsRestVU = intsRestVG;getGraph :: Int -> Int -> IO (Array Int [Int]);getGraph !nVerts !nEdges = accGraph . toInput <$> replicateM nEdges ints where { accGraph = accumArray @Array (flip (:)) [] (1, nVerts); toInput = concatMap2 $ second swap . dupe . tuple2};getWGraph :: Int -> Int -> IO (Array Int [H.Entry Int Int]);getWGraph !nVerts !nEdges = accGraph . toInput <$> replicateM nEdges ints where { accGraph = accumArray @Array (flip (:)) [] (1, nVerts); toInput = concatMap2 $ \ [!a, !b, !cost] -> ((a, H.Entry cost b), (b, H.Entry cost a))};getWGraph0 :: Int -> Int -> IO (Array Int [H.Entry Int Int]);getWGraph0 !nVerts !nEdges = accGraph . toInput <$> replicateM nEdges ints where { accGraph = accumArray @Array (flip (:)) [] (0, pred nVerts); toInput = concatMap2 $ \ [!a, !b, !cost] -> ((pred a, H.Entry cost (pred b)), (pred b, H.Entry cost (pred a)))};{-# INLINE endlBSB #-};endlBSB :: BSB.Builder;endlBSB = BSB.char7 '\n';putBSB :: BSB.Builder -> IO ();putBSB = BSB.hPutBuilder stdout;putLnBSB :: BSB.Builder -> IO ();putLnBSB = BSB.hPutBuilder stdout . (<> endlBSB);class ShowBSB a where { showBSB :: a -> BSB.Builder; default showBSB :: (Show a) => a -> BSB.Builder; showBSB = BSB.string8 . show};instance ShowBSB Int where { showBSB = BSB.intDec};instance ShowBSB Integer where { showBSB = BSB.integerDec};instance ShowBSB Float where { showBSB = BSB.floatDec};instance ShowBSB Double where { showBSB = BSB.doubleDec};showLnBSB :: ShowBSB a => a -> BSB.Builder;showLnBSB = (<> endlBSB) . showBSB;printBSB :: ShowBSB a => a -> IO ();printBSB = putBSB . showBSB;concatBSB :: (VG.Vector v a) => (a -> BSB.Builder) -> v a -> BSB.Builder;concatBSB f = VG.foldr' ((<>) . f) mempty;unwordsBSB :: (ShowBSB a, VG.Vector v a) => v a -> BSB.Builder;unwordsBSB = concatBSB ((<> BSB.string7 " ") . showBSB);unlinesBSB :: (ShowBSB a, VG.Vector v a) => v a -> BSB.Builder;unlinesBSB = concatBSB showLnBSB;traceMat2D :: (IArray a e, Ix i, Show e) => a (i, i) e -> ();traceMat2D !mat = traceSubMat2D mat (bounds mat);traceSubMat2D :: (IArray a e, Ix i, Show e) => a (i, i) e -> ((i, i), (i, i)) -> ();traceSubMat2D !mat ((!y0, !x0), (!yEnd, !xEnd)) = let { !_ = foldl' step () (range ys)} in () where { !xs = (y0, yEnd); !ys = (x0, xEnd); step !_ !y = traceShow (map (\ !x -> mat ! (y, x)) (range xs)) ()};isqrt :: Int -> Int;isqrt = round @Double . sqrt . fromIntegral;data LazySegmentTree v a op s = LazySegmentTree !(v s a) !(VUM.MVector s op) !Int;newLazySTree :: forall v a op m . (VGM.MVector v a, Monoid a, MonoidAction op a, VU.Unbox op, PrimMonad m) => Int -> m (LazySegmentTree v a op (PrimState m));newLazySTree !n = do { !as <- VGM.replicate n2 mempty; !ops <- VUM.replicate n2 mempty; return $ LazySegmentTree as ops h} where { (!h, !n2) = until ((>= 2 * n) . snd) (bimap succ (* 2)) (0 :: Int, 1 :: Int)};newLazySTreeV :: forall a op m . (Monoid a, MonoidAction op a, VU.Unbox op, PrimMonad m) => Int -> m (LazySegmentTree VM.MVector a op (PrimState m));newLazySTreeV = newLazySTree;newLazySTreeVU :: forall a op m . (VU.Unbox a, Monoid a, MonoidAction op a, VU.Unbox op, PrimMonad m) => Int -> m (LazySegmentTree VUM.MVector a op (PrimState m));newLazySTreeVU = newLazySTree;generateLazySTree :: forall v a op m . (VGM.MVector v a, Monoid a, MonoidAction op a, VU.Unbox op, PrimMonad m) => Int -> (Int -> a) -> m (LazySegmentTree v a op (PrimState m));generateLazySTree !n !f = do { !as <- VGM.unsafeNew n2; forMS_ (rangeMS 1 nLeaves) $ \ i -> do { VGM.write as (nLeaves + i - 1) $ f (pred i)}; forMS_ (rangeMSR 1 (pred nLeaves)) $ \ i -> do { !l <- VGM.read as (childL i); !r <- VGM.read as (childR i); VGM.write as i (l <> r)}; !ops <- VUM.replicate n2 mempty; return $ LazySegmentTree as ops h} where { (!h, !n2) = until ((>= 2 * n) . snd) (bimap succ (* 2)) (0 :: Int, 1 :: Int); !nLeaves = n2 `div` 2; childL !vertex = shiftL vertex 1; childR !vertex = shiftL vertex 1 .|. 1};generateLazySTreeV :: forall a op m . (Monoid a, MonoidAction op a, VU.Unbox op, PrimMonad m) => Int -> (Int -> a) -> m (LazySegmentTree VM.MVector a op (PrimState m));generateLazySTreeV = generateLazySTree;generateLazySTreeVU :: forall a op m . (VU.Unbox a, Monoid a, MonoidAction op a, VU.Unbox op, PrimMonad m) => Int -> (Int -> a) -> m (LazySegmentTree VUM.MVector a op (PrimState m));generateLazySTreeVU = generateLazySTree;updateLazySTree :: forall v a op m . (VGM.MVector v a, Monoid a, MonoidAction op a, Eq op, VU.Unbox op, PrimMonad m) => LazySegmentTree v a op (PrimState m) -> Int -> Int -> op -> m ();updateLazySTree stree@(LazySegmentTree !_ !ops !_) !iLLeaf !iRLeaf !op = do { _propOpMonoidsToLeaf stree iLLeaf; _propOpMonoidsToLeaf stree iRLeaf; let { !lVertex = iLLeaf + nVerts `div` 2; !rVertex = iRLeaf + nVerts `div` 2}; glitchLoopUpdate lVertex rVertex; _evalToRoot stree iLLeaf; _evalToRoot stree iRLeaf; return ()} where { !nVerts = VUM.length ops; isLeftChild = not . (`testBit` 0); isRightChild = (`testBit` 0); glitchLoopUpdate :: Int -> Int -> m (); glitchLoopUpdate !l !r | l > r = return () | otherwise = do { !l' <- if isRightChild l then do { VUM.modify ops (<> op) l; return $ succ l} else return l; !r' <- if isLeftChild r then do { VUM.modify ops (<> op) r; return $ pred r} else return r; glitchLoopUpdate (shiftR l' 1) (shiftR r' 1)}};queryLazySTree :: forall v a m op . (VGM.MVector v a, Monoid a, MonoidAction op a, Eq op, VU.Unbox op, PrimMonad m) => LazySegmentTree v a op (PrimState m) -> Int -> Int -> m a;queryLazySTree stree@(LazySegmentTree !as !ops !_) !iLLeaf !iRLeaf = do { _propOpMonoidsToLeaf stree iLLeaf; _propOpMonoidsToLeaf stree iRLeaf; let { !lVertex = iLLeaf + nVerts `div` 2; !rVertex = iRLeaf + nVerts `div` 2}; glitchLoopQuery lVertex rVertex mempty mempty} where { !nVerts = VGM.length as; isLeftChild = not . (`testBit` 0); isRightChild = (`testBit` 0); glitchLoopQuery :: Int -> Int -> a -> a -> m a; glitchLoopQuery !l !r !lAcc !rAcc | l > r = return $! lAcc <> rAcc | otherwise = do { (!l', !lAcc') <- if isRightChild l then do { !la' <- mact <$!> VUM.read ops l <*> VGM.read as l; return (succ l, lAcc <> la')} else return (l, lAcc); (!r', !rAcc') <- if isLeftChild r then do { !ra' <- mact <$!> VUM.read ops r <*> VGM.read as r; return (pred r, ra' <> rAcc)} else return (r, rAcc); glitchLoopQuery (shiftR l' 1) (shiftR r' 1) lAcc' rAcc'}};_propOpMonoidsToLeaf :: (VGM.MVector v a, MonoidAction op a, Eq op, VU.Unbox op, PrimMonad m) => LazySegmentTree v a op (PrimState m) -> Int -> m ();_propOpMonoidsToLeaf (LazySegmentTree !as !ops !height) !iLeaf = do { let { !leafVertex = iLeaf + nVerts `div` 2}; forMS_ (rangeMSR 1 (pred height)) $ \ iParent -> do { let { !vertex = nthParent leafVertex iParent}; !op <- VUM.read ops vertex; when (op /= mempty) $ do { VUM.modify ops (<> op) $! childL vertex; VUM.modify ops (<> op) $! childR vertex; VGM.modify as (mact op) vertex; VUM.write ops vertex mempty}}} where { !nVerts = VGM.length as; nthParent !leafVertex !nth = shiftR leafVertex nth; childL !vertex = shiftL vertex 1; childR !vertex = shiftL vertex 1 .|. 1};_evalToRoot :: (VGM.MVector v a, Monoid a, MonoidAction op a, VU.Unbox op, PrimMonad m) => LazySegmentTree v a op (PrimState m) -> Int -> m ();_evalToRoot (LazySegmentTree !as !ops !height) !iLeaf = do { let { !leafVertex = iLeaf + nVerts `div` 2}; forMS_ (rangeMS 1 (pred height)) $ \ iParent -> do { let { !vertex = nthParent leafVertex iParent}; let { !_ = dbgAssert (vertex > 0) "_evalToRoot"}; !aL' <- mact <$> VUM.read ops (childL vertex) <*> VGM.read as (childL vertex); !aR' <- mact <$> VUM.read ops (childR vertex) <*> VGM.read as (childR vertex); VGM.write as vertex $! aL' <> aR'}} where { !nVerts = VGM.length as; nthParent !leafVertex !nth = shiftR leafVertex nth; childL !vertex = shiftL vertex 1; childR !vertex = shiftL vertex 1 .|. 1};type Graph a = Array Int [a];type Vertex = Int;type WGraph a = Array Int [H.Entry a Vertex];bfsVec :: Graph Int -> Int -> VU.Vector Int;bfsVec graph start = VU.create $ do { let { !undef = -1 :: Int}; !vis <- VUM.replicate (rangeSize $ bounds graph) undef; let { inner !depth !vs | IS.null vs = return () | otherwise = do { let { vs' = IS.toList vs}; forM_ vs' $ \ v -> do { VUM.unsafeWrite vis v depth}; !next <- fmap (IS.fromList . concat) $ forM vs' $ \ v -> do { filterM (fmap (== undef) . VUM.unsafeRead vis) $ graph ! v}; inner (succ depth) next}}; !_ <- inner (0 :: Int) (IS.singleton start); return vis};bfsPath :: Graph Int -> Int -> Int -> Maybe Int;bfsPath !graph !start !end = inner (-1) IS.empty (IS.singleton start) where { inner :: Int -> IS.IntSet -> IS.IntSet -> Maybe Int; inner !depth !vis !vs | IS.member end vis = Just depth | IS.null vs = Nothing | otherwise = inner (succ depth) vis' vs' where { vis' = vis `IS.union` vs; vs' = IS.fromList $! filter (`IS.notMember` vis') $! concatMap (graph !) (IS.toList vs)}};bfsVerts :: Graph Int -> Int -> IM.IntMap Int;bfsVerts graph start = inner 0 IM.empty (IS.singleton start) where { inner :: Int -> IM.IntMap Int -> IS.IntSet -> IM.IntMap Int; inner !depth !vis !vs | IS.null vs = vis | otherwise = inner (succ depth) vis' vs' where { vis' = IM.union vis $! IM.fromSet (const depth) vs; vs' = IS.fromList $! filter (`IM.notMember` vis') $! concatMap (graph !) (IS.toList vs)}};bfsGrid :: UArray (Int, Int) Char -> (Int, Int) -> UArray (Int, Int) Int;bfsGrid !grid !start = runSTUArray $ do { let { !bounds_ = bounds grid}; let { (!_, !w) = both succ $! snd bounds_}; let { isBlock !yx = grid ! yx == '#'}; let { ix = index bounds_}; let { unIndex !i = i `divMod` w}; let { !undef = -1 :: Int}; !vis <- newArray bounds_ undef; let { nexts !yx0 = filter (\ yx -> inRange bounds_ yx && not (isBlock yx)) $! map (add2 yx0) dyxs where { dyxs = [(1, 0), (-1, 0), (0, 1), (0, -1)]}}; let { inner !depth !vs | IS.null vs = return () | otherwise = do { let { yxs = map unIndex $! IS.toList vs}; forM_ yxs $ \ yx -> do { writeArray vis yx depth}; !vss <- forM yxs $ \ yx -> do { filterM (fmap (== undef) . readArray vis) $ nexts yx}; inner (succ depth) $! IS.fromList . map ix $! concat vss}}; !_ <- inner (0 :: Int) (IS.singleton $ ix start); return vis};solve01BFS :: (Int, Int) -> UArray (Int, Int) Char -> UArray (Int, Int) Int;solve01BFS !start !grid = runSTUArray $ do { !dp <- newArray (bounds grid) undef; let { popLoop Seq.Empty = return (); popLoop ((!v1, !d1) Seq.:<| seq0) = do { !lastD <- readArray dp v1; if lastD /= undef then popLoop seq0 else do { writeArray dp v1 d1; popLoop <=< foldForM seq0 (grid `adjW` v1) $ \ seq (!v2, !w2) -> do { !d2 <- readArray dp v2; if d2 /= undef then return seq else do { if w2 == 0 then return ((v2, d1) Seq.<| seq) else return (seq Seq.|> (v2, succ d1))}}}}}; popLoop $ Seq.singleton (start, 0 :: Int); return dp} where { !undef = -1 :: Int; adjW :: UArray (Int, Int) Char -> (Int, Int) -> [((Int, Int), Int)]; adjW !grid !yx0 = let { !adjs1 = map (, 0 :: Int) $ filter ((&&) <$> inRange (bounds grid) <*> ((== '.') . (grid !))) $ map (add2 yx0) dir4; !adjs2 = map (, 1 :: Int) $ filter ((&&) <$> inRange (bounds grid) <*> ((== '.') . (grid !))) $ map (add2 yx0) bombs} in adjs1 ++ adjs2 where { !dir4 = [(0, 1), (0, -1), (1, 0), (-1, 0)]; !bombs = [(y, x) | y <- [-2 .. 2], x <- [-2 .. 2], abs x + abs y >= 2]}};bfsGrid01 :: (Int, Int) -> UArray (Int, Int) Bool -> UArray (Int, Int, Int) Int;bfsGrid01 !start !isBlock = runSTUArray $ do { !dp <- newArray ((0, 0, 0), (pred h, pred w, pred 4)) undef; forM_ [0 .. 3] $ \ iDir -> do { writeArray dp (fst start, snd start, iDir) 0}; let { popLoop Seq.Empty = return (); popLoop (((!y0, !x0, !iDir0), d0) Seq.:<| seq0) = foldM step seq0 [0 .. 3] >>= popLoop where { step !acc !iDir | not (inRange bounds_ (y, x)) || isBlock ! (y, x) = return acc | otherwise = do { !lastD <- readArray dp (y, x, iDir); if lastD /= undef && lastD <= d' then return acc else do { writeArray dp (y, x, iDir) d'; if iDir == iDir0 then return $ nextItem Seq.<| acc else return $ acc Seq.|> nextItem}} where { (!y, !x) = add2 (y0, x0) (dyxs VU.! iDir); !d' | iDir == iDir0 = d0 | otherwise = succ d0; !nextItem = ((y, x, iDir), d')}}}; popLoop . Seq.fromList $ map (\ iDir -> ((fst start, snd start, iDir), 0)) [0 .. 3]; return dp} where { !undef = -1 :: Int; !bounds_ = bounds isBlock; (!h, !w) = both succ . snd $! bounds isBlock; !dyxs = VU.fromList [(1, 0), (-1, 0), (0, 1), (0, -1)]};components :: Graph Int -> Int -> IS.IntSet;components !graph !start = inner (IS.singleton start) start where { inner vis v | null vs = vis' | otherwise = foldl' inner vis' vs where { vs = filter (`IS.notMember` vis) $! graph ! v; vis' = IS.union vis $! IS.fromList vs}};dfsEveryPathT072 :: UArray (Int, Int) Char -> (Int, Int) -> Int;dfsEveryPathT072 !gr !start | gr ! start == '#' = 0; dfsEveryPathT072 !gr !start = runST $ do { !vis <- newArray (bounds gr) False :: ST s (STUArray s (Int, Int) Bool); let { nexts v = filterM (fmap not . readArray vis) . filter ((&&) <$> inRange (bounds gr) <*> ((/= '#') . (gr !))) $! map (add2 v) [(0, 1), (0, -1), (1, 0), (-1, 0)]}; flip fix (0 :: Int, start) $ \ loop (!d1, !v1) -> do { when (v1 /= start) $ do { writeArray vis v1 True}; !v2s <- nexts v1; !maxDistance <- fmap (foldl' max (0 :: Int)) . forM v2s $ \ v2 -> do { if v2 == start then return (succ d1) else loop (succ d1, v2)}; writeArray vis v1 False; return maxDistance}};cyclesSUG :: Array Vertex [Vertex] -> VU.Vector Bool;cyclesSUG !graph = VU.create $ do { !degs <- VUM.replicate nVerts (0 :: Int); forM_ (assocs graph) $ \ (!v1, !v2s) -> do { forM_ v2s $ \ v2 -> do { VUM.modify degs succ v1; VUM.modify degs succ v2}}; !heap0 <- H.fromList <$> filterM (fmap (== 1) . VUM.read degs) [0 .. pred nVerts]; !isCycleVert <- VUM.replicate nVerts True; flip fix heap0 $ \ loop !heap -> case H.uncons heap of { Nothing -> return (); Just (!v1, !heap') -> do { VUM.write degs 0 v1; VUM.write isCycleVert v1 False; loop <=< foldForM heap' (graph ! v1) $ \ heap'' v2 -> do { !deg <- VUM.read degs v2; case deg of { 0 -> return heap''; 1 -> error "cycleSUD: degree 1 to degree 1?"; 2 -> do { VUM.modify degs pred v2; return $ H.insert v2 heap''}; _ -> do { VUM.modify degs pred v2; return heap''}}}}}; return isCycleVert} where { !nVerts = rangeSize (bounds graph)};dj :: forall a . (Num a, Ord a) => WGraph a -> Int -> IM.IntMap a;dj !graph !start = inner (H.singleton $! H.Entry 0 start) IM.empty where { merge :: H.Entry a Int -> H.Entry a Int -> H.Entry a Int; merge (H.Entry !cost1 !_v1) (H.Entry !cost2 !v2) = H.Entry (cost1 + cost2) v2; inner :: H.Heap (H.Entry a Int) -> IM.IntMap a -> IM.IntMap a; inner !heap !vis | H.null heap = vis | IM.member v vis = inner heap' vis | otherwise = inner heap'' vis' where { (entry@(H.Entry cost v), heap') = fromJust $! H.uncons heap; vis' = IM.insert v cost vis; vs = map (merge entry) $! filter ((`IM.notMember` vis') . H.payload) $! graph ! v; heap'' = foldl' (flip H.insert) heap' vs}};revDj :: WGraph Int -> Int -> IM.IntMap Int;revDj !graph !start = dj (revWGraph graph) start;revWGraph :: WGraph Int -> WGraph Int;revWGraph !graph = accumArray @Array (flip (:)) [] (bounds graph) $ concatMap revF $ assocs graph where { revF (!v1, !v2s) = map (\ (H.Entry !priority !v2) -> (v2, H.Entry priority v1)) v2s};djVec :: forall a . (Num a, Ord a, VU.Unbox a) => WGraph a -> Int -> a -> VU.Vector a;djVec !graph !start !undef = VU.create $ do { !vis <- VUM.replicate nVerts undef; let { inner !heap = case H.uncons heap of { Nothing -> return (); Just (entry@(H.Entry cost v), heap') -> do { !isNew <- (== undef) <$> VUM.read vis v; if not isNew then inner heap' else do { VUM.write vis v cost; !vs <- map (merge entry) <$> filterM (fmap (== undef) . VUM.read vis . H.payload) (graph ! v); inner $! foldl' (flip H.insert) heap' vs}}}}; inner (H.singleton $ H.Entry 0 start); return vis} where { !nVerts = rangeSize $! bounds graph; merge :: H.Entry a Int -> H.Entry a Int -> H.Entry a Int; merge (H.Entry !cost1 !_v1) (H.Entry !cost2 !v2) = H.Entry (cost1 + cost2) v2};revDjVec :: WGraph Int -> Int -> VU.Vector Int;revDjVec !graph !start = djVec (revWGraph graph) start (-1);{-# INLINE newFW #-};newFW :: (PrimMonad m, VU.Unbox cost) => (Vertex -> cost, cost, cost) -> Int -> [(Int, Int)] -> m (VUM.MVector (PrimState m) cost);newFW (!getCost, !zeroCost, !maxCost) !nVerts !edges = do { !dp <- VUM.replicate (nVerts * nVerts) maxCost; forMS_ (rangeMS 0 (pred nVerts)) $ \ !v -> VUM.unsafeWrite dp (ix (v, v)) zeroCost; forM_ edges $ \ (!v1, !v2) -> do { let { !cost = getCost v2}; VUM.unsafeWrite dp (ix (v1, v2)) cost}; return dp} where { ix :: (Int, Int) -> Int; ix = index ((0, 0), (nVerts - 1, nVerts - 1))};{-# INLINE runFW #-};runFW :: (PrimMonad m, VU.Unbox cost) => (cost -> cost -> cost, cost -> cost -> cost) -> Int -> VUM.MVector (PrimState m) cost -> m ();runFW (!mergeCost, !minCost) !nVerts !dp = do { let { !ve = pred nVerts}; forM_ (range ((0, 0, 0), (ve, ve, ve))) $ \ (!v3, !v1, !v2) -> do { !cost1 <- VUM.unsafeRead dp (ix (v1, v2)); !cost2 <- mergeCost <$> VUM.unsafeRead dp (ix (v1, v3)) <*> VUM.unsafeRead dp (ix (v3, v2)); VUM.unsafeWrite dp (ix (v1, v2)) $ minCost cost1 cost2}} where { ix :: (Int, Int) -> Int; ix = index ((0, 0), (nVerts - 1, nVerts - 1))};{-# INLINE newFW_ABC286E #-};newFW_ABC286E :: (PrimMonad m) => (Vertex -> (Int, Int)) -> Int -> [(Int, Int)] -> m (VUM.MVector (PrimState m) (Int, Int));newFW_ABC286E !getCost = newFW (getCost, (0, 0), (maxBound @Int, maxBound @Int));{-# INLINE runFW_ABC286E #-};runFW_ABC286E :: (PrimMonad m) => Int -> VUM.MVector (PrimState m) (Int, Int) -> m ();runFW_ABC286E = runFW (mergeCost, minCost) where { mergeCost :: (Int, Int) -> (Int, Int) -> (Int, Int); mergeCost (!d1, !v1) (!d2, !v2) | d1 == maxBound = (d1, v1) | d2 == maxBound = (d2, v2) | d1 == maxBound = (d1, v1) | otherwise = (d1 + d2, v1 + v2); minCost :: (Int, Int) -> (Int, Int) -> (Int, Int); minCost (!d1, !v1) (!d2, !v2) = case compare d1 d2 of { EQ -> (d1, max v1 v2); LT -> (d1, v1); GT -> (d2, v2)}};data RNEdge = RNEdge{to :: {-# UNPACK #-} !Vertex, cap :: {-# UNPACK #-} !Int, rev :: {-# UNPACK #-} !Int} deriving (Show);derivingUnbox "RNEdge" [t| RNEdge -> (Vertex, Int, Int) |] [| \ (RNEdge !x1 !x2 !x3) -> (x1, x2, x3) |] [| \ (!x1, !x2, !x3) -> RNEdge x1 x2 x3 |];type ResidualNetwork = VM.IOVector (IM.IntMap RNEdge);buildRN :: Int -> [(Int, (Int, Int))] -> IO ResidualNetwork;buildRN !nVerts !edges = do { !rn <- VM.replicate nVerts IM.empty; forM_ edges $ \ (!v1, (!v2, !cap_)) -> do { addEdgeRN rn v1 v2 cap_}; return rn} where { addEdgeRN :: ResidualNetwork -> Int -> Int -> Int -> IO (); addEdgeRN !rn !v1 !v2 !maxFlow = do { !edges1 <- VM.read rn v1; !edges2 <- VM.read rn v2; VM.write rn v1 $ IM.insertWith mergeEdge v2 (RNEdge v2 maxFlow v1) edges1; VM.write rn v2 $ IM.insertWith mergeEdge v1 (RNEdge v1 0 v2) edges2}; mergeEdge :: RNEdge -> RNEdge -> RNEdge; mergeEdge (RNEdge !to_ !flow !cap_) (RNEdge !_ !flow' !_) = RNEdge to_ (flow + flow') cap_};{-# INLINE maxFlowRN #-};maxFlowRN :: Int -> ResidualNetwork -> Int -> Int -> IO Int;maxFlowRN !nVerts !rn !v0 !ve = do { !vis <- VM.replicate nVerts False; inner vis} where { inner :: VM.IOVector Bool -> IO Int; inner !vis = augumentPath rn vis v0 ve >>= \case { Nothing -> return 0; Just (!flow, !path) -> do { updateFlow rn flow path; VM.set vis False; (flow +) <$> inner vis}}};{-# INLINE augumentPath #-};augumentPath :: ResidualNetwork -> VM.IOVector Bool -> Vertex -> Int -> IO (Maybe (Int, [(Vertex, Vertex)]));augumentPath !rn !vis !v0 !goal = visitVertex v0 (maxBound @Int) where { visitVertex :: Vertex -> Int -> IO (Maybe (Int, [(Vertex, Vertex)])); visitVertex !v !flow | v == goal = return $ Just (flow, []) | otherwise = do { VM.write vis v True; !edges <- VM.read rn v; foldM (step v flow) Nothing edges}; step :: Vertex -> Int -> Maybe (Int, [(Vertex, Vertex)]) -> RNEdge -> IO (Maybe (Int, [(Vertex, Vertex)])); step !_ !_ r@(Just _) _ = return r; step !from !flow !_ !edge = do { !visited <- VM.read vis (to edge); if visited || flow' == 0 then return Nothing else visitVertex (to edge) flow' >>= \case { Nothing -> return Nothing; Just (!f, !path) -> return $ Just (f, p : path)}} where { flow' = min flow (cap edge); p = (from, to edge)}};{-# INLINE updateFlow #-};updateFlow :: ResidualNetwork -> Int -> [(Vertex, Vertex)] -> IO ();updateFlow !rn !flow !path = forM_ path $ \ (!v1, !v2) -> addFlowRNEdge rn v1 v2 flow;{-# INLINE addFlowRNEdge #-};addFlowRNEdge :: ResidualNetwork -> Vertex -> Vertex -> Int -> IO ();addFlowRNEdge !rn !v1 !v2 !flow = do { (!edges1, !edge12) <- second (IM.! v2) . dupe <$> VM.read rn v1; (!edges2, !edge21) <- second (IM.! v1) . dupe <$> VM.read rn v2; VM.write rn v1 $ IM.insert v2 (RNEdge (to edge12) (cap edge12 - flow) (rev edge12)) edges1; VM.write rn v2 $ IM.insert v1 (RNEdge (to edge21) (cap edge21 + flow) (rev edge21)) edges2};type Color = Bool;type ColorInfo = ([Int], [Int]);colorize :: Graph Int -> IM.IntMap Color -> Vertex -> (IM.IntMap Color, Maybe ColorInfo);colorize !graph !colors0 = dfs True (colors0, Just ([], [])) where { dfs :: Color -> (IM.IntMap Color, Maybe ColorInfo) -> Vertex -> (IM.IntMap Color, Maybe ColorInfo); dfs !color (!colors, !acc) !v = let { (!colors', !acc') = setColor color (colors, acc) v} in if IM.member v colors then (colors', acc') else foldl' (dfs (not color)) (colors', acc') $ graph ! v; setColor :: Color -> (IM.IntMap Color, Maybe ColorInfo) -> Vertex -> (IM.IntMap Color, Maybe ColorInfo); setColor !color (!colors, !acc) !v = case IM.lookup v colors of { Just c | c == color -> (colors, acc) | otherwise -> (colors, Nothing); Nothing -> (IM.insert v color colors, applyColor color v acc)}; applyColor :: Color -> Vertex -> Maybe ColorInfo -> Maybe ColorInfo; applyColor !_ !_ Nothing = Nothing; applyColor !color !v (Just !acc) | color = Just $ first (v :) acc | otherwise = Just $ second (v :) acc};foldTree :: forall m a . Array Vertex [Vertex] -> Vertex -> (m -> a -> a) -> (Vertex -> a) -> (a -> m) -> a;foldTree !tree !root !sact !acc0At !toM = inner (-1) root where { inner :: Vertex -> Vertex -> a; inner !parent !v1 = let { !v2s = filter (/= parent) $ tree ! v1} in foldl' (\ acc v2 -> (toM $! inner v1 v2) `sact` acc) (acc0At v1) v2s};scanTreeVG :: (VG.Vector v a) => Array Vertex [Vertex] -> Vertex -> (m -> a -> a) -> (Vertex -> a) -> (a -> m) -> v a;scanTreeVG !tree !root !sact !acc0At !toM = VG.create $ do { !dp <- VGM.unsafeNew nVerts; !_ <- flip fix (-1, root) $ \ runTreeDp (!parent, !v1) -> do { let { !v2s = filter (/= parent) $! tree ! v1}; !x1 <- foldM (\ acc v2 -> (`sact` acc) . toM <$> runTreeDp (v1, v2)) (acc0At v1) v2s; VGM.write dp v1 x1; return x1}; return dp} where { !nVerts = rangeSize $! bounds tree};scanTreeVU :: VU.Unbox a => Array Vertex [Vertex] -> Vertex -> (m -> a -> a) -> (Vertex -> a) -> (a -> m) -> VU.Vector a;scanTreeVU = scanTreeVG;scanTreeV :: Array Vertex [Vertex] -> Vertex -> (m -> a -> a) -> (Vertex -> a) -> (a -> m) -> V.Vector a;scanTreeV = scanTreeVG;foldTreeAll :: (VU.Unbox a, VU.Unbox m, MonoidAction m a) => Array Vertex [Vertex] -> (Vertex -> a) -> (a -> m) -> VU.Vector a;foldTreeAll !tree !acc0At !toM = let { !treeDp = scanTreeVG tree root0 mact acc0At toM; !rootDp = VU.create $ do { !dp <- VUM.unsafeNew nVerts; flip fix (-1, op0, root0) $ \ runRootDp (!parent, !parentOp, !v1) -> do { let { !children = VU.fromList . filter (/= parent) $! tree ! v1}; let { !opL = VU.scanl' (\ op v2 -> (op <>) . toM $! treeDp VU.! v2) op0 children}; let { !opR = VU.scanr' (\ v2 op -> (<> op) . toM $! treeDp VU.! v2) op0 children}; let { !x1 = (parentOp <> VU.last opL) `mact` acc0At v1}; VUM.write dp v1 x1; flip VU.imapM_ children $ \ !i2 !v2 -> do { let { !lrOp = (opL VU.! i2) <> (opR VU.! succ i2)}; let { !v1Acc = (parentOp <> lrOp) `mact` acc0At v2}; runRootDp (v1, toM v1Acc, v2)}}; return dp}} in rootDp where { !nVerts = rangeSize $ bounds tree; !root0 = 0 :: Int; !op0 = mempty};newtype BinaryLifting v m = BinaryLifting (v m) deriving (Show, Eq);newBinLift :: (VG.Vector v s, Semigroup s) => s -> BinaryLifting v s;newBinLift !op0 = BinaryLifting ops where { !ops = VG.iterateN (pred 63) (\ !op -> op <> op) op0};newBinLiftV :: Semigroup s => s -> BinaryLifting V.Vector s;newBinLiftV = newBinLift;newBinLiftVU :: (Semigroup s, VU.Unbox s) => s -> BinaryLifting VU.Vector s;newBinLiftVU = newBinLift;stimesBL :: (Semigroup s, VG.Vector v s) => (BinaryLifting v s) -> s -> Int -> s;stimesBL (BinaryLifting !ops) !s0 !n = VU.foldl' step s0 (VU.enumFromN 0 62) where { step !m !i | testBit n i = m <> ops VG.! i | otherwise = m};mtimesBL :: (Monoid m, VG.Vector v m) => (BinaryLifting v m) -> Int -> m;mtimesBL !bin !n = stimesBL bin mempty n;sactBL :: (SemigroupAction s a, VG.Vector v s) => (BinaryLifting v s) -> a -> Int -> a;sactBL (BinaryLifting !ops) !acc0 !nAct = VU.foldl' step acc0 (rangeVG 0 62) where { step !acc !nBit | testBit nAct nBit = (ops VG.! nBit) `sact` acc | otherwise = acc};mactBL :: (MonoidAction m a, VG.Vector v m) => (BinaryLifting v m) -> a -> Int -> a;mactBL = sactBL;newDoubling :: (VG.Vector v a, VG.Vector v Int) => a -> (a -> a) -> v a;newDoubling !oper0 !squareCompositeF = VG.scanl' step oper0 $! VG.enumFromN (1 :: Int) 62 where { step !oper !_ = squareCompositeF oper};newDoublingV :: a -> (a -> a) -> V.Vector a;newDoublingV = newDoubling;applyDoubling :: (VG.Vector v op) => v op -> a -> (a -> op -> a) -> Int -> a;applyDoubling !opers !x0 !act !n = foldl' step x0 [0 .. 62] where { !_ = dbgAssert $ VG.length opers == 63; step !acc !nBit = if testBit n nBit then acc `act` (opers VG.! nBit) else acc};class RangeMS a where { rangeMS2 :: Monad m => (a, a) -> MS.Stream m a};instance RangeMS Int where { rangeMS2 (!l, !r) = rangeMS l r};instance RangeMS (Int, Int) where { rangeMS2 ((!y0, !x0), (!y1, !x1)) = MS.Stream step (y0, x0) where { {-# INLINE [0] step #-}; step (!y, !x) | x <= x1 = return $! MS.Yield (y, x) (y, x + 1) | y <= y1 = return $! MS.Yield (y, x) (y + 1, x0) | otherwise = return MS.Done}};class (Ix i, VU.Unbox i) => Unindex i where { unindex :: (i, i) -> Int -> i};instance Unindex Int where { unindex _ !v = v};instance Unindex (Int, Int) where { unindex ((!y0, !x0), (!_, !x1)) !yx = let { !w = x1 - x0 + 1; (!dy, !dx) = yx `quotRem` w} in (y0 + dy, x0 + dx)};instance Unindex (Int, Int, Int) where { unindex ((!z0, !y0, !x0), (!_, !y1, !x1)) !zyx = let { !h = y1 - y0 + 1; !w = x1 - x0 + 1; (!dz, !yx) = zyx `quotRem` (h * w); (!dy, !dx) = yx `quotRem` w} in (z0 + dz, y0 + dy, x0 + dx)};type Edge = (Vertex, Vertex);type WEdgeWith w = (Vertex, Vertex, w);type EdgeId = Int;data SparseGraph i w = SparseGraph{boundsSG :: !(i, i), nVertsSG :: !Int, nEdgesSG :: !Int, offsetsSG :: !(VU.Vector Int), adjacentsSG :: !(VU.Vector Vertex), edgeWeightsSG :: !(VU.Vector w)} deriving (Show);{-# INLINE buildUSG #-};buildUSG :: (Unindex i) => (i, i) -> VU.Vector (i, i) -> SparseGraph i ();buildUSG !boundsSG !edges = buildRawSG boundsSG $ VU.map (\ (!i1, !i2) -> (ix i1, ix i2, ())) edges where { ix = index boundsSG};{-# INLINE buildWSG #-};buildWSG :: (Unindex i, VUM.Unbox w) => (i, i) -> VU.Vector (i, i, w) -> SparseGraph i w;buildWSG !boundsSG !edges = buildRawSG boundsSG $ VU.map (\ (!i1, !i2, !w) -> (ix i1, ix i2, w)) edges where { ix = index boundsSG};{-# INLINE buildRawSG #-};buildRawSG :: (Unindex i, VUM.Unbox w) => (i, i) -> VU.Vector (Vertex, Vertex, w) -> SparseGraph i w;buildRawSG !boundsSG !edges = let { !nEdgesSG = VU.length edges; !nVertsSG = rangeSize boundsSG; !offsetsSG = VU.scanl' (+) 0 $ VU.create $ do { !outDegs <- VUM.replicate nVertsSG (0 :: Int); VU.forM_ edges $ \ (!v1, !_, !_) -> do { VUM.modify outDegs succ v1}; return outDegs}; !_ = dbgAssert (VU.last offsetsSG == nEdgesSG); (!adjacentsSG, !edgeWeightsSG) = runST $ do { !mOffsets <- VU.thaw offsetsSG; !mAdjacents <- VUM.unsafeNew nEdgesSG; !mWeights <- VUM.unsafeNew nEdgesSG; VU.forM_ edges $ \ (!v1, !v2, !w) -> do { !iEdgeFlatten <- VUM.unsafeRead mOffsets v1; VUM.unsafeWrite mOffsets v1 (iEdgeFlatten + 1); VUM.unsafeWrite mAdjacents iEdgeFlatten v2; VUM.unsafeWrite mWeights iEdgeFlatten w}; (,) <$> VU.unsafeFreeze mAdjacents <*> VU.unsafeFreeze mWeights}} in SparseGraph{..};{-# INLINE adj #-};adj :: SparseGraph i w -> Vertex -> VU.Vector Vertex;adj SparseGraph{..} v = VU.unsafeSlice o1 (o2 - o1) adjacentsSG where { !o1 = VU.unsafeIndex offsetsSG v; !o2 = VU.unsafeIndex offsetsSG (v + 1)};{-# INLINE eAdj #-};eAdj :: SparseGraph i w -> Vertex -> VU.Vector (EdgeId, Vertex);eAdj SparseGraph{..} v = VU.imap ((,) . (+ o1)) vs where { !o1 = VU.unsafeIndex offsetsSG v; !o2 = VU.unsafeIndex offsetsSG (v + 1); !vs = VU.unsafeSlice o1 (o2 - o1) adjacentsSG};{-# INLINE adjIx #-};adjIx :: (Unindex i) => SparseGraph i w -> i -> VU.Vector i;adjIx gr i = VU.map (unindex (boundsSG gr)) $ adj gr v where { !v = index (boundsSG gr) i};{-# INLINE adjW #-};adjW :: (VU.Unbox w) => SparseGraph i w -> Vertex -> VU.Vector (Vertex, w);adjW SparseGraph{..} v = VU.zip vs ws where { !o1 = VU.unsafeIndex offsetsSG v; !o2 = VU.unsafeIndex offsetsSG (v + 1); !vs = VU.unsafeSlice o1 (o2 - o1) adjacentsSG; !ws = VU.unsafeSlice o1 (o2 - o1) edgeWeightsSG};{-# INLINE adjWIx #-};adjWIx :: (Unindex i, VU.Unbox w) => SparseGraph i w -> i -> VU.Vector (i, w);adjWIx gr i = VU.map (first (unindex (boundsSG gr))) $ adjW gr v where { !v = index (boundsSG gr) i};dfsSG :: (Unindex i) => SparseGraph i w -> i -> IxVector i (VU.Vector Int);dfsSG gr@SparseGraph{..} !startIx = IxVector boundsSG $ VU.create $ do { let { !undef = -1 :: Int}; !dist <- VUM.replicate nVertsSG undef; flip fix (0 :: Int, index boundsSG startIx) $ \ loop (!depth, !v1) -> do { VUM.write dist v1 depth; VU.forM_ (gr `adj` v1) $ \ v2 -> do { !d <- VUM.read dist v2; when (d == undef) $ do { loop (succ depth, v2)}}}; return dist};componentsVecSG :: (Ix i) => SparseGraph i w -> i -> IxVector i (VU.Vector Bool);componentsVecSG !gr@SparseGraph{..} !startIx = IxVector boundsSG $ VU.create $ do { !vis <- VUM.replicate nVertsSG False; flip fix start $ \ loop v1 -> do { VUM.write vis v1 True; let { !v2s = gr `adj` v1}; VU.forM_ v2s $ \ v2 -> do { !visited <- VUM.read vis v2; when (not visited) $ do { loop v2}}}; return vis} where { !start = index boundsSG startIx :: Vertex};bfsSG :: (Unindex i) => SparseGraph i w -> i -> IxVector i (VU.Vector Int);bfsSG gr@SparseGraph{..} !startIx = IxVector boundsSG $ VU.create $ do { let { !undef = -1 :: Int}; !dist <- VUM.replicate nVertsSG undef; let { inner !depth !vs1 | IS.null vs1 = return () | otherwise = do { let { vs1' = IS.toList vs1}; forM_ vs1' $ \ v1 -> do { VUM.unsafeWrite dist v1 depth}; !vs2 <- foldForM [] vs1' $ \ acc v1 -> do { foldForMVG acc (gr `adj` v1) $ \ acc' v2 -> do { !d <- VUM.unsafeRead dist v2; if d == undef then return (v2 : acc') else return acc'}}; inner (succ depth) $ IS.fromList vs2}}; !_ <- inner (0 :: Int) (IS.singleton (index boundsSG startIx)); return dist};djSG :: forall i w . (Unindex i, Num w, Ord w, VU.Unbox w) => SparseGraph i w -> w -> i -> VU.Vector w;djSG gr@SparseGraph{..} !undef !startIx = VU.create $ do { !dist <- VUM.replicate nVertsSG undef; let { !heap0 = H.singleton $ H.Entry 0 (index boundsSG startIx)}; flip fix heap0 $ \ loop heap -> case H.uncons heap of { Nothing -> return (); Just (entry@(H.Entry cost v), heap') -> do { (== undef) <$> VUM.read dist v >>= \case { False -> loop heap'; True -> do { VUM.write dist v cost; !vws <- VU.filterM (fmap (== undef) . VUM.read dist . fst) $ gr `adjW` v; loop $ VU.foldl' (\ h (!v, !w) -> H.insert (merge entry (H.Entry w v)) h) heap' vws}}}}; return dist} where { merge :: H.Entry w Vertex -> H.Entry w Vertex -> H.Entry w Vertex; merge (H.Entry !cost1 !_v1) (H.Entry !cost2 !v2) = H.Entry (cost1 + cost2) v2};dfsPathSG :: (Unindex i) => SparseGraph i w -> i -> i -> Maybe [Edge];dfsPathSG gr@SparseGraph{..} !startIx !endIx = runST $ do { let { !undef = -1 :: Int}; !dist <- VUM.replicate nVertsSG undef; flip fix (0 :: Int, start, []) $ \ loop (!depth, !v1, !stack) -> do { !lastD1 <- VUM.read dist v1; when (lastD1 == undef) $ do { VUM.write dist v1 depth}; if lastD1 /= undef then return Nothing else if v1 == end then return $ Just stack else do { flip fix (gr `adj` v1) $ \ visitNeighbors v2s -> case unconsVG v2s of { Nothing -> return Nothing; Just (!v2, !v2s') -> do { (<|>) <$> loop (succ depth, v2, (v1, v2) : stack) <*> visitNeighbors v2s'}}}}} where { !start = index boundsSG startIx; !end = index boundsSG endIx};treeDfsPathSG :: (Unindex i) => SparseGraph i w -> i -> i -> [Edge];treeDfsPathSG gr@SparseGraph{..} !startIx !endIx = fromJust $ runST $ do { let { !undef = -1 :: Int}; flip fix (0 :: Int, undef, start, []) $ \ loop (!depth, !parent, !v1, !stack) -> do { if v1 == end then return $ Just stack else do { flip fix (VU.filter (/= parent) $ gr `adj` v1) $ \ visitNeighbors v2s -> case unconsVG v2s of { Nothing -> return Nothing; Just (!v2, !v2s') -> do { (<|>) <$> loop (succ depth, v1, v2, (v1, v2) : stack) <*> visitNeighbors v2s'}}}}} where { !start = index boundsSG startIx; !end = index boundsSG endIx};topSortSG :: SparseGraph i w -> [Vertex];topSortSG gr@SparseGraph{..} = runST $ do { !vis <- VUM.replicate nVertsSG False; let { dfsM !acc !v = do { VUM.unsafeRead vis v >>= \case { True -> return acc; False -> do { VUM.unsafeWrite vis v True; !vs <- VU.filterM (fmap not . VUM.unsafeRead vis) $ gr `adj` v; (v :) <$> VU.foldM' dfsM acc vs}}}}; MS.foldM' dfsM [] (rangeMS 0 (pred nVertsSG))};topScc1SG :: forall i w m . (PrimMonad m) => SparseGraph i w -> VUM.MVector (PrimState m) Bool -> Vertex -> m [Vertex];topScc1SG !gr' !vis !v0 = do { flip fix ([], v0) $ \ loop (!acc, !v) -> do { VUM.unsafeRead vis v >>= \case { False -> return acc; True -> do { VUM.unsafeWrite vis v True; !vs <- VU.filterM (fmap not . VUM.unsafeRead vis) $ gr' `adj` v; (v :) <$> VU.foldM' (curry loop) acc vs}}}};revSG :: (Unindex i, VU.Unbox w) => SparseGraph i w -> SparseGraph i w;revSG SparseGraph{..} = buildRawSG boundsSG edges' where { !vws = VU.zip adjacentsSG edgeWeightsSG; !edges' = flip VU.concatMap (rangeVU 0 (pred nVertsSG)) $ \ v1 -> let { !o1 = VU.unsafeIndex offsetsSG v1; !o2 = VU.unsafeIndex offsetsSG (v1 + 1); !vw2s = VU.unsafeSlice o1 (o2 - o1) vws} in VU.map (\ (v2, !w2) -> (v2, v1, w2)) vw2s};topSccSG :: (Unindex i, VU.Unbox w) => SparseGraph i w -> [[Int]];topSccSG gr = collectSccPreorderSG $ topSortSG gr where { !gr' = revSG gr; collectSccPreorderSG :: [Int] -> [[Int]]; collectSccPreorderSG !topVerts = runST $ do { !vis <- VUM.replicate (nVertsSG gr) False; filter (not . null) <$> mapM (topScc1SG gr' vis) topVerts}};{-# INLINE bsearch #-};bsearch :: (Int, Int) -> (Int -> Bool) -> (Maybe Int, Maybe Int);bsearch !rng = runIdentity . bsearchM rng . (return .);{-# INLINE bsearchL #-};bsearchL :: (Int, Int) -> (Int -> Bool) -> Maybe Int;bsearchL !a !b = fst $! bsearch a b;{-# INLINE bsearchR #-};bsearchR :: (Int, Int) -> (Int -> Bool) -> Maybe Int;bsearchR !a !b = snd $! bsearch a b;{-# INLINE bsearchM #-};bsearchM :: forall m . (Monad m) => (Int, Int) -> (Int -> m Bool) -> m (Maybe Int, Maybe Int);bsearchM (!low, !high) !isOk = both wrap <$> inner (low - 1, high + 1) where { inner :: (Int, Int) -> m (Int, Int); inner (!ok, !ng) | abs (ok - ng) == 1 = return (ok, ng); inner (!ok, !ng) = isOk m >>= \case { True -> inner (m, ng); False -> inner (ok, m)} where { !m = (ok + ng) `div` 2}; wrap :: Int -> Maybe Int; wrap !x | inRange (low, high) x = Just x | otherwise = Nothing};{-# INLINE bsearchML #-};bsearchML :: forall m . (Monad m) => (Int, Int) -> (Int -> m Bool) -> m (Maybe Int);bsearchML = fmap fst .: bsearchM;{-# INLINE bsearchMR #-};bsearchMR :: forall m . (Monad m) => (Int, Int) -> (Int -> m Bool) -> m (Maybe Int);bsearchMR = fmap snd .: bsearchM;{-# INLINE bsearchF32 #-};bsearchF32 :: (Float, Float) -> Float -> (Float -> Bool) -> (Maybe Float, Maybe Float);bsearchF32 (!low, !high) !diff !isOk = both wrap (inner (low - diff, high + diff)) where { inner :: (Float, Float) -> (Float, Float); inner (!ok, !ng) | abs (ok - ng) <= diff = (ok, ng); inner (!ok, !ng) | isOk m = inner (m, ng) | otherwise = inner (ok, m) where { !m = (ok + ng) / 2}; wrap :: Float -> Maybe Float; wrap !x | x == (low - diff) || x == (high + diff) = Nothing | otherwise = Just x};{-# INLINE bsearchF32L #-};bsearchF32L :: (Float, Float) -> Float -> (Float -> Bool) -> Maybe Float;bsearchF32L !a !b !c = fst $! bsearchF32 a b c;{-# INLINE bsearchF32R #-};bsearchF32R :: (Float, Float) -> Float -> (Float -> Bool) -> Maybe Float;bsearchF32R !a !b !c = fst $! bsearchF32 a b c;{-# INLINE bsearchF64 #-};bsearchF64 :: (Double, Double) -> Double -> (Double -> Bool) -> (Maybe Double, Maybe Double);bsearchF64 (!low, !high) !diff !isOk = both wrap (inner (low - diff, high + diff)) where { inner :: (Double, Double) -> (Double, Double); inner (!ok, !ng) | abs (ok - ng) < diff = (ok, ng); inner (!ok, !ng) | isOk m = inner (m, ng) | otherwise = inner (ok, m) where { !m = (ok + ng) / 2}; wrap :: Double -> Maybe Double; wrap !x | x == (low - diff) || x == (high + diff) = Nothing | otherwise = Just x};{-# INLINE bsearchF64L #-};bsearchF64L :: (Double, Double) -> Double -> (Double -> Bool) -> Maybe Double;bsearchF64L !a !b !c = fst $! bsearchF64 a b c;{-# INLINE bsearchF64R #-};bsearchF64R :: (Double, Double) -> Double -> (Double -> Bool) -> Maybe Double;bsearchF64R !a !b !c = fst $! bsearchF64 a b c;compressList :: [Int] -> (VU.Vector Int, [Int]);compressList xs = (indices, map (fromJust . fst . f) xs) where { !indices = VU.fromList $ nubSort xs; f !x = bsearch (0, pred (vLength indices)) $ \ i -> indices VU.! i <= x};isqrtSlow :: Int -> Int;isqrtSlow n = fromJust $ bsearchR (0, n) ((< n) . (^ (2 :: Int)));newtype ToParent = ToParent (VU.Vector Vertex);instance Semigroup ToParent where { (ToParent !vec1) <> (ToParent !vec2) = ToParent $ VU.map f vec2 where { !_ = dbgAssert (VG.length vec1 == VG.length vec2); f (-1) = (-1); f i = vec1 VU.! i}};instance SemigroupAction ToParent Vertex where { sact (ToParent !vec) !i = vec VU.! i};type LcaCache = (ToParent, VU.Vector Int, BinaryLifting V.Vector ToParent);treeDepthInfo :: Int -> (Int -> [Int]) -> Int -> (ToParent, VU.Vector Int);treeDepthInfo !nVerts !graph !root = runST $ do { !parents <- VUM.replicate nVerts (-1 :: Int); !depths <- VUM.replicate nVerts (-1 :: Int); flip fix (0 :: Int, -1 :: Int, [root]) $ \ loop (!depth, !parent, !vs) -> do { forM_ vs $ \ v -> do { VUM.unsafeWrite depths v depth; VUM.unsafeWrite parents v parent; let { !vs' = filter (/= parent) $ graph v}; loop (succ depth, v, vs')}}; (,) <$> (ToParent <$> VU.unsafeFreeze parents) <*> VU.unsafeFreeze depths};lcaCache :: Int -> (Vertex -> [Vertex]) -> Vertex -> LcaCache;lcaCache !nVerts !graph !root = (toParent, depths, toParentN) where { (!toParent, !depths) = treeDepthInfo nVerts graph root; !toParentN = newBinLift toParent};lca :: LcaCache -> Int -> Int -> (Int, Int);lca (!_, !depths, !toParentN) !v1 !v2 = (vLCA, depths VU.! vLCA) where { !d1 = depths VU.! v1; !d2 = depths VU.! v2; parentN = sactBL toParentN; !v1' = if d1 <= d2 then v1 else v2; !v2' = parentN (if d1 > d2 then v1 else v2) (abs $ d1 - d2); !dLCA = fromJust . snd $ bsearch (0, min d1 d2) $ \ d -> parentN v1' d /= parentN v2' d; !vLCA = parentN v1' dLCA};lcaLen :: LcaCache -> Int -> Int -> Int;lcaLen cache@(!_, !depths, !_) !v1 !v2 = let { (!_, !d) = lca cache v1 v2; !d1 = depths VU.! v1; !d2 = depths VU.! v2} in (d1 - d) + (d2 - d);newtype ToParentM m = ToParentM (Int, VU.Vector m);type FoldLcaCache m = (LcaCache, V.Vector (VU.Vector m));foldLcaCache :: forall m . (Monoid m, VU.Unbox m) => Int -> (Vertex -> [Vertex]) -> Vertex -> (Vertex -> Vertex -> m) -> FoldLcaCache m;foldLcaCache !nVerts !graph !root !edgeValueOf = (cache, foldCache) where { !cache@(!parents, !_, BinaryLifting !parents') = lcaCache nVerts graph root; foldCache :: V.Vector (VU.Vector m); !foldCache = V.map snd $! newDoubling toParent appendArray where { !toParent = (0, VU.map f (rangeVG 0 (pred nVerts))) where { f v = case parents `sact` v of { (-1) -> mempty; p -> edgeValueOf v p}}; appendArray (!iBit, !ops) = (succ iBit, VU.imap f ops) where { f !v0 !op = case (parents' V.! iBit) `sact` v0 of { (-1) -> op; p -> op <> (ops VU.! p)}}}};foldLcaCache2 :: forall a m . (Monoid m, VU.Unbox m) => Array Int [(Vertex, a)] -> (a -> m) -> FoldLcaCache m;foldLcaCache2 !tree !toMonoid = foldLcaCache nVerts adj root getValue where { !root = 0 :: Vertex; !nVerts = rangeSize $ bounds tree; adj = map fst . (tree !); getValue !v !p = toMonoid . snd . fromJust . find ((== p) . fst) $ tree ! v};foldViaLca :: forall m . (Monoid m, VU.Unbox m) => FoldLcaCache m -> Int -> Int -> m;foldViaLca (cache@(!_, !depths, BinaryLifting !parents'), !ops') !v1 !v2 = let { (!_, !d) = lca cache v1 v2; !d1 = depths VU.! v1; !d2 = depths VU.! v2; !a1 = foldParentN v1 (d1 - d); !a2 = foldParentN v2 (d2 - d)} in a1 <> a2 where { foldParentN :: Vertex -> Int -> m; foldParentN !v0 !nthParent = snd $ V.foldl' step (v0, mempty) input where { !input = V.zip3 (rangeVG 0 62) parents' ops'; step :: (Vertex, m) -> (Int, ToParent, VU.Vector m) -> (Vertex, m); step (!v, !acc) (!iBit, !parents, !ops) | testBit nthParent iBit = (parents `sact` v, acc <> (ops VU.! v)) | otherwise = (v, acc)}};compressVU :: VU.Vector Int -> (VU.Vector Int, VU.Vector Int);compressVU xs = (indexer, VU.map (fromJust . fst . f) xs) where { !indexer = VU.fromList $ nubSort $ VU.toList xs; f !x = bsearch (0, pred $ vLength indexer) $ \ i -> indexer VU.! i <= x};invNumVG :: Int -> (VG.Vector v Int) => v Int -> Int;invNumVG xMax xs = runST $ do { !stree <- newSTreeVU (+) (xMax + 1) (0 :: Int); foldForMVG (0 :: Int) xs $ \ acc x -> do { !s <- if x == xMax then return 0 else fromJust <$> querySTree stree (succ x, xMax); modifySTree stree succ x; return $! acc + s}};compressInvNumVG :: VU.Vector Int -> Int;compressInvNumVG xs = invNumVG (pred (VU.length xs')) xs' where { !xs' = snd $ compressVU xs};imos2D :: ((Int, Int), (Int, Int)) -> UArray (Int, Int) Int -> UArray (Int, Int) Int;imos2D !bounds_ !seeds = runSTUArray $ do { !arr <- newArray bounds_ (0 :: Int); let { (!minY, !minX) = fst bounds_}; forM_ (range bounds_) $ \ (!y, !x) -> do { !v <- if x == minX then return 0 else readArray arr (y, x - 1); let { !diff = seeds ! (y, x)}; writeArray arr (y, x) $! v + diff}; forM_ (range bounds_) $ \ (!x, !y) -> do { !v <- if y == minY then return 0 else readArray arr (y - 1, x); !diff <- readArray arr (y, x); writeArray arr (y, x) $! v + diff}; return arr};imos2DRev :: ((Int, Int), (Int, Int)) -> UArray (Int, Int) Int -> UArray (Int, Int) Int;imos2DRev !bounds_ !seeds = runSTUArray $ do { !arr <- newArray bounds_ (0 :: Int); let { (!minY, !minX) = fst bounds_}; let { (!maxY, !maxX) = snd bounds_}; forMS_ (rangeMSR minX maxX) $ \ x -> do { forMS_ (rangeMSR minY maxY) $ \ y -> do { !v <- if x == maxX then return 0 else readArray arr (y, x + 1); let { !diff = seeds ! (y, x)}; writeArray arr (y, x) $! v + diff}}; forMS_ (rangeMSR minX maxX) $ \ x -> do { forMS_ (rangeMSR minY maxY) $ \ y -> do { !v <- if y == maxY then return 0 else readArray arr (y + 1, x); !diff <- readArray arr (y, x); writeArray arr (y, x) $! v + diff}}; return arr};log2 :: (FiniteBits b) => b -> Int;log2 !x = finiteBitSize x - 1 - countLeadingZeros x;log2CeilInt :: Int -> Int;log2CeilInt !x = msb + ceiling_ where { !msb = log2 x; !ceiling_ = if clearBit x msb > 0 then 1 else 0};bitCeil :: Int -> Int;bitCeil = bit . log2CeilInt;addMod, subMod, mulMod :: Int -> Int -> Int -> Int;addMod !x !a !modulo = (x + a) `mod` modulo;subMod !x !s !modulo = (x - s) `mod` modulo;mulMod !b !p !modulo = (b * p) `mod` modulo;factMod :: Int -> Int -> Int;factMod 0 _ = 1; factMod 1 _ = 1; factMod !n !m = n * factMod (n - 1) m `rem` m;powModConst :: Int -> Int -> Int -> Int;powModConst !base !power !modulo = powModByCache power (powModCache (base `mod` modulo) modulo);invModF :: Int -> Int -> Int;invModF !d !modulo = invModFC modulo (powModCache d modulo);divModF :: Int -> Int -> Int -> Int;divModF !x !d !modulo = divModFC x (powModCache d modulo) `rem` modulo;powModCache :: Int -> Int -> (Int, VU.Vector Int);powModCache !base !modulo = (modulo, doubling) where { doubling = newDoubling base (\ x -> x * x `rem` modulo)};powModByCache :: Int -> (Int, VU.Vector Int) -> Int;powModByCache !power (!modulo, !cache) = foldl' step 1 [0 .. 62] where { step !acc !nBit = if testBit power nBit then acc * (cache VU.! nBit) `rem` modulo else acc};invModFC :: Int -> (Int, VU.Vector Int) -> Int;invModFC !primeModulo = powModByCache (primeModulo - 2);divModFC :: Int -> (Int, VU.Vector Int) -> Int;divModFC !x context@(!modulo, !_) = x * invModFC modulo context `rem` modulo;factMods :: Int -> Int -> VU.Vector Int;factMods !n !modulo = VU.scanl' (\ !x !y -> x * y `rem` modulo) (1 :: Int) $ VU.fromList [(1 :: Int) .. n];bcMod :: Int -> Int -> Int -> Int;bcMod !n !r !modulo = foldl' (\ !x !y -> divModF x y modulo) (facts VU.! n) [facts VU.! r, facts VU.! (n - r)] where { facts = factMods n modulo};prevPermutationVec :: (Ord e, VG.Vector v e, VG.Vector v (Down e)) => v e -> v e;prevPermutationVec = VG.map (\case { Down !x -> x}) . VG.modify (void . VGM.nextPermutation) . VG.map Down;dictOrderModuloVec :: (VG.Vector v Int) => v Int -> Int -> Int;dictOrderModuloVec xs modulo = runST $ do { !stree <- newSTreeVU (+) (VG.length xs + 1) (0 :: Int); let { !facts = factMods (VG.length xs) modulo}; !counts <- flip VG.imapM xs $ \ i x -> do { !nUsed <- fromJust <$> querySTree stree (0, x); let { !nUnused = x - nUsed}; let { !factMod = facts VG.! (VG.length xs - (i + 1))}; let { !inc = nUnused * factMod `rem` modulo}; insertSTree stree x 1; return inc}; return $! succ $! VG.foldl1' (\ !acc x -> (acc + x) `rem` modulo) counts};class TypeInt a where { typeInt :: Proxy a -> Int};newtype ModInt p = ModInt{toInt :: Int} deriving (Eq);instance Show (ModInt p) where { show = show . toInt};instance TypeInt p => Num (ModInt p) where { (ModInt !x1) + (ModInt !x2) = ModInt $! (x1 + x2) `mod` typeInt (Proxy @p); (ModInt !x1) * (ModInt !x2) = ModInt $! (x1 * x2) `mod` typeInt (Proxy @p); negate (ModInt !v) = ModInt $ (-v) `mod` typeInt (Proxy @p); abs = id; signum _ = 1; fromInteger = ModInt . fromInteger};instance TypeInt p => Fractional (ModInt p) where { recip (ModInt !x) = ModInt $! invModF x (typeInt (Proxy @p)); fromRational !r = ModInt n / ModInt d where { n = fromInteger $! Ratio.numerator r; d = fromInteger $! Ratio.denominator r}};instance (TypeInt p) => Enum (ModInt p) where { toEnum = ModInt . (`mod` typeInt (Proxy @p)); fromEnum = coerce};instance TypeInt p => SemigroupAction (Product (ModInt p)) (ModInt p) where { sact (Product !x1) !x2 = x1 * x2};newtype instance  VUM.MVector s (ModInt p) = MV_ModInt (VUM.MVector s Int);newtype instance  VU.Vector (ModInt p) = V_ModInt (VU.Vector Int);instance VU.Unbox (ModInt p);instance VGM.MVector VUM.MVector (ModInt p) where { basicLength (MV_ModInt v) = VGM.basicLength v; {-# INLINE basicLength #-}; basicUnsafeSlice i n (MV_ModInt v) = MV_ModInt $ VGM.basicUnsafeSlice i n v; {-# INLINE basicUnsafeSlice #-}; basicOverlaps (MV_ModInt v1) (MV_ModInt v2) = VGM.basicOverlaps v1 v2; {-# INLINE basicOverlaps #-}; basicUnsafeNew n = MV_ModInt <$> VGM.basicUnsafeNew n; {-# INLINE basicUnsafeNew #-}; basicInitialize (MV_ModInt v) = VGM.basicInitialize v; {-# INLINE basicInitialize #-}; basicUnsafeReplicate n x = MV_ModInt <$> VGM.basicUnsafeReplicate n (coerce x); {-# INLINE basicUnsafeReplicate #-}; basicUnsafeRead (MV_ModInt v) i = coerce <$> VGM.basicUnsafeRead v i; {-# INLINE basicUnsafeRead #-}; basicUnsafeWrite (MV_ModInt v) i x = VGM.basicUnsafeWrite v i (coerce x); {-# INLINE basicUnsafeWrite #-}; basicClear (MV_ModInt v) = VGM.basicClear v; {-# INLINE basicClear #-}; basicSet (MV_ModInt v) x = VGM.basicSet v (coerce x); {-# INLINE basicSet #-}; basicUnsafeCopy (MV_ModInt v1) (MV_ModInt v2) = VGM.basicUnsafeCopy v1 v2; {-# INLINE basicUnsafeCopy #-}; basicUnsafeMove (MV_ModInt v1) (MV_ModInt v2) = VGM.basicUnsafeMove v1 v2; {-# INLINE basicUnsafeMove #-}; basicUnsafeGrow (MV_ModInt v) n = MV_ModInt <$> VGM.basicUnsafeGrow v n; {-# INLINE basicUnsafeGrow #-}};instance VG.Vector VU.Vector (ModInt p) where { basicUnsafeFreeze (MV_ModInt v) = V_ModInt <$> VG.basicUnsafeFreeze v; {-# INLINE basicUnsafeFreeze #-}; basicUnsafeThaw (V_ModInt v) = MV_ModInt <$> VG.basicUnsafeThaw v; {-# INLINE basicUnsafeThaw #-}; basicLength (V_ModInt v) = VG.basicLength v; {-# INLINE basicLength #-}; basicUnsafeSlice i n (V_ModInt v) = V_ModInt $ VG.basicUnsafeSlice i n v; {-# INLINE basicUnsafeSlice #-}; basicUnsafeIndexM (V_ModInt v) i = coerce <$> VG.basicUnsafeIndexM v i; {-# INLINE basicUnsafeIndexM #-}; basicUnsafeCopy (MV_ModInt mv) (V_ModInt v) = VG.basicUnsafeCopy mv v; elemseq _ = seq; {-# INLINE elemseq #-}};data RollingHash b p = RollingHash{sourceLength :: !Int, dimensions :: !(VU.Vector Int), hashSum :: !(VU.Vector Int)} deriving (Show, Eq);data HashInt = HashInt;instance TypeInt HashInt where { typeInt _ = 100};newRH :: forall p . TypeInt p => String -> RollingHash HashInt p;newRH !source = RollingHash n bn hashSum_ where { !p = typeInt (Proxy @p); !b = typeInt (Proxy @HashInt); !n = length source; !bn = VU.iterateN (succ n) (\ lastB -> b * lastB `mod` p) (1 :: Int); !hashSum_ = evalState (VU.mapM (\ !ch -> state $ \ !acc -> f ch acc) $ VU.fromList source) (0 :: Int) where { f :: Char -> Int -> (Int, Int); f !ch !lastX = dupe $! (lastX * b + ord ch) `mod` p}};lengthRH :: RollingHash b p -> Int;lengthRH (RollingHash !len !_ !_) = len;data HashSlice p = HashSlice{hashValue :: {-# UNPACK #-} !Int, hashLength :: {-# UNPACK #-} !Int} deriving (Show, Eq);sliceRH :: forall b p . (TypeInt p) => RollingHash b p -> Int -> Int -> HashSlice p;sliceRH (RollingHash !_ !bn !s) !i0 !i1 | i0 > i1 = emptyHS | otherwise = let { !len = i1 - i0 + 1; !s1 = s VU.! i1; !s0 = fromMaybe 0 $ s VU.!? pred i0; !value = (s1 - (bn VU.! len) * s0) `mod` p} in HashSlice value len where { !p = typeInt (Proxy @p)};consHS :: forall b p . (TypeInt p) => RollingHash b p -> HashSlice p -> HashSlice p -> HashSlice p;consHS (RollingHash !_ !bn !_) (HashSlice !v0 !l0) (HashSlice !v1 !l1) = HashSlice value len where { !p = typeInt (Proxy @p); !value = ((bn VU.! l1) * v0 + v1) `mod` p; !len = l0 + l1};emptyHS :: HashSlice p;emptyHS = HashSlice 0 0;concatHS :: forall b p t . (TypeInt p, Foldable t) => RollingHash b p -> t (HashSlice p) -> HashSlice p;concatHS !rhash !slices = foldl' (consHS rhash) emptyHS slices;mulMatToCol :: (Num e, IArray UArray e) => UArray (Int, Int) e -> [e] -> [e];mulMatToCol !mat !col = let { !rows = chunksOf n (elems mat)} in map (sum . zipWith (*) col) rows where { !n = length col; !_ = dbgAssert $ (== n) . succ . fst . snd $ bounds mat};mulMat :: (Num e, IArray UArray e) => UArray (Int, Int) e -> UArray (Int, Int) e -> UArray (Int, Int) e;mulMat !a !b = listArray @UArray ((i0, k0), (ix, kx)) [sum [a ! (i, j) * b ! (j', k) | (j, j') <- zip (range (j0, jx)) (range (j'0, j'x))] | i <- range (i0, ix), k <- range (k0, kx)] where { ((!i0, !j0), (!ix, !jx)) = bounds a; ((!j'0, !k0), (!j'x, !kx)) = bounds b; !_ = dbgAssert (jx - j0 == j'x - j'0)};mulMatMod :: Int -> UArray (Int, Int) Int -> UArray (Int, Int) Int -> UArray (Int, Int) Int;mulMatMod m a b = listArray @UArray ((i0, k0), (ix, kx)) [sum [a ! (i, j) * b ! (j', k) `mod` m | (j, j') <- zip (range (j0, jx)) (range (j'0, j'x))] `mod` m | i <- range (i0, ix), k <- range (k0, kx)] where { ((!i0, !j0), (!ix, !jx)) = bounds a; ((!j'0, !k0), (!j'x, !kx)) = bounds b; !_ = dbgAssert (jx - j0 == j'x - j'0)};unitMat :: Int -> UArray (Int, Int) Int;unitMat !n = accumArray @UArray (+) (0 :: Int) ((0, 0), (pred n, pred n)) $ map ((, 1) . dupe) [0 .. pred n];newtype MulMatMod a = MulMatMod (UArray (Int, Int) Int) deriving (Eq, Show);instance forall p . TypeInt p => Semigroup (MulMatMod p) where { (MulMatMod !m1) <> (MulMatMod !m2) = MulMatMod $ mulMatMod (typeInt (Proxy @p)) m1 m2};rot45 :: (Int, Int) -> (Int, Int);rot45 (!x, !y) = (x - y, x + y);mDigitsRev :: Integral n => n -> n -> Maybe [n];mDigitsRev !base !i = if base < 1 then Nothing else Just $ dr base i where { dr _ 0 = []; dr !b !x = case base of { 1 -> genericTake x $ repeat 1; _ -> let { (!rest, !lastDigit) = quotRem x b} in lastDigit : dr b rest}};mDigits :: Integral n => n -> n -> Maybe [n];mDigits !base !i = reverse <$> mDigitsRev base i;digitsRev :: Integral n => n -> n -> [n];digitsRev !base = fromJust . mDigitsRev base;digits :: (Integral n) => n -> n -> [n];digits _ 0 = [0]; digits !base !x = reverse $ digitsRev base x;unDigits :: Integral n => n -> [n] -> n;unDigits !base = foldl' (\ !a !b -> a * base + b) 0;convertBase :: Integral a => a -> a -> [a] -> [a];convertBase !from !to = digits to . unDigits from;primes :: [Int];primes = 2 : 3 : minus [5, 7 ..] (unionAll [[p * p, p * p + 2 * p ..] | p <- tail primes]) where { minus (x : xs) (y : ys) = case compare x y of { LT -> x : minus xs (y : ys); EQ -> minus xs ys; GT -> minus (x : xs) ys}; minus xs _ = xs; union (x : xs) (y : ys) = case compare x y of { LT -> x : union xs (y : ys); EQ -> x : union xs ys; GT -> y : union (x : xs) ys}; union xs [] = xs; union [] ys = ys; unionAll :: Ord a => [[a]] -> [a]; unionAll ((x : xs) : t) = x : union xs (unionAll $ pairs t) where { pairs ((x : xs) : (ys : t)) = (x : union xs ys) : pairs t}; unionAll _ = error "unionAll: unreachable"};primeFactors :: Int -> [(Int, Int)];primeFactors !n_ = map (\ !xs -> (head xs, length xs)) . group $ inner n_ input where { input = 2 : 3 : [y | x <- [5, 11 ..], y <- [x, x + 2]]; inner n pps@(p : ps) | n == 1 = [] | n < p * p = [n] | r == 0 = p : inner q pps | otherwise = inner n ps where { (q, r) = divMod n p}; inner _ _ = error "unreachable"};divisorsOf :: Int -> [Int];divisorsOf n = sort $ inner 1 where { inner k | k * k > n = [] | k * k == n = [k] | r == 0 = k : d : inner (succ k) | otherwise = inner (succ k) where { (!d, !r) = n `divMod` k}}
{- ORMOLU_ENABLE -}
-- }}}

data MyModulo = MyModulo

instance TypeInt MyModulo where
  -- typeInt _ = 1_000_000_007
  typeInt _ = 998244353

type MyModInt = ModInt MyModulo

modInt :: Int -> MyModInt
modInt = ModInt . (`mod` typeInt (Proxy @MyModulo))

undef :: Int
undef = -1

main :: IO ()
main = do
  !n <- int
  !input <- VU.replicateM n ints3

  -- edges @! (vTo, vFrom) -> cost
  let !edges = IxVector (both dupe (0, n - 1)) . VU.generate (n * n) $ \i ->
        let (!v2, !v1) = i `divMod` n
            (!x1, !y1, !z1) = input VU.! v1
            (!x2, !y2, !z2) = input VU.! v2
            !w = abs (x1 - x2) + abs (y1 - y2) + max 0 (z2 - z1)
         in w

  let !undefCost = maxBound @Int

  -- N' = 2^17 = 131072 ~ 10^5. N * N' seems to be safe.
  let !nSets = bit n :: Int

  -- TODO: Refactor
  let !tsp = VU.constructN (n * nSets) f
        where
          f !vec
            -- initially at vertex zero
            | VU.length vec < 2 * n =
                if VU.length vec == n then 0 else undefCost
            -- unvisitable
            | not (testBit s v2) = undefCost
            -- relax
            | otherwise =
                let !s' = clearBit s v2
                    g !v1 !acc
                      | not (testBit s v1) || acc == undefCost = undefCost
                      | otherwise = acc + (edges @! (v2, v1))
                 in VU.minimum $ VU.imap g (VU.slice (n * s') n vec)
            where
              (!s, !v2) = (vLength vec) `divMod` n

  let !_ = dbg (tsp)

  let !finals = VU.slice (n * pred nSets) n tsp
  let !results = flip VU.imap finals \v2 acc -> acc + edges @! (0, v2)

  print $ VU.minimum results

Submission Info

Submission Time
Task E - Traveling Salesman among Aerial Cities
User toyboot4e
Language Haskell (GHC 8.8.3)
Score 500
Code Size 83680 Byte
Status AC
Exec Time 194 ms
Memory 23052 KiB

Compile Error

Loaded package environment from /home/contestant/.ghc/x86_64-linux-8.8.3/environments/default

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 500 / 500
Status
AC × 3
AC × 23
Set Name Test Cases
Sample sample_01.txt, sample_02.txt, sample_03.txt
All random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_09.txt, random_10.txt, random_11.txt, random_12.txt, random_13.txt, random_14.txt, random_15.txt, random_16.txt, random_17.txt, random_18.txt, random_19.txt, random_20.txt, sample_01.txt, sample_02.txt, sample_03.txt
Case Name Status Exec Time Memory
random_01.txt AC 193 ms 22812 KiB
random_02.txt AC 2 ms 4288 KiB
random_03.txt AC 193 ms 22932 KiB
random_04.txt AC 189 ms 22928 KiB
random_05.txt AC 188 ms 22940 KiB
random_06.txt AC 3 ms 4132 KiB
random_07.txt AC 193 ms 22824 KiB
random_08.txt AC 24 ms 7272 KiB
random_09.txt AC 191 ms 23052 KiB
random_10.txt AC 3 ms 4304 KiB
random_11.txt AC 194 ms 22928 KiB
random_12.txt AC 6 ms 4580 KiB
random_13.txt AC 194 ms 22932 KiB
random_14.txt AC 2 ms 4292 KiB
random_15.txt AC 191 ms 22812 KiB
random_16.txt AC 15 ms 6196 KiB
random_17.txt AC 192 ms 22892 KiB
random_18.txt AC 15 ms 6068 KiB
random_19.txt AC 189 ms 22908 KiB
random_20.txt AC 27 ms 7424 KiB
sample_01.txt AC 2 ms 4316 KiB
sample_02.txt AC 2 ms 4356 KiB
sample_03.txt AC 191 ms 22840 KiB