{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q+,R+,S+,T-,V+,X+,Y+}
{$M 65000,0,655360}

program galvosukis;

  const max_n = 100;   {EiluÑiÖ skaiÑius}
        max_m = 100;   {StulpeliÖ skaiÑius}

  type  tipas = integer;
        REl = ^El;
        El = record
               e, s : byte;     { EilutÓ, stulpelis }
               kr : 1..6;       { Kryptis }
               kitas : REl
             end;

  var t : text;
      lentele : array[1..max_n, 1..max_m] of tipas;

      reisk : array[1..max_n, 1..max_m] of word;
      {Kuriai reiÕkiniÖ grupei priklauso langelis}

      sarasas : array[1..max_n*max_m div 3 + 2] of REl;
      {ReiÕkiniÖ grupiÖ sÐraÕas}

      gylis, rezult : word;
      kiek_reisk, kiek : word;
      eil, st,     { eiluÑiÖ ir stulpeliÖ skaiÑius }
      i, j, pg  : word;
      z, p : Rel;

  const kryptis : array[1..6] of record  { Kurias "kryptis" patikrinti, }
                                         { ieÕkant reiÕkiniÖ }
                                   e1, s1, e2, s2 : shortint
                                 end = ((e1:0;s1:1;e2:0;s2:2),
                                        (e1:1;s1:0;e2:2;s2:0),
                                        (e1:1;s1:0;e2:1;s2:-1),
                                        (e1:1;s1:0;e2:1;s2:1),
                                        (e1:0;s1:1;e2:1;s2:1),
                                        (e1:0;s1:-1;e2:1;s2:-1));

  procedure duomenys;
    { Perskaitomi pradiniai duomenys }
    var i, j : integer;
  begin
    Assign(t,'lent.dat'); Reset(t);
    readln(t, eil, st);
    for i := 1 to eil do begin
      for j := 1 to st do read(t, lentele[i,j]);
      readln(t)
    end;
    Close(t);
    FillChar(reisk, SizeOf(reisk), 0);
    FillChar(sarasas, SizeOf(sarasas), 0);

  end;

  procedure zymeti(i,j,k,x : longint);
   {PaØymima, kad 3-langeliai priklauso konkreÑiai reiÕkiniÖ grupei}
  begin
    reisk[i,j]:=x;
    reisk[i+kryptis[k].e1,j+kryptis[k].s1]:=x;
    reisk[i+kryptis[k].e2,j+kryptis[k].s2]:=x;
  end;

  procedure rasti_reiskinius(i,j:longint);
    { Rasti reiÕkinius "iÕ" langelio (i,j) }
    var k, skirtingi, x : word;
        min : word;
        b : array[1..3]of word;
        z, p : REl;

    function reiskinys(a,b,c:longint):boolean;
      {Ar 3 skaiÑiai sudaro reiÕkinÔ}
    begin
      reiskinys := (a+b=c)or(a=b+c)or(a*b=c)or(a=b*c)or
                   (a=abs(b-c))or(abs(a-b)=c)or
                   (a/b=c)or(b/a=c)or(a=b/c)or(a=c/b)
    end;

    procedure prideti(prie, ka : longint);
     {Sujungia sÐraÕus (reiÕkiniÖ grupes) prie ir ka }
      var i : integer;
    begin
      z := sarasas[ka];
      while z <> nil do
        begin
          with z^ do zymeti(e,s,kr,prie); { PaØymime naujais numeriais }
          z := z^.kitas
        end;
      p := sarasas[prie];
      while p^.kitas <> nil do p := p^.kitas;
      p^.kitas := sarasas[ka];   { Sujungiame }
      for i := 1 to kiek_reisk do  { Koreguosime reiÕkiniÖ sÐraÕus }
        if reisk[sarasas[i]^.e,sarasas[i]^.s]>ka
          then begin
                 z := sarasas[i];
                 while z <> nil do
                   begin
                     with z^ do zymeti(e,s,kr,reisk[e,s]-1);
                     z := z^.kitas
                   end;
               end;
      Move(Sarasas[ka+1],Sarasas[ka],SizeOf(Rel)*(kiek_reisk-ka));
      dec(kiek_reisk)
    end;

    procedure prijungti;
    begin
      if (skirtingi = 0)and(x = kiek_reisk+1)
        then begin
               inc(kiek_reisk);
               GetMem(sarasas[kiek_reisk],SizeOf(El));
               with sarasas[kiek_reisk]^ do begin
                 e := i; s := j; kr := k; kitas := nil
               end
             end
        else begin
               z := sarasas[x];
               while z^.kitas<>nil do z:=z^.kitas;
               GetMem(p, SizeOf(el));
               with p^ do begin
                 e := i; s := j; kr := k; kitas := nil
               end;
               z^.kitas := p;
               if skirtingi = 1
                 then prideti(x,b[3])
                 else if skirtingi = 2
                        then begin
                               prideti(x,b[3]);
                               prideti(x,b[2])
                             end
             end
    end;

  begin
    for k := 1 to 6 do
      if (i+kryptis[k].e1<=eil)and(i+kryptis[k].e1>=1)and
         (i+kryptis[k].e2<=eil)and(i+kryptis[k].e2>=1)and
         (j+kryptis[k].s1<=st)and(j+kryptis[k].s1>=1)and
         (j+kryptis[k].s2<=st)and(j+kryptis[k].s2>=1)
        then if reiskinys(lentele[i,j],
                          lentele[i+kryptis[k].e1,j+kryptis[k].s1],
                          lentele[i+kryptis[k].e2,j+kryptis[k].s2])
                    {Jei radome reiÕkinÔ...}
               then begin
                     { IÕsiaiÕkinsime, kokiems reiÕkiniams tie langeliai
                       jau priklauso...}
                      b[1]:=reisk[i,j];
                      b[2]:=reisk[i+kryptis[k].e1,j+kryptis[k].s1];
                      b[3]:=reisk[i+kryptis[k].e2,j+kryptis[k].s2];
                      if b[1]>b[2]
                        then begin x:=b[1]; b[1]:=b[2]; b[2]:=x end;
                      if b[2]>b[3]
                        then begin x:=b[2]; b[2]:=b[3]; b[3]:=x end;
                      if b[1]>b[2]
                        then begin x:=b[1]; b[1]:=b[2]; b[2]:=x end;
                      if b[1]<>0
                        then begin
                               if (b[1]=b[2])and(b[2]=b[3])
                                 then skirtingi := 0
                                 else if (b[1]<>b[2])and(b[2]<>b[3])
                                        then skirtingi := 2
                                        else skirtingi := 1;
                               x:=b[1]
                             end
                        else if b[2]<>0
                               then begin
                                      x := b[2];
                                      if b[2]=b[3] then skirtingi := 0
                                        else skirtingi:=1;
                                    end
                               else begin
                                      skirtingi:=0;
                                      if b[3]=0 then x := kiek_reisk+1
                                        else x := b[3]
                                    end;
                      {x-kokiai grupei reiÕkinys bus priskirtas }
                      zymeti(i,j,k,x);
                      prijungti;  { Koreguosime grupiÖ sÐraÕÐ }
                    end
  end;

  function telpa(i,j,k,x : longint):boolean;
   { Ar dar galima ÔdÓti reiÕkinÔ }
  begin
    telpa := (reisk[i,j]=x)and(reisk[i+kryptis[k].e1,j+kryptis[k].s1]=x)and
             (reisk[i+kryptis[k].e2,j+kryptis[k].s2]=x)
  end;

  procedure ieskoti( lygis : word; kiek : word; kuris:Rel );
   { RekursinÓ paieÕkos proced×ra }
    var pag : integer;
        z : Rel;
  begin
      if kiek>rezult
         then rezult := kiek;
      if gylis-lygis+kiek>rezult
         then begin
                zymeti(kuris^.e,kuris^.s,kuris^.kr,0);  {UØimame}
                z := kuris;
                pag := 0;
                repeat
                  z := z^.kitas;    {keliaujama per sÐraÕÐ}
                  inc(pag);
                  if gylis-(lygis+pag)+kiek+1<=rezult
                     then break;
                  if z <> nil
                     then if telpa(z^.e,z^.s,z^.kr,i) {Jei reiÕkinys telpa...}
                            then ieskoti(lygis+pag, kiek+1, z)
                until z = nil;
                zymeti(kuris^.e,kuris^.s,kuris^.kr,i); {atlaisviname}
              end
  end;

  procedure rezultatai;
  begin
    Assign(t, 'lent.rez'); Rewrite(t);
    write(t, kiek);
    Close(t);
  end;

  procedure istrinti;
  {Atlaisvinama uØimta atmintis}
  begin
    for i := 1 to kiek_reisk do begin
      p := sarasas[i];
      repeat
        z := p^.kitas;
        FreeMem(p,SizeOf(EL));
        p := z
      until z = nil;
    end
  end;

begin
  duomenys;

  kiek_reisk := 0;
  for i := 1 to eil do
    for j := 1 to st do
      rasti_reiskinius(i,j);

  kiek := 0;
  j := 0;
  for i := 1 to kiek_reisk do begin
    gylis := 0;      { skaiÑiuosime kiek reiÕkiniÖ sudaro i-aja grupÒ }
    z := sarasas[i];
    while z<>Nil do begin
      inc(gylis);
      z := z^.kitas
    end;
    rezult := 0;
    if gylis > 2
      then begin
             pg := 1; p := sarasas[i];
             while p <> nil do begin
               ieskoti(pg,1,p);
               p := p^.kitas; inc(pg);
               if p <> nil then if gylis-pg+1<rezult then break
             end;
             kiek := kiek + rezult;
           end
      else inc(kiek);
  end;

  rezultatai;
  istrinti
end.
