{ tennis1.pas }
{ Solution for the TENNIS problem of BOI 2002 }
{ Ahto Truu }
{ Tested with FPC 1.0.4/GO32V2 }

const
   iname = 'TENNIS.IN'; { input file name }
   oname = 'TENNIS.OUT'; { output file name }
   pos = 'SOLUTION'; { "positive" answer }
   neg = 'NO SOLUTION'; { "negative" answer }
   maxn = 1000; { max allowed number of players }

type
   player = record { this is the data we keep on each player }
      num : integer; { sequence number of this player }
      gam : integer; { number of games still available }
   end;

{ exchanges two players' data }
procedure swap(var a, b : player);
var c : player;
begin
   c := a; a := b; b := c;
end;

var
{ global data }
   n : integer; { number of players }
   p : array [1..maxn] of player; { player data }
   g : array [1..maxn, 1..maxn] of boolean; { "game matrix" }
                         { g[i, j] iff players i and j play }
   ok : boolean; { do we have a solution? }
{ temporary variables }
   f : text;
   i, j, k : integer;
   s : boolean;

begin
   { load the input data }
   assign(f, iname); reset(f);
   readln(f, n);
   for i := 1 to n do
      readln(f, p[i].gam);
   close(f);

   { assign the sequence numbers to players }
   for i := 1 to n do
      p[i].num := i;

   { sort the players in descending order of number of games }
   { note that we really don't need an efficient algorithm here }
   for i := 1 to n do begin
      k := i;
      for j := i + 1 to n do
         if p[k].gam < p[j].gam then
            k := j;
      if k > i then
         swap(p[i], p[k]);
   end;

   { reset the matrix }
   for i := 1 to n do
      for j := 1 to n do
         g[i, j] := false;

   { fill the matrix in a greedy way }
   { on each step, the player with highest number of available games }
   { is set to play with the players with the second, third, etc }
   ok := true; { assume we'll find a solution }
   for k := 1 to n do begin
      { no more games to match, we're done }
      if p[k].gam = 0 then
         break;
      { not enough players to match, we have a problem }
      if k + p[k].gam > n then begin
         ok := false;
         break;
      end;
      { match the current player with the following ones }
      i := k + 1;
      while (p[k].gam > 0) and (p[i].gam > 0) do begin
         g[p[k].num][p[i].num] := true;
         g[p[i].num][p[k].num] := true;
         p[k].gam := p[k].gam - 1;
         p[i].gam := p[i].gam - 1;
         i := i + 1;
      end;
      { some games were left for current player, we have a problem }
      if p[k].gam > 0 then begin
         ok := false;
         break;
      end;
      { restore proper order of the players }
      { note that we don't need to re-sort the array }
      { we even don't need to implement a full merge }
      j := i - 1;
      while i <= n do
         if p[j].gam < p[i].gam then
            i := i + 1
         else
            break;
      i := i - 1;
      while j > k do
         if p[j].gam < p[i].gam then begin
            swap(p[i], p[j]);
            j := j - 1;
            i := i - 1;
         end else
            break;
   end;

   { output the answer }
   assign(f, oname); rewrite(f);
   if ok then begin
      writeln(f, pos);
      for i := 1 to n do begin
         s := false;
         for j := 1 to n do
            if g[i, j] then begin
               if s then
                  write(f, ' ');
               write(f, j);
               s := true;
            end;
         writeln(f);
      end;
   end else
      writeln(f, neg);
   close(f);
end.
