#include <iterator>
#include <vector>
#include <new>
#include <functional>
#include <array>
#include <limits>
#include <utility>
#include <map>
#include <chrono>
#include <cstdio>
#include <random>
template<typename T> struct ScanfSpecifier{};
#define DEF(T,V) template<> struct ScanfSpecifier<T>{static constexpr const char* value = V;};
DEF(char*,"%s")DEF(int,"%d")DEF(double,"%lf")DEF(float,"%f")DEF(char,"%c")DEF(const char*,"%s")DEF(unsigned long,"%lu")DEF(unsigned int, "%u")DEF(long double, "%Lf")
#ifdef _MSC_VER
DEF(long long int,"%I64d")
#else
DEF(long long int,"%lld")
#endif
#undef DEF
template<typename T> int RD(T& arg){return std::scanf(ScanfSpecifier<T>::value, &arg);}
template<int S> int RD(char (&arg)[S]){return std::scanf("%s", arg);}
int RD(char* arg){return std::scanf("%s", arg);}
template<> int RD<char>(char& arg){return std::scanf(" %c", &arg);}
template<typename T, typename... Args> int RD(T& arg1, Args&... args) {return RD(arg1) + RD(args...);}
template<typename T> T RD(){T ret; RD(ret); return ret;}
template<typename It> void RDV(It begin, It end) { while(begin != end) RD(*begin++); }
template<typename C> void RDV(C& c) {RDV(std::begin(c), std::end(c));}
template<typename T> void WT(T arg) {std::printf(ScanfSpecifier<T>::value, arg); }
template<typename T, typename U> void WT(std::pair<T, U> arg) {std::printf("("); WT(arg.first); std::printf(", "); WT(arg.second); std::printf(")");}
template<typename... Args> void WT(Args... args) { int alc = 0; int dummy[] = {((alc++? std::printf(" "): 0), WT(args), 0)...}; }

template<typename... Args> void WTL(Args... args) { WT(args...); std::printf("\n"); }
template<typename It> void WTV(It begin, It end) { int alc = 0; while(begin != end) (alc++? std::printf(" "): 0), WT(*begin++); }
template<typename C> void WTV(const C& c) {WTV(std::begin(c), std::end(c));}
template<typename It> void WTVL(It begin, It end) { WTV(begin, end); std::printf("\n"); }
template<typename C> void WTVL(const C& c) {WTVL(std::begin(c), std::end(c));}

#define _M_VARGS_NUM_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define _M_VARGS_NUM(...) _M_VARGS_NUM_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define _W1(_1) (#_1[0] == '"' || #_1[0] == '\''? WT("", _1, ""): WT('[', #_1, '=', _1, ']'))
#define _W2(_1, _2) (_W1(_1), _W1(_2))
#define _W3(_1, _2, _3) (_W1(_1), _W2(_2, _3))
#define _W4(_1, _2, _3, _4) (_W1(_1), _W3(_2, _3, _4))
#define _W5(_1, _2, _3, _4, _5) (_W1(_1), _W4(_2, _3, _4, _5))
#define _W6(_1, _2, _3, _4, _5, _6) (_W1(_1), _W5(_2, _3, _4, _5, _6))
#define _W7(_1, _2, _3, _4, _5, _6, _7) (_W1(_1), _W6(_2, _3, _4, _5, _6, _7))
#define _W8(_1, _2, _3, _4, _5, _6, _7, _8) (_W1(_1), _W7(_2, _3, _4, _5, _6, _7, _8))
#define _WW_IMPL2(num, ...) _W ## num(__VA_ARGS__)
#define _WW_IMPL(num, ...) _WW_IMPL2(num, __VA_ARGS__)
#define WW(...) (std::printf("(%03d) ", __LINE__), _WW_IMPL(_M_VARGS_NUM(__VA_ARGS__), __VA_ARGS__), WTL(""))


namespace XX
{
    int mmReset = 0;
    
    void resetMemory(){++mmReset;}


