#include <bits/stdc++.h>
using namespace std;

// macros
#define rep(i, n) for(ll i = 0; i < (ll)(n); i++)
#define rrep(i, n) for(ll i = (ll)(n) - 1; i >= 0; i--)
#define mfor(i, s, t) for(ll i = (ll)(s); i < (ll)(t); i++)

// type alias
using ll = long long;

// const value
const ll mod = 1000000007;
const ll inf = 1000000000000LL;

// meta programming
template<typename F> class res_type_;
template<typename R, typename... Args> class res_type_<R(*)(Args...)> {
public:
	using type = R;
};
template<typename R, typename... Args> class res_type_<function<R(Args...)>> {
public:
	using type = R;
};
template<typename F> class res_type_ {
public:
	using type = typename res_type_<decltype(+declval<F>())>::type;
};
template<typename F> using res_type = typename res_type_<F>::type;

template<typename V> class mem_type_;
template<typename T> class mem_type_<vector<T>> {
public:
	using type = T;
};
template<typename V> using mem_type = typename mem_type_<V>::type;

// functions for functional programming
auto v_range(ll n) {
	vector<ll> ret;
	ret.reserve(n);
	rep(i, n) {
		ret.push_back(i);
	}
	return ret;
}
template<typename F> auto v_init(ll n, F f) {
	vector<res_type<F>> ret;
	ret.reserve(n);
	rep(i, n) {
		ret.push_back(f(i));
	}
	return ret;
}
template<typename T> auto v_rev(const vector<T>& v) {
	vector<T> ret;
	ret.reserve(v.size());
	rrep(i, v.size()) {
		ret.push_back(v[i]);
	}
	return ret;
}
template<typename T, typename F> void v_iter(const vector<T>& v, F f) {
	for(const auto& i: v) {
		f(i);
	}
}
template<typename T, typename F> auto v_map(const vector<T>& v, F f) {
	vector<res_type<F>> ret;
	ret.reserve(v.size());
	for(const auto& i: v) {
		ret.push_back(f(i));
	}
	return ret;
}
template<typename T, typename R, typename F> auto v_fold(const vector<T>& v, R r, F f) {
	for(const auto& i: v) {
		r = f(r, i);
	}
	return r;
}
template<typename T, typename F> auto v_filter(const vector<T>& v, F f) {
	vector<T> ret;
	for(const auto& i: v) {
		if(f(i)) {
			ret.push_back(i);
		}
	}
	return ret;
}
template<typename T, typename F> auto v_fmap(const vector<T>& v, F f) {
	vector<mem_type<res_type<F>>> ret;
	for(const auto& i: v) {
		for(const auto& j: f(i)) {
			ret.push_back(j);
		}
	}
	return ret;
}
template<typename T, typename F> bool v_forall(const vector<T>& v, F f) {
	for(const auto& i: v) {
		if(!f(i)) {
			return false;
		}
	}
	return true;
}
template<typename T, typename F> bool v_exists(const vector<T>& v, F f) {
	for(const auto& i: v) {
		if(f(i)) {
			return true;
		}
	}
	return false;
}
template<typename T, typename F> ll v_find(const vector<T>& v, F f) {
	rep(i, v.size()) {
		if(f(v[i])) {
			return i;
		}
	}
	return -1;
}
template<typename T> auto v_with_index(const vector<T>& v) {
	vector<pair<ll, T>> ret;
	ret.reserve(v.size());
	rep(i, v.size()) {
		ret.push_back(make_pair(i, v[i]));
	}
	return ret;
}
template<typename T, typename U> auto v_zip(const vector<T>& t, const vector<U>& u) {
	assert(t.size() == u.size());
	vector<pair<T, U>> ret;
	ret.reserve(t.size());
	rep(i, t.size()) {
		ret.push_back(make_pair(t[i], u[i]));
	}
	return ret;
}
template<typename T, typename U> auto v_unzip(const vector<pair<T, U>>& v) {
	vector<T> t;
	vector<U> u;
	t.reserve(v.size());
	u.reserve(v.size());
	for(const auto& i: v) {
		t.push_back(i.first);
		u.push_back(i.second);
	}
	return make_pair(t, u);
}
template<typename T> auto v_with_next(const vector<T>& v) {
	assert(v.size() >= 2);
	vector<pair<T, T>> ret;
	ret.reserve(v.size() - 1);
	rep(i, v.size() - 1) {
		ret.push_back(make_pair(v[i], v[i + 1]));
	}
	return ret;
}
template<typename T> auto v_with_next_circle(const vector<T>& v) {
	assert(v.size() >= 2);
	vector<pair<T, T>> ret;
	ret.reserve(v.size());
	rep(i, v.size() - 1) {
		ret.push_back(make_pair(v[i], v[i + 1]));
	}
	ret.push_back(make_pair(v.back(), v[0]));
	return ret;
}
template<typename T> T v_sum(const vector<T>& v) {
	assert(!v.empty());
	T now = v[0];
	mfor(i, 1, v.size()) {
		now = now + v[i];
	}
	return now;
}
template<typename T> T v_min(const vector<T>& v) {
	assert(!v.empty());
	T now = v[0];
	mfor(i, 1, v.size()) {
		if(v[i] < now) {
			now = v[i];
		}
	}
	return now;
}
template<typename T> pair<T, ll> v_min_index(const vector<T>& v) {
	assert(!v.empty());
	T now = v[0];
	ll ind = 0;
	mfor(i, 1, v.size()) {
		if(v[i] < now) {
			now = v[i];
			ind = i;
		}
	}
	return make_pair(now, ind);
}
template<typename T> T v_max(const vector<T>& v) {
	assert(!v.empty());
	T now = v[0];
	mfor(i, 1, v.size()) {
		if(now < v[i]) {
			now = v[i];
		}
	}
	return now;
}
template<typename T> pair<T, ll> v_max_index(const vector<T>& v) {
	assert(!v.empty());
	T now = v[0];
	ll ind = 0;
	mfor(i, 1, v.size()) {
		if(now < v[i]) {
			now = v[i];
			ind = i;
		}
	}
	return make_pair(now, ind);
}

