#include <bits/stdc++.h>
#define For(i, a, b) for(int (i)=(int)(a); (i)<(int)(b); ++(i))
#define rFor(i, a, b) for(int (i)=(int)(a)-1; (i)>=(int)(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<int, lint> pil;
typedef pair<lint, lint> pll;
template<class T>bool chmax(T &a, const T &b){if(a<b){a=b; return true;} return false;}
template<class T>bool chmin(T &a, const T &b){if(a>b){a=b; return true;} return false;}

constexpr lint mod = 1e9+7;
constexpr lint INF = mod*mod;
constexpr int MAX = 100010;

template<typename T> struct SegTree_dual{
    using F=function<T(T, T)>;
    int sz=1;
    T et;
    F f, g;
    vector<T> node;

    SegTree_dual(int sz_, T et_, F f_, F g_): et(et_), f(f_), g(g_){
        while(sz<sz_) sz<<=1;
        node.resize(sz<<1, et);
    }

    void update(int l, int r, T x){
        for(l+=sz, r+=sz; l<r; l>>=1, r>>=1){
            if(l&1){
                node[l]=g(node[l], x);
                l++;
            }
            if(r&1){
                --r;
                node[r]=g(node[r], x);
            }
        }
    }

    T query(int i){
        i+=sz;
        T val=node[i];
        i>>=1;
        while(i){
            val=f(val, node[i]);
            i>>=1;
        }
        return val;
    }
};

template<typename T> struct SegTree{
    using F=function<T(T, T)>;
    int sz=1;
    T et;
    F f, g;
    vector<T> node;

    SegTree(int sz_, T et_, F f_, F g_): et(et_), f(f_), g(g_){
        while(sz<sz_) sz<<=1;
        node.resize(sz<<1, et);
    }

    void update(int i, T x){
        i+=sz;
        node[i]=g(node[i], x);
        i>>=1;
        while(i){
            node[i]=f(node[i<<1], node[(i<<1)+1]);
            i>>=1;
        }
    }

    T query(int l, int r){
        T vl=et, vr=et;
        for(l+=sz, r+=sz; l<r; l>>=1, r>>=1){
            if(l&1) vl=f(vl, node[l++]);
            if(r&1) vr=f(node[--r], vr);
        }
        return f(vl, vr);
    }

    int lower_bound(T x, function<bool(T, T)> cmp){
        if(cmp(node[1], x)) return sz;
        int i=1;
        T L=et;
        while(i<sz){
            if(cmp(f(L, node[i<<1]), x)){
                L=f(L, node[i<<1]);
                i=(i<<1)+1;
            }
            else i<<=1;
        }
        return i-sz;
    }
};

int main(){
    int q;
    scanf("%d", &q);
    vector<lint> x, a(q), b(q);
    vector<int> c(q);
    rep(i, q){
        scanf("%d", &c[i]);
        if(c[i] == 1){
            scanf("%lld%lld", &a[i], &b[i]);
            x.push_back(a[i]);
        }
    }
    sort(x.begin(), x.end());
    x.erase(unique(x.begin(), x.end()), x.end());
    int n = x.size();

    SegTree_dual<int> st_slope(n, 0, plus<>(), plus<>());
    SegTree<int> st_num(n, 0, plus<>(), plus<>());
    SegTree<lint> st_sum(x.size(), 0, plus<>(), plus<>());
    lint C = 0;
    rep(i, q){
        if(c[i] == 1){
            C += b[i];
            int idx = lower_bound(x.begin(), x.end(), a[i]) - x.begin();
            st_slope.update(0, idx, -1);
            st_slope.update(idx, n, 1);
            st_num.update(idx, 1);
            st_sum.update(idx, a[i]);
        }
        else{
            int low = 0, high = n-1, k;
            if(st_slope.query(low) >= 0) k = low;
            else{
                while(high-low > 1) {
                    int mid = (high + low) / 2;
                    (st_slope.query(mid) >= 0 ? high : low) = mid;
                }
                k = high;
            }
            lint fsz = st_num.query(0, k), bsz = st_num.query(k, n);
            lint F = st_sum.query(0, k), B = st_sum.query(k, n);
            printf("%lld %lld\n", x[k], x[k]*fsz-F + B-x[k]*bsz + C);
        }
    }
}

Measured memory_bytes: 11508