    template<int BLOCKSIZE, int INITBUF = 1 << 24>
    class MemoryManager
    {
        public:
            static constexpr const int INIT = INITBUF / BLOCKSIZE;

            static MemoryManager* inst()
            {
                static MemoryManager ret;
                return &ret;
            }
            
            void reset()
            {
                if(mmReset != _cnt)
                {
                    _cnt = mmReset;
                    _ptr = nullptr;
                    _size = INIT * BLOCKSIZE;
                    _pos = _idx = 0;
                }
            }
            void* alloc()
            {
                reset();


                void* ret;
                if(_ptr)
                {
                    ret = _ptr;
                    _ptr = *static_cast<void**>(_ptr);
                }
                else 
                {
                    if(_pos == _size) 
                    {
                        _pos = 0;
                        ++_idx;
                        _size <<= 1;
                        if(!_buf[_idx])
                            _buf[_idx] = new char[std::max(_size, 1)];
                    }

                    ret = _buf[_idx] + _pos;
                    _pos += BLOCKSIZE;
                }

                return ret;
            }

            void dealloc(void* p)
            {
                *static_cast<void**>(p) = _ptr;
                _ptr = p;
            }

            ~MemoryManager()
            {
//                for(int i = 1; i <= _idx; i++)
//                    delete []_buf[i];
            }

        private:

            MemoryManager() { _buf[0] = _init; }

            char _init[INIT * BLOCKSIZE];
            int _size = INIT * BLOCKSIZE;
            int _idx = 0;
            int _pos = 0;
            char* _buf[32] = {};
            void* _ptr = nullptr;
            int _cnt = 0;
    };

    template<typename T>
    struct BlockAllocater
    {
        void* operator new(std::size_t count) { return MemoryManager<sizeof(T)>::inst()->alloc(); }
        void operator delete(void* ptr) { return MemoryManager<sizeof(T)>::inst()->dealloc(ptr); }
    };
    template<typename T>
    struct NullNode
    {
        static T nullnode;
        static T* null() { return &nullnode; }
        bool isNull(){return this == null();}
    };

    template<typename T>
    T NullNode<T>::nullnode;
}





namespace XX
{
    namespace Random
    {
        using namespace std::chrono;
        unsigned x = 123456789, y = 362436069,
                z=521288629 ^ time_point_cast<nanoseconds>(high_resolution_clock::now()).time_since_epoch().count(), w=88675123;
        void setSeed(unsigned seed){z = seed;}
        unsigned xor128() 
        {
            unsigned t = x ^ (x << 11);
            x = y; y = z; z = w;
            return w = w ^ (w >> 19) ^ (t ^ (t >> 8));
        }

        unsigned long long xor128ll()
        {
            return ((long long)xor128()) << 32 | xor128();
        }

        bool randomTest(unsigned int pn, unsigned long long pd)
        {
            return (xor128() * pd >> 32) < pn;
        }
    }   
}






struct Range
{   
    struct It {   int num, step; int operator*(){return num;} void operator++(){num += step;} bool operator!=(const It& other){return num != other.num;} };
    Range(int ee):b(0),e(ee){}
    Range(int bb, int ee):b(bb), e(ee){}
    It begin(){return {b, (b < e? 1: -1)};}
    It end(){return {e, 0};}
    int b, e;
};

template<typename T> inline T& UMAX(T& x, T y){if(x < y)x = y; return x;}
template<typename T> inline T& UMIN(T& x, T y){if(y < x)x = y; return x;}
template<typename T, typename... Args> struct ArithmiticPromotion { typedef decltype(T() + typename ArithmiticPromotion<Args...>::type()) type; };
template<typename T, typename U> struct ArithmiticPromotion<T, U> { typedef decltype(T() + U()) type; };
template<typename T> struct ArithmiticPromotion<T, T> { typedef T type; };
template<typename T> struct ArithmiticPromotion<T> { typedef T type; };
template<typename T, typename U> typename ArithmiticPromotion<T, U>::type MAX(T a, U b) { return a < b? b: a; }
template<typename T, typename... Args> typename ArithmiticPromotion<T, Args...>::type MAX(T a, Args... args) { return MAX(a, MAX(args...)); }
template<typename T, typename U> typename ArithmiticPromotion<T, U>::type MIN(T a, U b) { return a < b? a: b; }
template<typename T, typename... Args> typename ArithmiticPromotion<T, Args...>::type MIN(T a, Args... args) { return MIN(a, MIN(args...)); }



