#include "bits/stdc++.h"

using namespace std;

using ll = long long;
using ld = long double;
using P = pair<int, int>;
constexpr ld EPS = 1e-12;
constexpr int INF = numeric_limits<int>::max() / 2;
constexpr int MOD = 1e9 + 7;

template <typename T>
void printv(const vector<T> &v)
{
    int sz = v.size();
    for (int i = 0; i < sz; i++)
    {
        cout << v[i] << " \n"[i == sz - 1];
    }
}

template <typename T>
void coordinateCompression(std::vector<T> &a)
{
    int N = a.size();
    std::vector<T> xs = a;
    sort(xs.begin(), xs.end());
    xs.erase(unique(xs.begin(), xs.end()), xs.end());
    for (int i = 0; i < N; i++)
    {
        a[i] = lower_bound(xs.begin(), xs.end(), a[i]) - xs.begin();
    }
}

class LazySegmentTree
{
    int n;
    using T1 = ll;
    using T2 = ll;
    std::vector<T1> node;
    std::vector<T2> lazy;

    // 遅延評価
    void eval(int k, int l, int r)
    {
        // 遅延配列が空なら終了
        if (lazy[k] == 0)
            return;
        // 遅延配列を適用
        node[k] = node[k] + lazy[k];
        if (r - l > 1)
        {
            lazy[2 * k + 1] = lazy[2 * k + 1] + lazy[k] / 2;
            lazy[2 * k + 2] = lazy[2 * k + 2] + lazy[k] / 2;
        }
        // 遅延配列初期化
        lazy[k] = 0;
    }

public:
    LazySegmentTree(int _n)
    {
        int sz = _n;
        n = 1;
        while (n < sz)
            n *= 2;
        // 配列初期化
        node.resize(2 * n - 1, 0);
        lazy.resize(2 * n - 1, 0);
    }
    LazySegmentTree(int _n, T1 _v)
    {
        int sz = _n;
        n = 1;
        while (n < sz)
            n *= 2;
        node.resize(2 * n - 1, 0);
        lazy.resize(2 * n - 1, 0);

        for (int i = 0; i < sz; i++)
            node[i + n - 1] = _v;
        for (int i = n - 2; i >= 0; i--)
            node[i] = node[i * 2 + 1] + node[i * 2 + 2];
    }

    // 半開区間 [a, b) に対して値 val を反映させる
    void update(int a, int b, T2 val, int l = 0, int r = -1, int k = 0)
    {
        if (r < 0)
            r = n;
        // ノード k で遅延評価
        eval(k, l, r);
        if (b <= l || r <= a)
            return;
        // 区間が被覆されている場合
        if (a <= l && r <= b)
        {
            // 遅延配列更新, 評価
            lazy[k] = lazy[k] + (r - l) * val;
            eval(k, l, r);
        }
        else
        {
            // 子ノードの値を評価し, 更新
            int mid = (l + r) / 2;
            update(a, b, val, l, mid, 2 * k + 1);
            update(a, b, val, mid, r, 2 * k + 2);
            node[k] = node[2 * k + 1] + node[2 * k + 2];
        }
    }

    // 半開区間 [a, b) に対してクエリを投げる
    T1 query(int a, int b, int l = 0, int r = -1, int k = 0)
    {
        if (r < 0)
            r = n;
        eval(k, l, r);
        // 範囲外なら単位元返す
        if (b <= l || r <= a)
            return 0;
        if (a <= l && r <= b)
            return node[k];
        int mid = (l + r) / 2;
        T1 vl = query(a, b, l, mid, 2 * k + 1);
        T1 vr = query(a, b, mid, r, 2 * k + 2);
        return vl + vr;
    }
};

template <typename T>
class FenwickTree
{
    int n;
    std::vector<T> bit;

public:
    FenwickTree(int _n) : n(_n), bit(_n, 0) {}

    void add(int pos, const T &w)
    {
        assert(0 <= pos && pos < n);
        for (int i = pos; i < n; i |= i + 1)
            bit[i] += w;
    }
    // v[0] + ... + v[pos-1]
    T sum(int pos)
    {
        assert(0 <= pos && pos <= n);
        T res = 0;
        for (int i = pos - 1; i >= 0; i = (i & (i + 1)) - 1)
        {
            res += bit[i];
        }
        return res;
    }
    T sum(int l, int r)
    {
        assert(0 <= l && l <= r && r <= n);
        return sum(r) + (-sum(l));
    }
};

LazySegmentTree lst(200010);
FenwickTree<int> ft(200010);

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    int q;
    cin >> q;
    vector<ll> type(q), a(q, 1e15), b(q);
    for (int i = 0; i < q; i++)
    {
        cin >> type[i];
        if (type[i] == 1)
        {
            cin >> a[i] >> b[i];
        }
    }
    vector<ll> v = a;
    coordinateCompression(v);
    map<ll, ll> rev; // v[i] -> x
    for (int i = 0; i < q; i++)
    {
        if (rev.find(v[i]) == rev.end())
            rev[v[i]] = a[i];
        else
            rev[v[i]] = min(rev[v[i]], a[i]);
    }
    ll bsum = 0, cnt = 0;
    for (int i = 0; i < q; i++)
    {
        if (type[i] == 2)
        {
            ll ret = bsum;
            // lb ->
            int lb = 0, ub = 200010;
            while (ub - lb > 1)
            {
                int mid = (lb + ub) / 2;
                /*
                if (ft.sum(mid, 200010) < cnt - (cnt + 1) / 2)
                    ub = mid;
                else
                    lb = mid;
                */
                if (ft.sum(0, mid) < (cnt + 1) / 2)
                    lb = mid;
                else
                    ub = mid;
            }
            ll x = rev[lb];
            ret += lst.query(lb, lb + 1);
            ret += x * (-ft.sum(lb + 1, 200010) + ft.sum(0, lb));
            cout << x << " " << ret << endl;
            continue;
        }
        cnt++;
        bsum += b[i];
        lst.update(0, v[i], a[i]);
        lst.update(v[i] + 1, 200010, -a[i]);
        ft.add(v[i], 1);
    }
}


Measured memory_bytes: 24164