{-# LANGUAGE Strict #-}

import Data.ByteString.Char8 qualified as B
import Data.IntMap.Strict qualified as M
import Control.Monad
import Data.List
import Data.Graph
import Data.Array.Unboxed
import Data.Array.ST
import Control.Monad.ST
import Control.Monad.Trans.Maybe
import Control.Monad.Trans
import Data.Foldable

data UnionFind s
 = UnionFind
 { pa :: STUArray s Int Int
 , sz :: STUArray s Int Int
 }
mkUnionFind :: Int -> ST s (UnionFind s)
mkUnionFind n = UnionFind
 <$> newListArray (1,n) [1..n]
 <*> newArray (1,n) 1
ufind uf i = do
 p <- readArray (pa uf) i
 if p == i
    then pure i
    else ufind uf p >>= \p' -> p' <$ writeArray (pa uf) i p'
uunion uf i' j' = bothM (ufind uf) (i',j') >>= \(i,j) -> when (i /= j) $ do
 readArray (sz uf) i >>= modifyArray' (sz uf) j . (+)
 writeArray (pa uf) i j

int = (\(Just (x,_)) -> x) . B.readInt
intl = map int . B.words <$> B.getLine

ranks :: STUArray s Int Int -> [Int] -> ST s (Int -> ST s Int, Int -> Int, Int)
ranks a xs = do
  forM_ xs $ \i -> writeArray a i 0
  (n, order) <- foldM (\(c,acc) i -> do
    o <- readArray a i
    if o == 0
       then (c + 1, (c, i) : acc) <$ writeArray a i c
       else pure (c, acc))
    (1,[])
    xs
  let invRank :: UArray Int Int = array (1, n - 1) order
  pure (readArray a, (invRank !), n - 1)

twoColour :: Graph -> Maybe [([Int], [Int])]
twoColour g
  | any (\(u,v) -> (colours!u) == (colours!v)) (edges g) = Nothing
  | otherwise = Just $ partition ((>0) . (colours!)) . toList <$> comps
 where
  (1, n) = bounds g
  comps = dff g
  colours :: UArray Int Int = runSTUArray $ do
    col <- newArray (1, n) (-1)
    let colour c (Node i ch) = writeArray col i c >> mapM_ (colour (1 - c)) ch
    col <$ mapM_ (colour 0) comps

bothM f (a,b) = (,) <$> f a <*> f b

solve :: Int -> [[(Int, Int)]] -> MaybeT (ST s) Int
solve n evs = do
 uf <- lift (mkUnionFind n)
 rankA <- lift (newArray (1,n) 0)
 fmap sum $ forM evs $ \ev -> do
  ev <- lift $ forM ev $ bothM (ufind uf)
  when (any (uncurry (==)) ev) $ fail "contradiction"
  (rank, invRank, n) <- lift (ranks rankA $ concatMap (\(u,v) -> [u,v]) ev)
  g <- lift $ buildG (1,n) . concat <$> forM ev (fmap (\(u,v) -> [(u,v), (v,u)]) . bothM rank)
  colourClasses <- hoistMaybe $ twoColour g
  res <- lift $ sum . map (uncurry min) <$> forM colourClasses (bothM (fmap sum . mapM (readArray (sz uf) . invRank)))
  lift $ forM_ ev $ uncurry (uunion uf)
  pure res


main = do
 [n,m] <- intl
 events :: M.IntMap [(Int,Int)] <- foldl' (\m [u,v,t] -> M.alter (Just . maybe [(u,v)] ((u,v):)) t m) M.empty
   <$> replicateM m intl
 putStrLn $ maybe "impossible" (("possible\n"++) . show) $ runST $ runMaybeT $ solve n $ reverse $ M.elems events
