// Original C++ solution (slower):
#include <bits/stdc++.h>

#define rep(i,n) for (int i = 0; i < (n); i++)

#define repf(i,a,b) for (int i = (a); i < (b); i++)

#define repi(i,a,b) for (int i = (a); i <= (b); i++)

#define repr(i,a,b) for (int i = (a); i >= (b); i--)

#define all(x) (x).begin(),(x).end()

#define rall(x) (x).rbegin(),(x).rend()

#define debug(x)  cout << #x << " = " << (x) << endl;

#define SORT(x) sort(all(x));

#define RSORT(x) sort(rall(x));

using namespace std;

using ll = long long;

using vi = vector<int>;

using vvi = vector<vi>;

using vd = vector<double>;

using vb = vector<bool>;

using pii = pair<int, int>;

using vc = vector<char>;

using vvc = vector<vc>;

using vs = vector<string>;

using tiii = tuple<int, int, int>;

const int inf = 1<<29;

const ll mod = 1000000007;

const double eps = 1e-9;

const int dx[4] = {1,0,-1,0};

const int dy[4] = {0,1,0,-1};

//cout << fixed << setprecision(10);



ll N, x[1009], y[1009], h[1009]; vector<tuple<ll,ll,ll>> vec;



int main () {

  cin >> N;

  tuple<ll,ll,ll> G = make_tuple(-1,-1,-1);



  for (int i = 1; i <= N; i++) {

    cin >> x[i] >> y[i] >> h[i];

    if (h[i] >= 1) G = make_tuple(x[i],y[i],h[i]);

  }

  for(int Cx = 0; Cx <= 100; Cx++) {

    for (int Cy = 0; Cy <= 100; Cy++) {

      ll H = get<2>(G) + abs(get<0>(G)-Cx) + abs(get<1>(G)-Cy);

      H = max(H,0LL);

      bool flag = true;

      for (int i = 1; i <= N; i++) {

        ll hh = H - abs(x[i]-Cx) - abs(y[i]-Cy);

        hh = max(hh,0LL);

        if (h[i] != hh) flag = false;

      }

      if(flag == true) vec.push_back(make_tuple(Cx,Cy,H));

    }

  }



  if (vec.size() == 1) {

    cout << get<0>(vec[0]) << " " << get<1>(vec[0]) << " " << get<2>(vec[0]) << endl;

  }

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)

#define RFOR(i,a,b) for (int i = (b)-1; i >= (a); --i)

#define REP(i,n) FOR(i,0,(n))

#define REPS(i,n) FOR(i,1,(n)+1)

#define RREP(i,n) RFOR(i,0,(n))

#define ALL(x) (x).begin(),(x).end()

#define RALL(x) (x).rbegin(),(x).rend()

#define DEBUG(x)  cout << #x << " = " << (x) << endl;

#define SORT(x) sort(ALL(x));

#define RSORT(x) sort(RALL(x));

#define SUM(x) accumulate(ALL(x),0);

#define FI first

#define SE second

#define PB push_back

#define EB emplace_back

#define SZ(x) (int)(x).size()

#define BN(x) ((1<<x)-1)

#define DUP(x,y) (((x)+(y)-1)/(y))

using namespace std;

using ll = long long;

using vi = vector<int>;

using vvi = vector<vi>;

using pii = pair<int, int>;

using tiii = tuple<int, int, int>;

const ll mod = 1e9+7;

const int INF = (1<<30)-1;

const ll INFLL = (1LL<<62)-1;

const int dx[4] = {1,0,-1,0};

const int dy[4] = {0,1,0,-1};

//cout << fixed << setprecision(10);



template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }

template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }



ll gcd(ll a, ll b) { return b ? gcd(b,a%b) : a;}

ll lcm(ll a, ll b) { return a/gcd(a,b)*b;}



int main () {

  int N; cin >> N;

  vi x(N), y(N), h(N); REP(i,N) cin >> x[i] >> y[i] >> h[i];



  int H, Cx, Cy;

  int is;

  REP(i,N) {

    if (h[i] != 0) {

      is = i;

    }

  }



  REP(Cx,101) {

    REP(Cy,101) {

      bool flag = true;

      H = h[is]+abs(x[is]-Cx)+abs(y[is]-Cy);

      REP(i,N) {

        if (h[i]==0) {

          if (H-abs(x[i]-Cx)-abs(y[i]-Cy)>0) {

            flag = false;

            break;

          }

        }

        else {

          if (h[i]!=H-abs(x[i]-Cx)-abs(y[i]-Cy)) {

            flag = false;

            break;

          }

        }

      }

      if (flag == true) {

        printf("%d %d %d\n",Cx,Cy,H);

        return 0;

      }

    }

  }

  return 0;

}

// Fastest known solution for this problem: