#include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) begin(v),end(v)
#define fi first
#define se second
template<typename A, typename B> inline bool chmax(A &a, B b) { if (a<b) { a=b; return 1; } return 0; }
template<typename A, typename B> inline bool chmin(A &a, B b) { if (a>b) { a=b; return 1; } return 0; }
using ll = long long;
using pii = pair<int, int>;
constexpr ll INF = 1ll<<30;
constexpr ll longINF = 1ll<<60;
constexpr ll MOD = 1000000007;
constexpr bool debug = 0;
//---------------------------------//

struct LazySegTree {
	vector<ll> node, lazy;
	int n;
	
	LazySegTree(int _n) {
		n = 1;
		while (n < _n) n *= 2;
		
		node.resize(n * 2 - 1, 0);
		lazy.resize(n * 2 - 1, 0);
	}
	
	void eval(int k, int l, int r) {
		if (lazy[k] == 0) return;
		node[k] += lazy[k];
		if (r - l > 1) {
			lazy[k * 2 + 1] += lazy[k];
			lazy[k * 2 + 2] += lazy[k];
		}
		lazy[k] = 0;
	}
	
	void add(int a, int b, ll x, int k = 0, int l = 0, int r = -1) {
		if (r < 0) r = n;
		eval(k, l, r);
		
		if (a >= r || b <= l) return;
		if (a <= l && r <= b) {
			lazy[k] += x;
			eval(k, l, r);
		}
		else {
			add(a, b, x, k * 2 + 1, l, (l + r) / 2);
			add(a, b, x, k * 2 + 2, (l + r) / 2, r);
			node[k] = min(node[k * 2 + 1], node[k * 2 + 2]);
		}
	}
	
	ll query(int a, int b, int k = 0, int l = 0, int r = -1) {
		if (r < 0) r = n;
		eval(k, l, r);
		
		if (a >= r || b <= l) return 1ll<<60;
		if (a <= l && r <= b) return node[k];
		return min( query(a, b, k * 2 + 1, l, (l + r) / 2), query(a, b, k * 2 + 2, (l + r) / 2, r) );
	}
};

template<typename T>
struct SegmentTree {
	using F = std::function<T(T, T)>;
	using monoid = T;
	using size_type = std::size_t;
	
	SegmentTree(size_type n_, const F f, const monoid & id_elem) : f(f), id_elem(id_elem) {
		n = 1;
		while (n < n_) n <<= 1;
		node.resize(2 * n, id_elem);
	}
	
	size_type size() const noexcept {
		return n;
	}
	
	void set(size_type i, const monoid & x) {
		node[i += n] = x;
		while (i > 1) {
			i >>= 1;
			node[i] = f(node[i << 1], node[i << 1 | 1]);
		}
	}
	
	void add(size_type i, const monoid & x) {
		i += n;
		node[i] = f(node[i], x);
		while (i > 1) {
			i >>= 1;
			node[i] = f(node[i << 1], node[i << 1 | 1]);
		}
	}
	
	monoid fold(size_type l, size_type r) const {
		std::vector<size_type> front, back;
		for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
			if (l & 1) front.emplace_back(l++);
			if (r & 1) back.emplace_back(r - 1);
		}
		
		monoid res = id_elem;
		for (auto i : front) res = f(res, node[i]);
		for (auto it = back.rbegin(); it != back.rend(); ++it) res = f(res, node[*it]);
		return res;
	}
	
	size_type lower_bound(const monoid & x) const {
		if (node[1] < x) return n;
		size_type idx;
		monoid s = id_elem;
		for (idx = 1; idx < n;) {
			monoid nex = f(s, node[idx << 1]);
			if (nex < x) {
				idx = idx << 1 | 1;
				s = nex;
			}
			else idx = idx << 1;
		}
		return idx - n;
	}
	
	size_type upper_bound(const monoid & x) const {
		if (node[1] <= x) return n;
		size_type idx;
		monoid s = id_elem;
		for (idx = 1; idx < n;) {
			monoid nex = f(s, node[idx << 1]);
			if (nex <= x) {
				idx = idx << 1 | 1;
				s = nex;
			}
			else idx = idx << 1;
		}
		return idx - n;
	}
	
private:
	size_type n;
	F f;
	monoid id_elem;
	std::vector<monoid> node;
};

int main() {
	int Q;
	cin >> Q;
	
	using int3 = tuple<int, int, int>;
	vector<int3> query(Q);
	vector<int> cx;
	REP(i, Q) {
		int q;
		scanf("%d", &q);
		if (q == 1) {
			int a, b;
			scanf("%d %d", &a, &b);
			cx.push_back(a);
			query[i] = int3{q, a, b};
		}
		else {
			query[i] = int3{q, -1, -1};
		}
	}
	
	cx.push_back(-INF);
	cx.push_back(INF);
	
	sort(ALL(cx));
	cx.erase(unique(ALL(cx)), cx.end());
	
	int sz = cx.size();
	LazySegTree seg(cx.size());
	SegmentTree<int> seg2(cx.size(), [](int l, int r) {
		return l + r;
	}, 0);
	
	ll base = 0;
	for (auto cur : query) {
		int q, a, b;
		tie(q, a, b) = cur;
		if (q == 1) {
			int idx = lower_bound(ALL(cx), a) - cx.begin();
			seg.add(idx, sz, -a);
			seg.add(0, idx, a);
			seg2.add(idx, 1);
			base += b;
		}
		else {
			int allc = seg2.fold(0, sz);
			int ob = (allc + 1) / 2;
			int idx = seg2.lower_bound(ob);
			ll ans = seg.query(idx, idx + 1);
			
			int c = seg2.fold(0, idx + 1);
			ans += (ll)(c - (allc - c)) * cx[idx];
			ans += base;
			printf("%d %lld\n", cx[idx], ans);
		}
	}
	return 0;
}


Measured memory_bytes: 10616