{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q-,R+,S+,T-,V+,X+,Y+}
{$M 65000,0,655360}

{
        Starting number: 13
        List of task:
        1
        2
}

Program Table_formatter;
uses crt;

var
   Wn : integer;
   Win,Wout : string;
   OL       : array [1..32000] of char;
   Fout     : file;
   first    : boolean;
   Poz      : array [1..10000] of word;
   iPoz     : word;

procedure Anal_param;
var
   err : integer;
begin
     Wn:=80;
     Win:=paramstr (1);
     Wout:=paramstr (2);
     if Win[1]='-' then begin
        val (copy(Win,2,length(Win)-1),Wn,err);
        if err<>0 then writeln ('Error: Bad parameter');
        Win:=paramstr (2);
        Wout:=paramstr (3);
     end;
end;

procedure Save_Line;
var
   eol : array [1..2] of char;
begin
     blockwrite (fout,OL,Wn);
     eol[1]:=#13;
     eol[2]:=#10;
     blockwrite (fout,eol,2);
end;

function GetWord (s : string; var poz : byte) : string;
var
   a  : byte;
   ss : string;
begin
     ss:='';
     a:=poz;
     repeat
           if s[a]=#8 then s[a]:=' ';
           if (ss<>'') and (ss[length(ss)]=' ') and (s[a]=' ') then
           else
               ss:=ss+s[a];
           inc (a);
     until (a>length (s)) or (s[a-1]='>') or (s[a]='<');
     GetWord:=ss;
     poz:=a;
end;

procedure Draw_line;
var
   a : integer;
begin
     for a:=2 to Wn-1 do OL[a]:='-';
     if first then begin
        OL[1]:='+';
        OL[Wn]:='+';
        first:=false;
        exit;
     end;
     if iPoz>1 then
        for a:=2 to iPoz do OL[Poz[a]-2]:='+';
     OL[1]:='|';
     OL[Wn]:='|';
end;

function Getup (s : string) : string;
var
   a : byte;
begin
     if s<>'' then for a:=1 to length(s) do s[a]:=upcase(s[a]);
     getup:=s;
end;

procedure Change (var s : string);
var
   a : byte;
   w : string;
begin
     case length(s) of
       0,1,2,3 : ;
          4 : begin
                   if s='&lt;' then s:='<';
                   if s='&LT;' then s:='<';
                   if s='&gt;' then s:='>';
                   if s='&GT;' then s:='>';
              end;
          5 : begin
                   if s='&AMP;' then s:='&';
                   if s='&amp;' then s:='&';
              end;
     else
     for a:=1 to length(s)-5 do if (s[a]='&') then begin
         if (s[a+3]=';') and (upcase(s[a+2])='T') then begin
            if upcase(s[a+1])='L' then begin
               s[a]:='<';
               delete (s,a+1,3);
            end
            else
            if upcase(s[a+1])='G' then begin
               s[a]:='>';
               delete (s,a+1,3);
            end;
         end
         else
         if s[a+4]=';' then begin
            if (upcase(s[a+1])='A') and (upcase(s[a+2])='M') and
            (upcase(s[a+3])='P') then begin
               s[a]:='&';
               delete (s,a+1,4);
            end
         end;
     end;
     end;
end;

procedure Interp (s : string);
var
   a : byte;
   w : string;
   aa,ab : integer;
   def : byte;
   noc   : word;
