unittest
{
	assert( [ "4", "1 4 2", "2", "1 1 -8", "2" ].parse.expand.solve == "4 2\n1 -3" );
	assert( [ "4", "1 -1000000000 1000000000", "1 -1000000000 1000000000", "1 -1000000000 1000000000", "2" ].parse.expand.solve == "-1000000000 3000000000" );
	
	assert( [ "4", "1 -4 2", "2", "1 -1 -8", "2" ].parse.expand.solve == "-4 2\n-4 -3" );		// 追加ケース
}



import std.container;
import std.conv;
import std.format;
import std.range;
import std.stdio;
import std.typecons;

void main()
{
	stdin.byLineCopy.parse.expand.solve.writeln;
}

auto parse( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto n = input.front.to!( long );
	auto qss = new long[][ n ];
	foreach( ref qs; qss )
	{
		input.popFront;
		qs = input.front.split.to!( long[] );
	}
	return tuple( qss );
}

auto solve( long[][] qss )
{
	string[] anss;
	auto c  = 0L;
	auto x  = 0L;
	auto lt = 0L;
	auto lq = heapify( new long[ 10L ^^ 5 + 10 ], 0 );
	auto rt = 0L;
	auto rq = heapify!( ( x, y ) => y < x )( new long[ 10L ^^ 5 + 10 ], 0 );
	auto bt = 0L;
	foreach( qs; qss )
	{
		final switch( qs[ 0 ] )
		{
			case 1:
				// 左右のキューの長さが一致するようにaを追加（全体の個数が奇数の場合は左に寄せる）
				c++;
				if( qs[ 1 ] <= x )
				{
					lt += qs[ 1 ];
					lq.insert( qs[ 1 ] );
					if( lq.length != rq.length + c % 2 )
					{
						rt += lq.front;
						rq.insert( lq.front );
						lt -= lq.front;
						lq.popFront();
					}
				}
				else
				{
					rt += qs[ 1 ];
					rq.insert( qs[ 1 ] );
					if( lq.length != rq.length + c % 2 )
					{
						lt += rq.front;
						lq.insert( rq.front );
						rt -= rq.front;
						rq.popFront();
					}
				}
				
				// 中央値をxとして使う（全体の個数が奇数の場合は左に寄せる）
				x = lq.front;
				bt += qs[ 2 ];
				break;
			
			case 2:
				// 左右のキューの合計が x == 0 のときの答えなので、xに合わせてずらす
				auto ltx = ( x * ( lq.length.signed - 1 ) ) - ( lt - x );
				auto rtx = rt - ( x * rq.length.signed );
				anss ~= format( "%s %s", x, ltx + rtx + bt );
				break;
		}
	}
	return anss.join( "\n" );
}