// for convenience
template<typename K, typename V> class order_tag {
public:
	K key;
	V value;
	order_tag(K k, V v): key(k), value(v) {}
	bool operator==(const order_tag& o) const {
		return key == o.key;
	}
	bool operator!=(const order_tag& o) const {
		return key != o.key;
	}
	bool operator<(const order_tag& o) const {
		return key < o.key;
	}
	bool operator<=(const order_tag& o) const {
		return key <= o.key;
	}
	bool operator>(const order_tag& o) const {
		return key > o.key;
	}
	bool operator>=(const order_tag& o) const {
		return key >= o.key;
	}
};
template<typename K, typename V> auto tagging(const K& k, const V& v) {
	return order_tag<K, V>(k, v);
}
template<typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
	os << p.first << " " << p.second;
	return os;
}
template<typename K, typename V> ostream& operator<<(ostream& os, const order_tag<K, V>& p) {
	os << p.key << " " << p.value;
	return os;
}
template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
	rep(i, v.size()) {
		if(i > 0) {
			os << " ";
		}
		os << v[i];
	}
	return os;
}

int main() {
	ll n;
	cin >> n;
	vector<ll> x(n), y(n), h(n);
	rep(i, n) {
		cin >> x[i] >> y[i] >> h[i];
	}
	rep(i, 101) {
		rep(j, 101) {
			bool ok = true;
			ll ma = inf;
			ll ac = -1;
			rep(k, n) {
				if(h[k] == 0) {
					ma = min(ma, abs(i - x[k]) + abs(j - y[k]));
				}
				else {
					ll w = h[k] + abs(i - x[k]) + abs(j - y[k]);
					if(ac < 0) {
						ac = w;
					}
					else if(ac != w) {
						ok = false;
						break;
					}
				}
			}
			if(ok && 0 < ac && ac <= ma) {
				cout << i << " " << j << " " << ac << endl;
				exit(0);
			}
		}
	}
	return 0;
}


Measured memory_bytes: 256