#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<long long, long long>;
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define all(x) (x).begin(),(x).end()
constexpr char ln = '\n';
constexpr long long MOD = 1000000007;
//constexpr long long MOD = 998244353;
template<class T1, class T2> inline bool chmax(T1 &a, T2 b) { if (a < b) { a = b; return true;} return false; }
template<class T1, class T2> inline bool chmin(T1 &a, T2 b) { if (a > b) { a = b; return true;} return false; }
inline int popcount(int x) {return __builtin_popcount(x);}
inline int popcount(long long x) {return __builtin_popcountll(x);}
void print() { cout << "\n"; }
template<class T, class... Args>
void print(const T &x, const Args &... args) {
    cout << x << " ";
    print(args...);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

template<typename T>
struct BinaryIndexedTree {
    int N;
    vector<T> data;

    BinaryIndexedTree(){}
    BinaryIndexedTree(int N) : N(N), data(N+1,0) {}

    // [0,k) (0-indexed) a[0] + … + a[k-1]
    T sum(int k) {
        T ret = 0;
        for(; k > 0; k -= k & -k) ret += data[k];
        return ret;
    }

    // [l,r) (0-indexed) a[l] + …　+ a[r-1]
    T sum(int l, int r) {
        if (l >= r) return 0;
        T vl = sum(l);
        T vr = sum(r);
        return vr - vl;
    }
    // (0-indexed) a[k] += x;
    void add(int k, T x) {
        for(++k; k <= N; k += k & -k) data[k] += x;
    }

    // (0-indexed)
    int lowerbound(T x) {
        int k = 1;
        int ret = 0;
        while ((k<<1) <= N) k <<= 1;
        while (k) {
            if (ret + k <= N && data[ret+k] < x) {
                x -= data[ret+k];
                ret += k;
            }
            k >>= 1;
        }
        return ret;
    }

    // (0-indexed)
    int upperbound(T x) {return lowerbound(x+1);}
};

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    auto solve=[](int N, vector<int> A, vector<int> B, vector<int> C) {
        auto calcdy=[&](int a, int b, int c) {return double(-a)/b;};
        vector<int> kari(N);
        iota(all(kari),0);
        sort(all(kari),[&](int i, int j){return calcdy(A[i],B[i],C[i]) < calcdy(A[j],B[j],C[j]);});
        auto AA = A, BB = B, CC = C;
        rep(i,N) {
            AA[i] = A[kari[i]];
            BB[i] = B[kari[i]];
            CC[i] = C[kari[i]];
        }
        swap(A,AA); swap(B,BB); swap(C,CC);

        int K = N*(N-1)/2;
        auto check=[&](double pos) {
            vector<double> Z(N);
            rep(i,N) {
                Z[i] = (-pos*A[i]+C[i])/B[i];
            }
            vector<int> idx(N);
            iota(all(idx),0);
            sort(all(idx),[&](int i, int j){return Z[i] < Z[j];});
            vector<int> SZ(N);
            rep(i,N) SZ[idx[i]] = i;
            BinaryIndexedTree<int> BIT(N);
            int tmp = 0;
            rep(i,N) {
                tmp += BIT.sum(SZ[i]);
                BIT.add(SZ[i],1);
            }

            return tmp <= (K-1)/2;
        };

        double ok = -1e9;
        double ng = 1e9;
        rep(_,100) {
            double mid = (ok+ng)/2;
            if(check(mid)) ok = mid;
            else ng = mid;
        }

        return ok;
    };

    int N; cin >> N;
    vector<int> A(N),B(N),C(N);
    rep(i,N) cin >> A[i] >> B[i] >> C[i];

    double ansx = solve(N,A,B,C);
    swap(A,B);
    double ansy = solve(N,A,B,C);



    cout << fixed << setprecision(12) << ansx << " " << ansy << ln;
}


Measured memory_bytes: 5596