program tab;
{$A+,B-,D+,E+,F-,G-,I-,L+,N-,O-,P-,Q-,R-,S-,T-,V+,X+,Y+}
{$M 16384,0,655360}
type tbunka=^_bunka;
     _bunka=record
            poz_x,poz_y,del_x,del_y:word;
            rx,ry:word;
            cen1,cen2:byte;
            obsah:string;
            dalsi:tbunka;
           end;
const prazd:set of char=[#0..#31,' '];
var vstup:string;
    vystup:string;
    delka_r:byte;
    param:string;
    f1,f2:text;
    i,j,k,l,m,n:integer;
    vst:string;
    pole,posl,pp:tbunka;
    mapa:array[1..100,1..100] of byte;
    maxlen0:array[1..100] of word;
    maxlen:array[1..100] of word;
    delka:array[1..100] of byte;
    sloupcu,sloupcu_:byte;
    radku:byte;
    ss:string;
    form1,form2,_f1,_f2:byte;
    del1,del2:byte;
function mindel(s:string):byte;
var cy1,cy2,w:byte;
begin
 cy2:=0; w:=0;
 for cy1:=1 to length(s) do
  if (s[cy1]=' ') or (s[cy1]='-') then
   cy2:=0
  else
   begin
    inc(cy2);
    if w<cy2 then w:=cy2
   end;
 mindel:=w;
end;
function lame(s:string; w:word):word; { minimalni pocet radku pro bunku }
begin
 lame:=1
end;
procedure chalt; { chybove ukonceni }
begin
 close(f1); close(f2); if ioresult<>0 then; halt
end;
function radek:string; { nacteni radku ze vstupniho souboru }
var s:string;
    res:integer;
begin
 repeat
  readln(f1,s);
  res:=ioresult;
 until (s<>'') or (res<>0);
 if (res<>0) then begin writeln('Error while reading file.'); chalt end;
 radek:=s
end;
procedure akt(var sp:string); { aktualizace promenne vst }
var cykl:word;
    vysl:boolean;
begin
 vysl:=false; for cykl:=1 to length(sp) do if sp[cykl]='>' then vysl:=true;
 if not(seekeof(f1)) and not(vysl) then begin sp:=sp+radek; akt(sp) end;
end;
procedure zn(var sp:string); { odtraneni prvniho ynaku retezce }
begin
 akt(sp);
 sp:=copy(sp,2,length(sp)-1);
end;
procedure odmez(var s:string); { odstraneni mezer }
begin
 akt(s); while (s[1]=' ') and (s[0]<>#0) do s:=copy(s,2,length(s)-1);
end;
procedure spc_odmez(var s:string); { pouzito v procedure RETEZ }
begin
 while (s[1]=' ') and (s[0]<>#0) do s:=copy(s,2,length(s)-1);
end;
procedure _o(var s:string); { zvetseni prvniho pismene }
begin
 akt(s); s[1]:=upcase(s[1]);
end;
procedure _odmez(var s:string); { _o + odmez }
begin
 akt(s);
 while (s[1]=' ') and (s[0]<>#0) do s:=copy(s,2,length(s)-1);
 _o(s);
end;
procedure bs; { chyba v strukture }
begin
 writeln('Bad structure of table');
 chalt;
end;
function konec_r(var s:string):boolean; { kontrola konce radky }
var pomocna:string;
 function prvni:char;
 begin
  while (pomocna<>'') and (pomocna[1]=' ') do pomocna:=copy(pomocna,2,length(pomocna)-1);
  if pomocna='' then
   prvni:=' '
  else
   begin
    prvni:=upcase(pomocna[1]);
    pomocna:=copy(pomocna,2,length(pomocna)-1);
   end;
 end;
begin
 _odmez(s);
 if (s=' ') or (s='') then
  konec_r:=true
 else
  begin
   pomocna:=s;
   if (prvni='<') and (prvni='T') and (prvni='R') then konec_r:=true else konec_r:=false;
  end;
end;
function _cislo(var s:string):word; { nacteni cisla z retezce }
var vysl:word;
begin
 vysl:=0;
 _odmez(s);
 while s[1] in ['0'..'9'] do
  begin
   vysl:=vysl*10+ord(s[1])-48;
   zn(s);
  end;
 _cislo:=vysl;
end;
function bunka(xx,yy:word):tbunka; { vyhledani urcite bunky }
begin
 while mapa[xx,yy]=2 do dec(yy);
 while mapa[xx,yy]=6 do dec(yy);
 while mapa[xx,yy]=3 do dec(xx);
 if mapa[xx,yy]=0 then
  bunka:=nil
 else
  begin
   if posl=nil then posl:=pole;
   if (posl^.poz_x>xx) then posl:=pole;
   if (posl^.poz_x=xx) and (posl^.poz_y>yy) then posl:=pole;
   while (posl<>nil) and ((posl^.poz_x<>xx) or (posl^.poz_y<>yy)) do posl:=posl^.dalsi;
   bunka:=posl
  end;
end;
function minus(p:word):string; { p minusek }
var s:string;
begin
 s:='';
 while p>0 do begin dec(p); s:=s+'-' end;
 minus:=s;
end;
function mez(p:word):string; { p mezer }
var s:string;
begin
 s:='';
 while p>0 do begin dec(p); s:=s+' ' end;
 mez:=s;
end;
function retez(var s:string):string; { vyjmuti textoveho retezce ze zacatku retezce }
var t:string;
    u:byte;
 function tag:string;
 var sss:string;
 begin
  sss:='';
  if u+1<=length(t) then sss:=sss+upcase(t[u+1]);
  if u+2<=length(t) then sss:=sss+upcase(t[u+2]);
  if u+3<=length(t) then sss:=sss+upcase(t[u+3]);
  if (u+4<=length(t)) and (sss='AMP') then sss:=sss+upcase(t[u+4]);
  tag:=sss;
 end;
begin
 akt(s);
 t:='';
 while (s<>'') and (s[1]<>'<') do begin t:=t+s[1]; s:=copy(s,2,length(s)-1); end;
 spc_odmez(t);
 u:=1;
 while u<=length(t) do
  begin
   if t[u] in prazd then t[u]:=' ';
   if (t[u]=' ') and (u>1) and (t[u-1]=' ') then
    t:=copy(t,1,u-1)+copy(t,u+1,length(t)-u)
   else
    if t[u]='&' then
     begin
      if tag='LT;' then
       t:=copy(t,1,u-1)+'<'+copy(t,u+4,length(t)-u-3)
      else
       if tag='GT;' then
        t:=copy(t,1,u-1)+'>'+copy(t,u+4,length(t)-u-3)
       else
        if tag='AMP;' then
         t:=copy(t,1,u-1)+'&'+copy(t,u+5,length(t)-u-4);
     end;
   inc(u);
  end;
 if t[length(t)]=' ' then dec(byte(t[0]));
 retez:=t;
end;
function vytisk(r:word;b:boolean):boolean; { centrovani svisle }
                      {  byte - viceradkove radky }
var q:word;
begin
 r:=2*r; if b then dec(r);
 case pp^.cen2 of
  0: q:=1;
  1: q:=pp^.del_x;
  2: q:=2*pp^.del_x-1;
 end;
 r:=r+2-2*pp^.poz_x;
 vytisk:=(r=q);
end;
begin
 { nacteni parametru }
 if paramcount<2 then
  begin
   writeln('Syntax: 08TAB [-n] table_description formatted_table'); chalt;
  end;
 i:=1; param:=paramstr(1);
 delka_r:=80;
 if param[1]='-' then
  begin
   val(copy(param,2,length(param)-1),delka_r,j);
   if (j<>0) then begin writeln('First parametr behind "-" must  be a number.'); chalt end;
   inc(i);
  end;
 if paramcount<1+i then
  begin
   writeln('Syntax: 08TAB [-n] table_description formatted_table'); chalt;
  end;
 { otevreni souboru a incializace promennych }
 vstup:=paramstr(i);
 vystup:=paramstr(i+1);
 assign(f1,vstup); assign(f2,vystup);
 reset(f1); rewrite(f2);
 if (ioresult<>0) then begin writeln('Error while working with files.'); chalt end;
 pole:=nil; posl:=nil;
 sloupcu:=0;
 fillchar(mapa,sizeof(mapa),0);
 fillchar(maxlen,sizeof(maxlen),0);
 fillchar(delka,sizeof(delka),1);
 radku:=0;
 { cyklus pro zpracovani radky }
 while (not(seekeof(f1))) or (vst<>'') do
  begin
   akt(vst);
   sloupcu_:=0;
   { klicova slova - chybi pro svisle centrovani }
   odmez(vst); if vst[1]<>'<' then bs; zn(vst);
   _odmez(vst); if vst[1]<>'T' then bs; zn(vst);
   _o(vst); if vst[1]<>'R' then bs; zn(vst);
   _f1:=0; _f2:=0; _odmez(vst);
     while (vst[1]='A') do
      begin
      if vst[1]='A' then
       begin
        zn(vst);
        _o(vst); if vst[1]<>'L' then bs; zn(vst);
        _o(vst); if vst[1]<>'I' then bs; zn(vst);
        _o(vst); if vst[1]<>'G' then bs; zn(vst);
        _o(vst); if vst[1]<>'N' then bs; zn(vst);
        _odmez(vst); if vst[1]<>'=' then bs; zn(vst);
        _odmez(vst);
        case vst[1] of
        'R':begin
             zn(vst);
             _o(vst); if vst[1]<>'I' then bs; zn(vst);
             _o(vst); if vst[1]<>'G' then bs; zn(vst);
             _o(vst); if vst[1]<>'H' then bs; zn(vst);
             _o(vst); if vst[1]<>'T' then bs; zn(vst);
             _f1:=2;
             _odmez(vst);
            end;
        'L':begin
             zn(vst);
             _o(vst); if vst[1]<>'E' then bs; zn(vst);
             _o(vst); if vst[1]<>'F' then bs; zn(vst);
             _o(vst); if vst[1]<>'T' then bs; zn(vst);
             _f1:=0;
             _odmez(vst);
            end;
        'C':begin
             zn(vst);
             _o(vst); if vst[1]<>'E' then bs; zn(vst);
             _o(vst); if vst[1]<>'N' then bs; zn(vst);
             _o(vst); if vst[1]<>'T' then bs; zn(vst);
             _o(vst); if vst[1]<>'E' then bs; zn(vst);
             _o(vst); if vst[1]<>'R' then bs; zn(vst);
             _f1:=1;
             _odmez(vst);
            end;
        end;
       end;
      end;
   odmez(vst); if vst[1]<>'>' then bs; zn(vst);
   inc(radku);
   odmez(vst);
   { cyklus pro zpracovani sloupcu radky }
   while not(konec_r(vst)) do
    begin
     form1:=_f1; form2:=_f2; del1:=1; del2:=1;
     odmez(vst); if vst[1]<>'<' then bs; zn(vst);
     _odmez(vst); if vst[1]<>'T' then bs; zn(vst);
     _o(vst); if (vst[1]<>'H') and (vst[1]<>'D') then bs;
     if (vst[1]='H') then form1:=1; if (vst[1]='H') then form2:=1; zn(vst);
     _odmez(vst);
     { klicova slova - chybi pro svisle centrovani }
     while (vst[1]='A') or (vst[1]='R') or (vst[1]='C') do
      begin
      if vst[1]='C' then
       begin
        zn(vst);
        _o(vst); if vst[1]<>'O' then bs; zn(vst);
        _o(vst); if vst[1]<>'L' then bs; zn(vst);
        _o(vst); if vst[1]<>'S' then bs; zn(vst);
        _o(vst); if vst[1]<>'P' then bs; zn(vst);
        _o(vst); if vst[1]<>'A' then bs; zn(vst);
        _o(vst); if vst[1]<>'N' then bs; zn(vst);
        _odmez(vst); if vst[1]<>'=' then bs; zn(vst);
        _odmez(vst); del2:=_cislo(vst); _odmez(vst);
        if del1=0 then bs;
       end;
      if vst[1]='R' then
       begin
        zn(vst);
        _o(vst); if vst[1]<>'O' then bs; zn(vst);
        _o(vst); if vst[1]<>'W' then bs; zn(vst);
        _o(vst); if vst[1]<>'S' then bs; zn(vst);
        _o(vst); if vst[1]<>'P' then bs; zn(vst);
        _o(vst); if vst[1]<>'A' then bs; zn(vst);
        _o(vst); if vst[1]<>'N' then bs; zn(vst);
        _odmez(vst); if vst[1]<>'=' then bs; zn(vst);
        _odmez(vst); del1:=_cislo(vst); _odmez(vst);
        if del1=0 then bs;
       end;
      if vst[1]='A' then
       begin
        zn(vst);
        _o(vst); if vst[1]<>'L' then bs; zn(vst);
        _o(vst); if vst[1]<>'I' then bs; zn(vst);
        _o(vst); if vst[1]<>'G' then bs; zn(vst);
        _o(vst); if vst[1]<>'N' then bs; zn(vst);
        _odmez(vst); if vst[1]<>'=' then bs; zn(vst);
        _odmez(vst);
        case vst[1] of
        'R':begin
             zn(vst);
             _o(vst); if vst[1]<>'I' then bs; zn(vst);
             _o(vst); if vst[1]<>'G' then bs; zn(vst);
             _o(vst); if vst[1]<>'H' then bs; zn(vst);
             _o(vst); if vst[1]<>'T' then bs; zn(vst);
             form1:=2;
             _odmez(vst);
            end;
        'L':begin
             zn(vst);
             _o(vst); if vst[1]<>'E' then bs; zn(vst);
             _o(vst); if vst[1]<>'F' then bs; zn(vst);
             _o(vst); if vst[1]<>'T' then bs; zn(vst);
             form1:=0;
             _odmez(vst);
            end;
        'C':begin
             zn(vst);
             _o(vst); if vst[1]<>'E' then bs; zn(vst);
             _o(vst); if vst[1]<>'N' then bs; zn(vst);
             _o(vst); if vst[1]<>'T' then bs; zn(vst);
             _o(vst); if vst[1]<>'E' then bs; zn(vst);
             _o(vst); if vst[1]<>'R' then bs; zn(vst);
             form1:=1;
             _odmez(vst);
            end;
        end;
       end;
      end;
     if vst[1]<>'>' then bs; zn(vst);
     { text bunky }
     repeat
      inc(sloupcu_);
     until mapa[radku,sloupcu_]=0;
     mapa[radku,sloupcu_]:=1;
     if del2>1 then mapa[radku,sloupcu_]:=4;
     if del1>1 then mapa[radku,sloupcu_]:=5;
     for k:=2 to del2 do mapa[radku,sloupcu_+k-1]:=2;
     for l:=2 to del1 do for k:=1 to del2 do
      if k=1 then mapa[radku+l-1,sloupcu_+k-1]:=3 else mapa[radku+l-1,sloupcu_+k-1]:=6;
     ss:=retez(vst);
     { vlozeni do datove struktury }
     new(pp);
     pp^.poz_x:=radku;
     pp^.poz_y:=sloupcu_;
     pp^.del_x:=del1;
     pp^.del_y:=del2;
     pp^.obsah:=ss;
     pp^.cen1:=form1;
     pp^.cen2:=form2;
     pp^.dalsi:=nil;
     if pole=nil then
      begin
       pole:=pp; posl:=pp
      end
     else
      begin
       posl^.dalsi:=pp; posl:=pp
      end;
     if del2=1 then
      begin if length(ss)>maxlen[sloupcu_] then maxlen[sloupcu_]:=length(ss) end
     else
      sloupcu_:=sloupcu_+del2-1;
    end;
   if sloupcu_>sloupcu then sloupcu:=sloupcu_;
  end;
 close(f1);
 { konec vstupni casti programu }
 if (ioresult<>0) then begin writeln('Error while working with files.'); chalt end;
 { kontrola delky sloupcu }
 posl:=pole;
 while posl<>nil do
  begin
   if posl^.del_y>1 then
    begin
     j:=-3;
     for i:=posl^.poz_y to posl^.poz_y+posl^.del_y-1 do j:=j+3+maxlen[i];
     j:=length(posl^.obsah)-j;
     if j>0 then
      for i:=posl^.poz_y to posl^.poz_y+posl^.del_y-1 do
       maxlen[i]:=maxlen[i]+((j+i-posl^.poz_y) div posl^.del_y);
    end;
   if posl^.poz_x+posl^.del_x-1>radku then radku:=posl^.poz_x+posl^.del_x-1;
   posl:=posl^.dalsi;
  end;
 { vypis tabulky }
 j:=1;
 for i:=1 to sloupcu do j:=j+3+maxlen[i];
 if j>delka_r then
  begin
   writeln('Error: table is too long to fit line.');
   writeln('Trying to make table shorter'); { pokus o upravu formatu }
   move(maxlen,maxlen0,sizeof(maxlen));
   fillchar(maxlen,sizeof(maxlen),0);
   posl:=pole; {jednosloupcove bunky}
   while posl<>nil do
    begin
     if posl^.del_y=1 then
      begin
       k:=mindel(posl^.obsah);
       if maxlen[posl^.poz_y]<k then maxlen[posl^.poz_y]:=k;
      end;
     posl:=posl^.dalsi;
    end;
   posl:=pole; {vicesloupcove bunky }
   while posl<>nil do
    begin
     if posl^.del_y>1 then
      begin
       j:=-3;
       for i:=posl^.poz_y to posl^.poz_y+posl^.del_y-1 do j:=j+3+maxlen[i];
       j:=mindel(posl^.obsah)-j;
       if j>0 then
        for i:=posl^.poz_y to posl^.poz_y+posl^.del_y-1 do
         maxlen[i]:=maxlen[i]+((j+i-posl^.poz_y) div posl^.del_y);
      end;
     posl:=posl^.dalsi;
    end;
   j:=1;
   for i:=1 to sloupcu do j:=j+3+maxlen[i];
   if j>delka_r then
    begin
     writeln('Unable to change widths of columns'); chalt
    end;
   while j<delka_r do { natazeni na maximalni sirku }
    for i:=1 to sloupcu do
     if (j<delka_r) and (maxlen[i]<maxlen0[i]) then
      begin
       inc(j); inc(maxlen[i])
      end;
  end;
 { vypocet sirky bunky }
 posl:=pole;
 while posl<>nil do
  begin
   j:=-3;
   for i:=posl^.poz_y to posl^.poz_y+posl^.del_y-1 do j:=j+maxlen[i]+3;
   posl^.ry:=j;
   posl:=posl^.dalsi;
  end;
 { vypocet vysek radku }
 posl:=pole;
 while posl<>nil do
  if posl^.del_x=1 then
   begin
    i:=lame(posl^.obsah,posl^.ry);
    if i>delka[posl^.poz_x] then delka[posl^.poz_x]:=i;
    posl:=posl^.dalsi;
   end
  else
   posl:=posl^.dalsi;
 posl:=pole;
 while posl<>nil do
  if posl^.del_x>1 then
   begin
    m:=lame(posl^.obsah,posl^.ry);
    j:=-1;
    for i:=posl^.poz_x to posl^.poz_x+posl^.del_x-1 do j:=j+delka[i]+1;
    if m>j then
     for i:=1 to posl^.del_x do
      delka[posl^.poz_x+i-1]:=delka[posl^.poz_x+i-1]+((m-j+i-1) div posl^.del_x);
    posl:=posl^.dalsi;
   end
  else
   posl:=posl^.dalsi;
 posl:=pole;
 while posl<>nil do
  begin
   j:=-1;
   for i:=posl^.poz_x to posl^.poz_x+posl^.del_x-1 do j:=j+delka[i]+1;
   posl^.rx:=j;
   posl:=posl^.dalsi;
  end;
 { VYTISK }
 j:=1;
 for i:=1 to sloupcu do j:=j+3+maxlen[i];
 writeln(f2,'+'+minus(j-2)+'+');
 { cyklus pro radky }
 for i:=1 to radku do
  begin
   write(f2,'|');
   for j:=1 to sloupcu do
    { tady bude cyklus pro viceradkove radky }
    begin
     { jednoradkove bunky }
     if (mapa[i,j]=1) or (mapa[i,j]=4) or (mapa[i,j]=0) then
     begin
      pp:=bunka(i,j);
      m:=-3;
      if pp<>nil then for k:=1 to pp^.del_y do m:=m+3+maxlen[pp^.poz_y+k-1];
      if pp=nil then
       write(f2,mez(maxlen[j]+2)+'|')
      else
       case pp^.cen1 of
       0: write(f2,' '+pp^.obsah+mez(m-length(pp^.obsah))+' |');
       1: write(f2,' '+mez(((m-length(pp^.obsah)+1) div 2))+pp^.obsah+mez((m-length(pp^.obsah)) div 2)+' |');
       2: write(f2,mez(m+1-length(pp^.obsah))+pp^.obsah+' |');
       end;
     end;
     { viceradkove bunky }
     if (mapa[i,j]=3) or (mapa[i,j]=5) then
      begin
       pp:=bunka(i,j);
       m:=-3;
       for k:=1 to pp^.del_y do m:=m+3+maxlen[pp^.poz_y+k-1];
       if vytisk(i,true) then
        begin
         case pp^.cen1 of
         0: write(f2,' '+pp^.obsah+mez(m-length(pp^.obsah))+' |');
         1: write(f2,' '+mez(((m-length(pp^.obsah)+1) div 2))+pp^.obsah+mez((m-length(pp^.obsah)) div 2)+' |');
         2: write(f2,mez(m+1-length(pp^.obsah))+pp^.obsah+' |');
         end;
        end
       else
        write(f2,mez(m+2)+'|')
      end;
    end;
   { oddeleni radku }
   writeln(f2);
   if i=radku then
    write(f2,'+')
   else
    write(f2,'|');
   for j:=1 to sloupcu do
    if i=radku then
     if j=sloupcu then
      write(f2,minus(maxlen[j]+2)+'+')
     else
      write(f2,minus(maxlen[j]+3))
    else
     begin { viceradkove bunky }
      if (mapa[i+1,j]=3) then
       begin
        pp:=bunka(i+1,j);
        m:=-3;
        for k:=1 to pp^.del_y do m:=m+3+maxlen[pp^.poz_y+k-1];
        if vytisk(i,false) then
         begin
          case pp^.cen1 of
          0: write(f2,' '+pp^.obsah+mez(m-length(pp^.obsah))+' |');
          1: write(f2,' '+mez(((m-length(pp^.obsah)+1) div 2))+pp^.obsah+mez((m-length(pp^.obsah)) div 2)+' |');
          2: write(f2,mez(m+1-length(pp^.obsah))+pp^.obsah+' |');
          end;
         end
        else
         write(f2,mez(m+2)+'|')
       end
      else
       if (mapa[i+1,j]<>6) then
       if j=sloupcu then
        write(f2,minus(maxlen[j]+2)+'|')
       else
        write(f2,minus(maxlen[j]+2)+'+');
     end;
   writeln(f2);
  end;
 close(f2);
 if (ioresult<>0) then begin writeln('Error while working with files.'); chalt end;
end.