namespace XX
{
    template<typename T>
    class Treap
    {
        public:
    //        template<typename U = T, void(U::*P)(T&, T&) = &U::operator()>
  //          static constexpr bool CHECK_STAT(void(T::*p)(T&, T&) = P){return true;}
//            static constexpr bool CHECK_STAT(...){return false;}
            static const constexpr bool HAS_STAT = 0;//CHECK_STAT(0);

            int size() const{ return _size;}
            Treap():_size(0){}
            template<typename... Args> void insert(Args... args) { _size++; _insert(_root, _newnode(args...)); }
            bool erase(const T& val) { bool ret = false; if(_erase(_root, val))_size--, ret = true; return ret;}
            int rank(const T& val)const { return _rank(_root, val); }
            T kth(int k)const { return _kth(_root, k);}



            T min()const
            {
                Node* node = _root;
                while(!node->child[0]->isNull())
                    node = node->child[0];
                return node->data;
            }
            T max()const
            {
                Node* node = _root;
                while(!node->child[1]->isNull())
                    node = node->child[1];
                return node->data;
            }
            


            template<typename F>
            void statistic(T key, F f)
            {
                statistic(_root, key, f);
            }


            struct Node: public BlockAllocater<Node>, NullNode<Node>
            {
                int pr = -1;
                T data;
                Node* child[2] = {Node::null(), Node::null()};
                int sum;

                Node(){}
                template<typename... Args> Node(int p, Args... args) :pr(p), data(args...) {}
            };

            Node* find(const T& data)
            {
                return _find(_root, data);
            }

            template<typename F>
            void travel(Node* node, F f)
            {
                if(node->isNull())return;
                
                travel(node->child[0], f);
                f(node);
                travel(node->child[1], f);
            }
            template<typename F>
            void travel(int num, Node* node, F f)
            {
                if(node->isNull())return;
                travel(num, node->child[0], f);
                if(node->child[0]->sum < num)
                {
                    f(node);
                    if(node->child[0]->sum + 1 < num)
                        travel(num - node->child[0]->sum - 1, node->child[1], f);
                }
            }
            template<typename F>
            void travel(F f)
            {
                travel(_root, f);
            }
            template<typename F>
            void travel(int num, F f)
            {
                travel(num, _root, f);
            }

            template<typename F>
            void statistic(Node* node, T key, F f)
            {
                if(node->isNull())return;
                if(node->data < key)
                {
                    f(node->data);
                    statistic(node->child[1], key, f);
                }
                else
                {
                    statistic(node->child[0], key, f);
                }
            }

            void clear()
            {
                _dealloc(_root); _root = Node::null(); _size = 0;
            }
            Node* _root = Node::null();
            int _size;
        private:


            void _dealloc(Node* node)
            {
                if(!node->isNull())
                {
                    _dealloc(node->child[0]);
                    _dealloc(node->child[1]);
                    delete node;
                }
            }

            T _kth(Node* now, int k)const
            {
                while(true)
                {
                    int ls = now->child[0]->sum;
                    if(ls > k)
                        now = now->child[0];
                    else if(ls == k)
                        break;
                    else
                        k -= ls + 1, now = now->child[1];
                }
                return now->data;
            }

            void _rotate(Node*& node, int idx)
            {
                Node* child = node->child[idx];
                node->child[idx] = child->child[idx ^ 1];
                child->child[idx ^ 1] = node;
                node = child;
            }

