{-# LANGUAGE OverloadedStrings #-}
import Data.Maybe
import Data.Char
import Data.List
import Data.Array
import Control.Monad
import Control.Monad.Reader
import qualified Data.ByteString.Char8 as BS
import qualified Data.Vector.Unboxed as VU

main = do
  n <- getInt
  ps <- replicateM n $ do
    [a, b, h] <- getIntList
    return ((a, b), h)
  putStrLn . unwords . map show. solve $ ps

solve :: [((Int, Int), Int)] -> [Int]
solve ps = head [[cx, cy, h]| cx <- [0..100], cy <- [0..100], let c = (cx, cy), let h = height c p, check c h ps]
  where
    p = head . filter ((/=0).snd) $ ps
    height (cx, cy) ((x, y), h) = h + (abs (cx - x)) + (abs (cy - y))
    check c ch ps = all (f c) ps
      where
        f c q@((x, y), h)
          | h == 0 = ch > height c q
          | otherwise = ch == height c q

-- IO
readInt :: BS.ByteString -> Int
readInt = fst . fromJust . BS.readInt

getInt :: IO Int
getInt = readInt <$> BS.getLine

getIntList :: IO [Int]
getIntList = unfoldr (BS.readInt . BS.dropWhile isSpace) <$> BS.getLine

getIntVec :: Int -> IO (VU.Vector Int)
getIntVec n = VU.unfoldrN n (BS.readInt . BS.dropWhile isSpace) <$> BS.getLine