begin
     fillchar (OL,Wn,' ');
     a:=1;
     noc:=0;
     def:=0;
     repeat
           w:=GetWord (s,a);
           if getup(w)='<TR>' then begin
              Draw_line;
              Save_line;
              fillchar (OL,Wn,' ');
           end
           else
           if getup(w)='<TH>' then begin
              def:=1;
              inc (noc);
              OL[Poz[noc]-2]:='|';
           end
           else
           if getup(w)='<TH ALIGN=CENTER>' then begin
              def:=1;
              inc (noc);
              OL[Poz[noc]-2]:='|';
           end
           else
           if getup(w)='<TH ALIGN=LEFT>' then begin
              def:=0;
              inc (noc);
              OL[Poz[noc]-2]:='|';
           end
           else
           if getup(w)='<TH ALIGN=RIGHT>' then begin
              def:=2;
              inc (noc);
              OL[Poz[noc]-2]:='|';
           end
           else
           if getup(w)='<TD>' then begin
              def:=0;
              inc (noc);
              OL[Poz[noc]-2]:='|';
           end
           else
           if getup(w)='<TD ALIGN=LEFT>' then begin
              def:=0;
              inc (noc);
              OL[Poz[noc]-2]:='|';
           end
           else
           if getup(w)='<TD ALIGN=RIGHT>' then begin
              def:=2;
              inc (noc);
              OL[Poz[noc]-2]:='|';
           end
           else
           if getup(w)='<TD ALIGN=CENTER>' then begin
              def:=1;
              inc (noc);
              OL[Poz[noc]-2]:='|';
           end
           else begin
                Change (w);
                if def=1 then begin
                   ab:=Poz[noc+1]-Poz[noc]-3;
                   ab:=(ab-length(w)) div 2;
                   if ab<0 then ab:=0;
                   for aa:=Poz[noc]+ab to Poz[noc]+ab+length(w)-1 do
                    OL[aa]:=w[aa-Poz[noc]-ab+1];
                end
                else
                if def=2 then begin
                   ab:=Poz[noc+1]-Poz[noc]-3-length(w);
                   if ab<0 then ab:=0;
                   for aa:=Poz[noc]+ab to Poz[noc]+ab+length(w)-1 do
                    OL[aa]:=w[aa-Poz[noc]-ab+1];
                end
                else
                    for aa:=Poz[noc] to Poz[noc]+length(w)-1 do
                        OL[aa]:=w[aa-Poz[noc]+1];
           end;
     until a>length (s);
     OL[Wn]:='|';
     Save_line;
end;

procedure Make_table;
var
   f : text;
   s : string;
begin
     first:=true;
     assign (f,Win);
     reset (f);
     repeat
           readln (f,s);
           Interp (s);
     until eof (f);
     close (f);
     first:=true;
     Draw_line;
     Save_line;
end;

procedure Get_data;
var
   f : text;
   a : byte;
   l : word;
   s,w : string;
   MaxL : array [1..10000] of word;
   ileC : word;
begin
     assign (f,Win);
     reset (f);
     ileC:=0;
     fillchar (maxl,20000,0);
     repeat
           readln (f,s);
           a:=1;
           l:=0;
           repeat
                 w:=GetWord (s,a);
                 w:=getup(w);
                 if (w='<TH>') or (w='<TD>') or
                 (w='<TH ALIGN=left>') or
                 (w='<TH ALIGN=LEFT>') or
                 (w='<TH ALIGN=right>') or
                 (w='<TH ALIGN=RIGHT>') or
                 (w='<TH ALIGN=center>') or
                 (w='<TH ALIGN=CENTER>') or
                 (w='<TD ALIGN=left>') or
                 (w='<TD ALIGN=LEFT>') or
                 (w='<TD ALIGN=right>') or
                 (w='<TD ALIGN=RIGHT>') or
                 (w='<TD ALIGN=center>') or
                 (w='<TD ALIGN=CENTER>')
                 then inc (l)
                 else
                     if l<>0 then
                     if length (w)>MaxL[l] then MaxL[l]:=length (w);
           until a>length (s);
           if l>ileC then ileC:=l;
     until eof (f);
     close (f);
     Poz[1]:=3;
     if ileC>1 then
        for a:=2 to ileC do
            Poz[a]:=Poz[a-1]+MaxL[a-1]+3;
     Poz[ileC+1]:=Wn+2;
     iPoz:=ileC;

     if Poz[ileC]+MaxL[ileC]+1>Wn then begin
        writeln;
        writeln('Error: Table is too long to fit line.');
        close (fout);
        erase (fout);
        halt;
     end;
end;

BEGIN
     Anal_param;
     assign (Fout,Wout);
     rewrite (Fout,1);
     Get_data;
     Make_table;
     close (Fout);
END.