            bool _erase(Node*& now, const T& data)
            {
                if(now->isNull())
                    return false;

                bool ret = false;

                if(data < now->data)
                    ret = _erase(now->child[0], data);
                else if(now->data < data)
                    ret = _erase(now->child[1], data);
                else if(now->child[0]->isNull() && now->child[1]->isNull())
                {
                    delete now;
                    now = Node::null();
                    return true;
                }
                else 
                {
                    int idx = now->child[0]->pr < now->child[1]->pr;
                    _rotate(now, idx);
                    _erase(now->child[idx ^ 1], data);
                    ret = true;
                }
                _resum(now);
                return ret;
            }
            int _rank(Node* now, const T& data)const
            {
                if(now->isNull())
                    return 0;
                if(now->data < data)
                    return now->sum + _rank(now->child[1],data) - now->child[1]->sum;
                else 
                    return _rank(now->child[0], data);
            }

            template<bool S = HAS_STAT>
            typename std::enable_if<S, void>::type _resum(Node* node)
            {
                node->sum = 1 + node->child[0]->sum + node->child[1]->sum;
                node->data(node->child[0]->data, node->child[1]->data);
            }
            template<bool S = HAS_STAT>
            typename std::enable_if<!S, void>::type _resum(Node* node, ...)
            {
                node->sum = 1 + node->child[0]->sum + node->child[1]->sum;
            }

            Node* _find(Node* now, const T& data)
            {
                /*
                if(now->isNull())
                    return now;
                else if(data < now->data)
                    return _find(now->child[0], data);
                else if(now->data < data)
                    return _find(now->child[1], data);
                else
                    return now;*/
                while(!now->isNull())
                    if(data < now->data)
                        now = now->child[0];
                    else if(now->data < data)
                        now = now->child[1];
                    else
                        break;
                return now;
            }
            void _insert(Node*& now, Node* node) 
            {
                if(now->isNull())
                    now = node;
                else                
                {
                    int idx = now->data < node->data;
                    _insert(now->child[idx], node);
                    if(now->pr < node->pr)
                    {
                        _rotate(now, idx);
                        _resum(now->child[idx ^ 1]);
                    }
                }
                _resum(now);
            }

            template<typename... Args>
            Node* _newnode(Args... args)
            {
                return new Node(Random::xor128() & std::numeric_limits<int>::max(), args...);
            }

    };
}






//alias
using RG = Range;
//RD[L],RDV[L],WT[L],WTV[L] for i/o
//template
#include <vector>
#include <string>
#include <cstring>
#include <queue>
#include <set>
#include <map>
#include <cstdlib>
#include <algorithm>
#include <functional>
using namespace std;

//alias
using XX::Random::xor128;
using XX::Random::randomTest;
//Treap
using XX::Treap;  //insert(value)  erase(value)   rank(value)
typedef long long int ll;

const int SIZE = 50009;
long double A[SIZE], B[SIZE],C[SIZE];
int N;
int main()
{
    RD(N);
    for(int i: RG(N))
        RD(A[i], B[i], C[i]);

    long double ans[2];

    for(int z: RG(2))
    {
        long double l = -1e9, r = 1e9;

        for(int k: RG(100))
        {
            XX::resetMemory();
            auto m = (l + r) / 2;

            vector<pair<long double, int>> q;
            for(int i: RG(N))
                q.push_back({(C[i] - m * B[i]) / A[i], i});
            sort(q.begin(), q.end());
            Treap<long double> p;
            ll alc = 0;
            for(int i: RG(N))
            {
                auto s = B[q[i].second] / A[q[i].second];
                alc += p.size() - p.rank(s);
                p.insert(s);
            }

            


            if(alc > (N * (N - 1ll) / 2 + 1) / 2 - 1)
                r = m;
            else
                l = m;
        }

        ans[z] = (l + r) / 2;

        for(int i: RG(N))
            swap(A[i], B[i]);
    }

    for(int i: RG(1, -1))
        printf("%.12Lf ", ans[i]);
    WTL();


}






Measured memory_bytes: 9524