program i172mo;

{ A KoMaL i.172. feladatanak megoldasa }
{ Programozasi kornyezet: Borland Pascal 7.0 }
{ Hasznalat: i172mo bemenetifajlneve kimenetifajlneve }

var
  tdb : Integer; { a termekek darabszama }
  ter : array [1..100] of Integer; { a termekek ara }
  ki : Text; { a kimeneti allomany }

procedure Beolvas;
var be : Text;
    kod : LongInt;
begin
  tdb := 0;
  Assign( be, ParamStr(1) );
  ReSet( be );
  while not eof(be) do
  begin
    Inc(tdb);
    ReadLn( be, kod, ter[tdb] );
  end;
  Close( be );
end;

var
  kidb : Integer; { hanyadik vasarlast irjuk a kimeneti fajlba }
  ossz : LongInt; { mennyibe kerult eddig a dolog }

procedure Kimenet( ar : Integer );
begin
  if kidb>0 then Dec( ar,100 );
  Inc( kidb );
  Inc( ossz, ar );
  WriteLn( ki, ar );
end;

type
  Valasztas = array [1..100] of Boolean; { a valasztasra jelolt aruk }
var
  val : Valasztas; { a kovetkezo eljaras altal kijelolt aruk }
  ert : LongInt; { a kijelolt aruk osszerteke }

procedure Kivesz; { a tablazatbol kivesszuk a val[]-ban jelolteket }
var i,j : Integer;
begin
  j := tdb;
  for i := 1 to tdb do if val[i] then Dec(tdb); { csokkentjuk a darab mutatot }
  i := 1;
  while i<j do
  begin
    while (i<j) and val[j] do Dec(j); { keresunk egy nem kijeloltet a vegerol }
    while (i<j) and not val[i] do Inc(i); { keresunk egy kijeloltet elolrol }
    if i<j then { ha talaltunk, akkor atvisszuk elore }
    begin
      ter[i] := ter[j];
      Inc(i);
      Dec(j);
    end;
  end;
end;

procedure Haromezresek; { a haromezer folottieket kiirjuk a kimenetre }
var i,j : Integer; { segedvaltozok }
begin
  for i := 1 to tdb do val[i] := False;
  for i := 1 to tdb do
    if ter[i]>=3000 then
    begin
      Kimenet( ter[i] );
      val[i] := True;
    end;
  Kivesz; { kivesszuk oket a ter[] tablazatbol }
end;

function Valogat( db : Integer ) : Boolean;
{ Az eljaras a ter[] arukbol a legkisebb 3000 Ft-ot meghalado
  db szamu termeket kivalasztja es megjeloli val[]-ban }
var
  leg : Valasztas; { az eddigi legkisebb 3000 folott valasztas }
  lar : LongInt ; { az eddigi legkisebb valasztasnal fizetendo osszeg }
  i,j,k : Integer; { segedvaltozok }
  ar : Integer;
begin
  { Visszalepeses keresessel megvizsgaljuk az osszes db elemu reszhalmazt }

  for i := 1 to tdb do val[i] := False; { meg egyiket sem valasztottuk }
  for i := 1 to db do val[i] := True; { az elso kdb-t valasztjuk }
  lar := 50001; { meg nem sikerult valasztani - ez a MAX ar egy termekre }

  repeat
    { megszamoljuk, hogy ez a valasztas mennyibe kerul }
    ar := 0;
    for k := 1 to tdb do if val[k] then Inc( ar,ter[k] );
    if (ar>=3000) and (ar<lar) then { ha jobb, mint az eddigi }
    begin { mostantol ez a legjobb valasztas }
      lar := ar;
      leg := val;
    end;

    { vesszuk a kovetkezo reszhalmazt a val[] tombben valo "lepegetessel" }

    j := 1; { az elejerol indulunk }
    k := 0; { meg nem sikerult talalni megfelelo lepest }
    while j<tdb do { megkeressuk az utolso jelolot, amely tovabb tud lepni }
    begin
      if val[j] and not val[j+1] then k := j; { k-adikkal lephetunk }
      Inc(j);
    end;

    if k>0 then { sikerul lepni }
    begin
      val[k] := False;  Inc(k);
      val[k] := True; Inc(k);
      i := k;
      while i<=tdb do { minden kesobbi valasztast utana sorolunk be }
      begin
        if val[i] then
        begin
          val[k] := True;
          val[i] := False;
        end;
        Inc(i);
      end;
    end;
  until k=0; { ha nem sikerult lepni, akkor vege }

  if lar=50001 then Valogat := False
  else
  begin
    ert := lar;
    val := leg;
    Valogat := True;
  end;
end;

var
  db : Integer; { a valasztando elemek jelenlegi szama }
  i  : Integer;
begin
  Beolvas;
  kidb := 0; { meg semmi nem ment a kimenetre }
  Assign( ki,ParamStr(2) );
  ReWrite( ki );

  Haromezresek;
  repeat
    db := 1; { az egy elembol allokkal kesz vagyunk }
    repeat
      Inc(db); { a ketelemuek a legkisebbek, amiket megnezunk }
    until (db>tdb) or Valogat(db); { vagy nincs, vagy sikerult valasztani }
    if db<=tdb then
    begin
      Kimenet( ert );
      Kivesz;
    end;
  until db>tdb; { mar nem sikerult 3000 Ft folotti reszhalmazt megadni }

  ert := 0; { a maradekot megvasaroljuk }
  for i := 1 to tdb do Inc(ert,ter[i]);
  if( ert>0) then Kimenet( ert ); { ha valoban maradt valami }

  WriteLn( ki, ossz );

  Close( ki );
end.

