import Control.Monad
import Data.List

pm_list2 :: [Int] -> ([Int], [Int])
pm_list2 ls =
  let n = length ls
   in splitAt (div n 2) $ sort ls

max_val2 :: ([Int], [Int]) -> Int
max_val2 (m, p) = (sum p) - (sum m)

construct_op2 :: Bool -> ([Int], [Int]) -> [(Int, Int)]
construct_op2 is_even (m, p) =
  if is_even
    then let rev = reverse $ concat [[pp, mm] | (pp, mm) <- (zip p m)]
          in eater (head rev) (tail rev)
    else let rev =
               reverse $
               ((head p) : (concat [[mm, pp] | (pp, mm) <- (zip (tail p) m)]))
          in eater (head rev) (tail rev)

eater :: Int -> [Int] -> [(Int, Int)]
eater now [] = []
eater now (x:xs) = (x, now) : (eater (x - now) xs)

solver :: [Int] -> (Int, [(Int, Int)])
solver ls =
  let (m, p) = pm_list2 ls
   in (max_val2 (m, p), construct_op2 (even $ length ls) (m, p))

main :: IO ()
main = do
  _ <- getLine
  dat <- (map read . words) <$> getLine
  let (v, ls) = solver dat
  print v
  forM_ ls (\(x, y) -> putStrLn $ show x ++ " " ++ show y)
