#if 1
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <array>
#include <deque>
#include <algorithm>
#include <utility>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <numeric>
#include <assert.h>
#include <bitset>

auto& in = std::cin;
auto& out = std::cout;

int32_t N;
int32_t A[40000];
int32_t B[40000];
int32_t C[40000];

std::pair<double, int32_t> zero_V[40000];
std::pair<double, int32_t> tmp_V[40000];
int32_t zero_V_pos[40000];//i番目のzero_Vのindex

void func_xtoy(double X, std::pair<double, int32_t>(& res)[40000])
{
	for (size_t i = 0; i < N; i++)
	{
		res[i].first = double(C[i] - A[i] * X) / B[i];
		res[i].second = -zero_V_pos[i];
	}
	std::sort(res, res + N);
}
void func_ytox(double Y, std::pair<double, int32_t>(&res)[40000])
{
	for (size_t i = 0; i < N; i++)
	{
		res[i].first = double(C[i] - B[i] * Y) / A[i];
		res[i].second = -zero_V_pos[i];
	}
	std::sort(res, res + N);
}

template<typename FUNC>
//区間[b,e)　でf(r)==trueとなる最大のrを探す
//predの条件：(f(i) == true && f(j) == false) ==> (i < j)
//　　　　　　f(b) == true && f(e) == false
double binary_search_D(double b, double e, FUNC&& f)
{
	for (size_t i = 0; i < 70; ++i)
	{
		auto mid = (b + e) / 2;
		if (f(mid)) {
			b = mid;
		}
		else {
			e = mid;
		}
	}
	return b;
}

inline constexpr uint32_t get_min2pow(uint32_t value, uint32_t work = 1) {
	return ((value <= work) ? (work) : (get_min2pow(value, work * 2)));
}
template<typename value_type_, uint32_t N_RAW_MAX>
class segment_tree
{
public:
	using value_type = value_type_;
	static constexpr uint32_t N_MAX = get_min2pow(N_RAW_MAX);
private:
	value_type default_value;
	value_type value[N_MAX * 2 - 1] = {};
	static inline constexpr int32_t getchild(int i) {
		return i * 2 + 1;
	}
	static inline constexpr int32_t getparent(int i) {
		return (i - 1) / 2;
	}
	void Init_impl(int k = 0)
	{
		if (k < N_MAX - 1) {
			//ノード
			auto c1 = getchild(k), c2 = c1 + 1;
			Init_impl(c1);
			Init_impl(c2);
			value[k] = merge(value[c1], value[c2]);
		}
		else {
			//葉
			value[k] = default_value;
		}
	}
	value_type query_impl(int32_t a, int32_t b, int32_t k = 0, int32_t l = 0, int32_t r = N_MAX)const
	{
		if (r <= a || b <= l)return default_value;
		if (a <= l && r <= b)return value[k];
		int m = (l + r) / 2;
		return merge(query_impl(a, b, getchild(k), l, m), query_impl(a, b, getchild(k) + 1, m, r));
	}

public:
	template<typename T, typename FUNC = std::plus<>>
	void change(int32_t i, T&& v, FUNC&& operation = std::plus<>{})
	{
		i += N_MAX - 1;
		//葉
		value[i] = std::forward<FUNC>(operation)(std::move(value[i]), std::forward<T>(v));
		i = getparent(i);
		//ノード
		for (;;) {
			auto c1 = getchild(i), c2 = c1 + 1;
			value[i] = merge(value[c1], value[c2]);
			if (i == 0) { break; }
			i = getparent(i);
		}
	}

	//-----------------------------変更するコードここから-----------------------------//
private:
	static inline value_type merge(const value_type& l, const value_type& r)
	{
		//RSQ
		return l + r;
	}
public:
	inline void init()
	{
		default_value = 0;
		Init_impl();
	}
	inline value_type query(int32_t a, int32_t b)const
	{
		return query_impl(a, b);
	}
};

segment_tree<int32_t, 40000> sgt;
int main()
{
	using std::endl;
	in.sync_with_stdio(false);
	out.sync_with_stdio(false);
	in.tie(nullptr);
	out.tie(nullptr);

	in >> N;
	for (int32_t i = 0; i < N; i++)
	{
		in >> A[i] >> B[i] >> C[i];
	}

	//Xを求める！！！
	for (int32_t i = 0; i < N; i++)
	{
		zero_V_pos[i] = i;
	}
	func_xtoy(-1000000000.0, zero_V);
	for (int32_t i = 0; i < N; i++)
	{
		zero_V_pos[-zero_V[i].second] = i;
	}
	double X_RES = binary_search_D(-1000000000.0,+1000000000.0,
		[](double X) {
		func_xtoy(X, tmp_V);
		sgt.init();
		//交差回数を求める
		int32_t conf = 0;
		int32_t min_ = 0;
		sgt.change((-tmp_V[0].second), 1);
		for (int32_t i = 1; i < N; i++)
		{
			conf += sgt.query((-tmp_V[i].second), N);
			sgt.change((-tmp_V[i].second), 1);
		}
		return conf * 2 < (N*(N - 1) / 2);
	});

	//Yを求める！！！
	for (int32_t i = 0; i < N; i++)
	{
		zero_V_pos[i] = i;
	}
	func_ytox(-1000000000.0, zero_V);
	for (int32_t i = 0; i < N; i++)
	{
		zero_V_pos[-zero_V[i].second] = i;
	}
	double Y_RES = binary_search_D(-1000000000.0, +1000000000.0,
		[](double Y) {
		func_ytox(Y, tmp_V);
		sgt.init();
		//交差回数を求める
		int32_t conf = 0;
		int32_t min_ = 0;
		sgt.change((-tmp_V[0].second), 1);
		for (int32_t i = 1; i < N; i++)
		{
			conf += sgt.query((-tmp_V[i].second), N);
			sgt.change((-tmp_V[i].second), 1);
		}
		return conf*2 < (N*(N - 1) / 2);
	});

	out
		<< std::fixed << std::setprecision(19)
		<< X_RES << ' ' << Y_RES << endl;

	return 0;
}
#endif


Measured memory_bytes: 2688