{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
import qualified Data.ByteString.Lazy.Char8 as B
import Data.Maybe
import Data.List
import qualified Data.Vector.Unboxed as VU
-- import qualified Data.Vector.Unboxed.Mutable as VUM
-- import Control.Monad
-- import Control.Monad.ST
-- import Debug.Trace
trace _ = id

data Plane = Plane {p_ry::Int, p_rx::Int, p_z0::Int}
           deriving (Eq, Ord, Show)

solve :: Int -> Int -> [[Int]] ->
         Maybe (Int, Int, [(Int, Int, String)], Int, Int)
solve a b d | possible = Just build
            | otherwise = Nothing
  where
    vd = VU.fromListN (a*b) (concat d)
    enc y x = (y-1) * b + (x-1)
    valyx y x | trace ("valyx" ++ show (y,x)) False = undefined
    valyx y x = vd VU.! (enc (min y a) (min x b))
    tri' = [ptPlane y x | y <- [1..a], x <- [1..b]]
    ptPlane y x = catMaybes [mkPlane y x dy dx | dy <- [-1,1], dx <- [-1,1]]
    mkPlane y x dy dx | trace ("mkPlane(in) " ++ show (y,x,dy,dx)) False
      = undefined
    mkPlane y x dy dx = trace ("mkPlane " ++ show (y,x,dy,dx,a)) a
      where a = mkPlane' y x dy dx
    mkPlane' y x dy dx
      | outRangeY y || outRangeY (y+dy) || outRangeX x || outRangeX (x+dx)
        || rx < 0 || ry < 0 || z0 < 0 || not (checkConvex ry rx z0)
      = Nothing
      | otherwise
      = Just (Plane ry rx z0) 
      where v0 = valyx y x
            ry = (valyx (y+dy) x - v0) `div` dy
            rx = (valyx y (x+dx) - v0) `div` dx
            z0 = v0 - ry*y - rx*x
            outRangeY y = y < 1 || (a+1) < y
            outRangeX x = x < 1 || (b+1) < x
    yxPair = [(y,x) | y <- [1..a], x <- [1..b]]
    checkConvex ry rx z0
      = all (\(y,x) -> ry*y + rx*x + z0 >= valyx y x) yxPair

    possible = all (not . null) tri'
    tri = nub $ map minimum tri'
    yMax = maximum $ map p_ry tri
    safeMax [] = 0
    safeMax xs = maximum xs
    lxMax = [safeMax $ map p_rx $ filter ((== ry) . p_ry) tri
            | ry <- [0..yMax]]
    board = [(u+1,v+1,c) | (u,v,c) <- boardM]
    boardM = [connY y | y <- [0..yMax-1]]
             ++ [connX y x | y <- [0..yMax-1], x <- [0 .. (lxMax !! y) - 1]]
             ++ [connP p | p <- tri]
    connY y = (bEncY y, bEncY (y+1), "Y")
    connX y x = (bEncX y x, bEncX y (x+1), "X")
    connP (Plane ry rx z0) = (bEncX ry rx, bEncT, show z0)
    bEncY y = y
    bEncX y 0 = bEncY y
    bEncX y x = (yMax+1) + (accXMax !! y) + (x-1)
    bEncT = (yMax+1) + (accXMax !! (yMax+1)) 
    accXMax = scanl' (+) 0 lxMax
    build = (bEncT + 1, length board, board, 1, bEncT + 1)

readBInt :: B.ByteString -> Int
readBInt = fst . fromJust . B.readInt

tmain :: B.ByteString -> Maybe (Int, Int, [(Int, Int, String)], Int, Int)
tmain cont =
  let remLines0 = map B.words (B.lines cont)
      [bs_a,bs_b]:remLines1 = remLines0
      a = readBInt bs_a
      b = readBInt bs_b
      d = map (map readBInt) remLines1
  in solve a b d

outAnswer :: Maybe (Int, Int, [(Int, Int, String)], Int, Int) -> IO ()
outAnswer Nothing               = putStrLn "Impossible"
outAnswer (Just (n,m,uvcs,s,t)) = do
  putStrLn "Possible"
  putStrLn $ unwords $ map show [n,m]
  putStr $ unlines $ map (\(u,v,s) -> unwords [show u, show v, s]) uvcs
  putStrLn $ unwords $ map show [s,t]

main :: IO ()
main = outAnswer . tmain =<< B.getContents
