program daugiakampis;
  { 29 u‘davinys }

  const MAXN = 100; { did‘iausias galimas tažk— skai‡ius }
   type taskas = record
                   x, y: integer
                 end;
        tdaugiakampis = array [0..MAXN] of taskas;

  procedure skaityti (var d: tdaugiakampis; var n: integer);
    var f: text;
        i: integer;
  begin
     assign (f, 'DAUG.DAT');
     reset (f);
     read (f, n);
     n := n - 1; { tažkai numeruojami nuo 0 iki n }
     for i := 0 to n do
        read (f, d[i].x, d[i].y);
     close (f)
  end; { skaityti }

  function ant_tieses (A, B, C: taskas): boolean;
  { ar tažkas C yra vienoje ties‚je su tažkais A ir B }
  begin
     ant_tieses := (C.y - B.y) * (B.x - A.x) =
                   (C.x - B.x) * (B.y - A.y)
  end; { ant_tieses }

  function ne_tieseje (d: tdaugiakampis; n: integer): boolean;
  { patikrina ar ne visi duoti taÕkai yra vienoje tiesÓje }
    var i: integer;
        nera: boolean;
  begin
     nera := true;
     i := 2;
     { tikrinama, ar yra bent vienas taÕkas nepriklausantis tiesei, }
     { einanÑiai per d[0] ir d[1] }
     while nera and (i <= n) do
       begin
         nera := ant_tieses (d[i], d[0], d[1]);
         i := i + 1
       end;
     ne_tieseje := not nera;
  end;  { ne_tieseje }

  function maziau (O, A, B: taskas): boolean;
  { palyginamos taÕku A ir B padÓtys taÕko O atØvilgiu: }
  { Oy yra vertikalus spindulys  virÕ— nuo taÕko O,    }
  { k(M) - kampas MOy matuojamas prieÕ laikrodØio rodyklŠ nuo Oy,}
  { ‡ia M - tažkas }
  { Taigi, P(A) < P(B), kai k(A) < k(B) arba kai }
  { k(A) = k(B) ir |OA| < |OB|  }

    function zenklas (x: integer): integer;
    begin
       if x > 0 then zenklas := 1
                else if x < 0 then zenklas := -1
                              else zenklas := 0
    end; { zenklas }

  begin
     A.x := A.x - O.x; A.y := A.y - O.y; { pereinama  kordinaÑi— sistem… }
     B.x := B.x - O.x; B.y := B.y - O.y; { su centru taÕke O              }
     case zenklas (A.x) * zenklas (B.x) of
        -1: { A ir B priežingose vertikaliosios ažies pus‚se }
             maziau := (A.x < 0);
         0: { A arba B yra ant y aÕies }
             maziau := (B.x > 0) or
                       (B.y < 0) and (A.x < 0) or
                       (B.x < 0) and (A.y < 0) or
                       (A.x = 0) and (B.x = 0) and { abu tažkai ant aži— }
                         (((A.y < B.y) or (B.y < 0)) and (A.y > 0) or
                           (A.y > B.y) and (A.y < 0));
         1: { A ir B toje paÑioje pusÓje }
             maziau := (A.y * B.x < A.x * B.y) or
                       (A.y * B.x = A.x * B.y) and (abs (A.x) < abs(B.x))
     end
  end;  { maziau }

  procedure sutvarkyti (var d: tdaugiakampis; n: integer);
  { daugiakampio tažkai surikiuojami pagal s…ryÕ MaØiau }
  { naudojant Greitojo rikiavimo metodÐ }

     procedure rusiuok (ka, de: integer);
       var i, j: integer;
           x, y: taskas;
     begin
        i := ka; j := de; x := d[(ka + de) div 2];
        repeat
          while maziau (d[0], d[i], x) do
            i := i + 1;
          while maziau (d[0], x, d[j]) do
            j := j - 1;
          if i <= j then
            begin
              y := d[i];
              d[i] := d[j];
              d[j] := y;
              i := i + 1;
              j := j - 1;
            end
        until i > j;
        if ka < j then rusiuok (ka, j);
        if i < de then rusiuok (i, de)
     end;  { rusiuok }

   begin
     rusiuok (1, n)
   end; { sutvarkyti }

  procedure rikiuoti (var d: tdaugiakampis; n: integer; { duotieji tažkai }
                      var galima: boolean { ar galima sudaryti daugiakamp });
  { jei daugiakamp sudaryti galima, tažkai surikiuojami pagal kamp… su }
  { pradiniu spinduliu }
  begin
    if not ne_tieseje (d, n) or (n <= 2) { jei visi tažkai vienoje ties‚je }
    then galima := false                 { j— per ma‘ai }
    else begin
           galima := true;
           sutvarkyti (d, n) { surikiuojami tažkai }
         end;
  end; { rikiuoti }

  function kitas (x, n: integer): integer;
  begin
     if x = n
        then kitas := 1
        else kitas := x + 1
  end; { kitas }

  function atgal (x, n: integer): integer;
  begin
     if x = 1
        then atgal := n
        else atgal := x - 1
  end; { atgal }

  function maziau_uz_180 (O, A, B: taskas): boolean;
  begin
    A.x := A.x - O.x; A.y := A.y - O.y;
    B.x := B.x - O.x; B.y := B.y - O.y;
    maziau_uz_180 := (B.y * A.x > B.x * A.y) or
                     (B.y * A.x = B.x * A.y) and (A.x * B.x > -A.y * B.y)
  end;

  procedure rasti_pradzia (d: tdaugiakampis; n: integer; var t: integer);
  { randa taÕk…, kur reikia jungti su taÕku O }
  begin
     t := 1;
     while maziau_uz_180 (d[0], d[t], d[kitas (t, n)]) and (t <= n) do
       t := t + 1;
     t := kitas (t, n)
  end;

  procedure rezultatai (d: tdaugiakampis; n: integer; galima: boolean);
  { ižveda taÕkus tokia tvarka, kad jungiant juos paeiliui b×t— }
  { gaunamas daugiakampis }
    var f: text;
    procedure rasyk_taska (i: integer);
    begin
       writeln (f, d[i].x, ' ', d[i].y)
    end;
    var pirm, pask, i, a: integer;
  begin { rezultatai }
    assign (f, 'DAUG.REZ');
    rewrite (f);
    if not galima
    then writeln (f, 'NE­MANOMA')
    else begin
           rasti_pradzia (d, n, a); { a - pirmasis pirmojo spindulio tažkas }
           { iežkosime tolimiausio paskutinio spindulio tažko }
           pask := atgal (a, n);
           { iežkosime pirmo to paties spindulio tažko }
           pirm := pask;
           while ant_tieses (d[0], d[pirm], d[pask]) do
             pirm := atgal (pirm, n);
           pirm := kitas (pirm, n);
           rasyk_taska (0);
           { tažkas O yra tarp tažk— a ir pirm }
           while a <> pirm do
             begin
               rasyk_taska (a);
               a := kitas (a, n)
             end;
           for i := pask downto pirm do
             rasyk_taska (i);
          end;
    close (f)
  end; { rezultatai }

  var n: integer;
      d: tdaugiakampis;
      galima: boolean;
begin
  skaityti (d, n);  { perskaitomi pradiniai duomenys }
  rikiuoti (d, n, galima); { tažkai surikiuojami pagal kamp… }
                                { sudarom… su pradiniu spinduliu }
  rezultatai (d, n, galima)
end.

