#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <complex>
#include <random>
#include <iomanip>

using namespace std;

typedef vector<int> VI;
typedef pair<int, int> P;
typedef long long ll;

#define omajinai ios::sync_with_stdio(false);cin.tie(0)

#define ALL(a)  (a).begin(),(a).end()
#define UNIQUE(a)  (a).erase(unique(ALL(a)),(a).end())
#define MP make_pair
#define PB push_back
#define EACH(i,c) REP(i,(c).size())
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort(ALL(c))

#define FOR(i,a,b) for(ll i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)
#define RFOR(i,b,a) for(int i=(b)-1;i>=(a);--i)
#define RREP(i,n) RFOR(i,n,0)

#define CLR(a) memset((a), 0 ,sizeof(a))

#define dump(x)  cerr << "[L " << __LINE__ << "] " << #x << " = " << (x) << "\n";
#define dump2(x,y)  cerr << "[L " << __LINE__ << "] " << #x << " = " << (x) << " , " << #y << " = " << (y) << "\n";

const double EPS = 1e-11;
const int _N = 4e4;

typedef pair<double, int> DI;

int n;
int a[_N], b[_N], c[_N];
DI linexs[_N], lineys[_N];

bool secondComp(DI a, DI b){
	return a.second < b.second;
}

bool revComp(DI a, DI b){
	return a.first < b.first;
}

// 分割統治で求める
int mergeCount(vector<DI> &v, int b, int e){
	if(e-b==1)return 0;
	int m = (e+b)/2;
	int l = mergeCount(v, b, m);
	int r = mergeCount(v, m, e);

	int res = l + r;
	int last = 0;
	vector<DI> narr;
	FOR(i, b, m){
		int f = lower_bound(v.begin() + m, v.begin() + e, v[i], secondComp)
					- v.begin() - m;
		res += (f - last)*(m-i);
		narr.insert(narr.end(), v.begin() + m + last, v.begin() + m + f);
		last = f;
		narr.PB(v[i]);
	}
	narr.insert(narr.end(), v.begin() + m + last, v.begin() + e);

	FOR(i, b, e){
		v[i] = narr[i - b];
	}

	return res;
}

struct BIT{
	int data[_N+1];
	void init(int n){
		REP(i, n+1)data[i] = 0;
	}
	void add(int i, int x){
		i++;
		while(i<=n){
			data[i]+=x;
			i+=i&-i;
		}
	}
	int sum(int i){
		i++;
		int sum = 0;
		while(i>=1){
			sum+=data[i];
			i-=i&-i;
		}
		return sum;
	}
};

BIT tree;

// N log N
int countLeft(double x, bool r){
	// contain x
	vector<DI> v;
	REP(_i, n){
		int i;
		double y;
		if(!r){
			i = linexs[_i].second;
			y = (c[i] - a[i]*x)/b[i];
		}
		else{
			i = lineys[_i].second;
			y = (c[i] - b[i]*x)/a[i];
		}

		v.PB(MP(y, _i));
	}
	sort(ALL(v), revComp);


	// BITによる解法
//	tree.init(n);
//	int sum = 0;
//	REP(i, n){
//		sum += i - tree.sum(v[i].second);
//		tree.add(v[i].second, 1);
//	}
//
//	return sum;

	// 分割統治法による解法
	return mergeCount(v, 0, n);
}

// O(N log^2 N)
int main() {
	cin >> n;

	REP(i,n){
		cin>>a[i]>>b[i]>>c[i];
		// for greater sort
		// マイナスにしてある
		linexs[i] = MP((double)a[i]/b[i], i);
		lineys[i] = MP((double)b[i]/a[i], i);
	}
	sort(linexs, linexs + n);
	sort(lineys, lineys + n);

	int target = (n*(n-1)/2 + 1) / 2; // [(nC2 + 1) / 2]

	// log N
	double high,low;
	high = 1e20;low=-1e20;
	REP(i, 105){
		double mid = (high+low)/2;
		// N log N
		int x=countLeft(mid, false);
		// go x==target
		if(x < target) low = mid;
		else high = mid;
	}

	double ansx = low;
	high = 1e20;low=-1e20;
	REP(i, 105){
		double mid = (high+low)/2;
		int x=countLeft(mid, true);
		// go x==target
		if(x < target) low = mid;
		else high = mid;
	}
	double ansy = low;

	cout << fixed << setprecision(9) << ansx << " " << ansy << endl;
}


Measured memory_bytes: 4920