// #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;

#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
typedef pair<int, int> pii;
typedef long long ll;
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

// 抽象 SegmentTree (0-indexed・一点更新・区間取得)
// static な update, combine 関数を持つクラスを別途定義して使う
template <typename MonoidType, class SegFunc>
struct SegmentTree {
    // node, identity element
    int n;
    vector<MonoidType> node;
    MonoidType E0;

    inline void build(int m, const vector<MonoidType> &v = vector<MonoidType>()) {
        if(v.size()) m = v.size();
        n = 1; while(n < m) n <<= 1;

        node = vector<MonoidType>(n << 1, E0);
        if(v.size()) {
            for(int i=0; i<m; i++) {
                node[n+i] = v[i];
            }
            for(int i=n-1; i>=1; i--) {
                node[i] = SegFunc::combine(node[i << 1], node[i << 1 | 1]);
            }
        }
    }

    // initialize
    SegmentTree() {}
    SegmentTree(int n_, MonoidType E0_,
                vector<MonoidType> v = vector<MonoidType>()) : E0(E0_) {
        build(n_, v);
    }

    // update k-th element (applied value: x)
    void update(int k, MonoidType x) {
        k += n;
        node[k] = SegFunc::update(node[k], x);
        while(k > 0) {
            k >>= 1;
            node[k] = SegFunc::combine(node[k << 1], node[k << 1 | 1]);
        }
    }

    // range query for [a, b)
    // 非再帰のアイデア: http://d.hatena.ne.jp/komiyam/20131202/1385992406
    MonoidType query(int a, int b) {
        MonoidType vl = E0, vr = E0;
        for(int l=a+n, r=b+n; l<r; l>>=1, r>>=1) {
            if(l & 1) vl = SegFunc::combine(vl, node[l++]);
            if(r & 1) vr = SegFunc::combine(node[--r], vr);
        }
        return SegFunc::combine(vl, vr);
    }
};

/*
struct SegFunc {
    using Monoid = hoge;
    
    // a に対して b を作用させる時の更新動作
    static Monoid update(Monoid a, Monoid b) {
    
    }
    // a と b をマージさせる時の動作
    static Monoid combine(Monoid a, Monoid b) {

    }
};
*/

using int64 = long long;
struct SegFunc {
    static int64 update(int64 a, int64 b) {
        return a + b;
    }
    static int64 combine(int64 a, int64 b) {
        return a + b;
    }
};

signed main() {
    int Q; cin >> Q;
    map<int, int> cmp;
    vector<int> q(Q), a(Q), b(Q), p(Q);
    for(int i=0; i<Q; i++) {
        cin >> q[i];
        if(q[i] == 1) {
            cin >> a[i] >> b[i];
            cmp[ a[i] ]++;
        }
    }

    int id = 0;
    vector<int> rev;
    for(auto &e : cmp) rev.push_back(e.first), e.second = id++;
    for(int i=0; i<Q; i++) {
        if(q[i] == 1) {
            p[i] = cmp[ a[i] ];
            // fprintf(stderr, "p = %lld\n", p[i]);
        }
    }

    vector<int> used(id);
    SegmentTree<int, SegFunc> seg1(id, 0), seg2(id, 0);
    int acc = 0, cnt = 0;
    for(int i=0; i<Q; i++) {
        if(q[i] == 1) {
            acc += b[i];
            {
                cnt++;
                seg1.update(p[i], 1   );
                seg2.update(p[i], a[i]);
                used[ p[i] ] = true;
            }
        }
        else {
            /*
            int k = 1, sum = 0;
            // fprintf(stderr, "seg1.n = %lld\n", seg1.n);
            while(k < seg1.n) {
                int target = (cnt + 1) / 2;
                //fprintf(stderr, "k = %lld, nl = %lld, nr = %lld\n",
                //        k, seg1.node[2*k], seg1.node[2*k+1]);
                if(seg1.node[2*k] + sum >= target) {
                    k = 2*k;
                }
                else {
                    k = 2*k+1;
                    sum += seg1.node[2*k];
                }
            }
            */
            int ub = id, lb = 0;
            while(ub - lb > 1) {
                int mid = (ub + lb) / 2;
                int target = (cnt + 1) / 2;
                if(seg1.query(0, mid) >= target) {
                    ub = mid;
                }
                else {
                    lb = mid;
                }
            }
            
            int idx = lb;
            // fprintf(stderr, "idx = %lld\n", idx);
            int al = rev[idx];

            int cl = seg1.query(0, idx);
            int cr = seg1.query(idx+1, id);
            int vl = seg2.query(0, idx);
            int vr = seg2.query(idx+1, id);
            
            int ar = (cl*al - vl) + (vr - cr*al) + acc;
            printf("%lld %lld\n", al, ar);
        }
    }
    return 0;
}


Measured memory_bytes: 20856