 #include <windows.h>
 #include <math.h>
 UINT tekbuf;
 extern char *RS,*RSA,*C,*IZ;
 extern UINT *LN,*R,*Z,*SE,*STK,*F,*st,*LL,*TT,*S,*OBL1,*OBL2,*OBL3,
	 *OBL4,*CVOTR,*CVOBJ,*CVSTR,*ZCV,*PROT,*CLIN,ist,rish,risl,oblshirina,ttt,
	 oblvisota,razmerobl,SETX,SETY,SETEND,CVOTREND,CVOBJEND,PROTEND,CVEND,LINEND,OBJBGN,
	 PTNBGN,RR1,RR2,RR3,RR4,RR5,RR6,RR7,
	 *extr,*extr1,*extr2,*extr3,indobl1,indobl2;
 extern UINT mem(UINT);
 extern UINT text1(UINT*);
 extern void(* cvptn[])();
 extern UINT text2(UINT*);
 extern UINT convchisl(UINT);
 extern UINT losint(INT);
 extern UINT intlos(int);
 extern UINT lindelta(UINT);
 extern UINT cvnutr(UINT,UINT);
 extern UINT loschisl(UINT);
 extern UINT diskr(UINT,UINT,UINT);
 extern UINT cvrasst(UINT,UINT);
 extern UINT linsokr(UINT,UINT);
 extern void cfree(UINT,UINT);
 void cvuprostit(void);
 extern int chisli(UINT);
 extern void opr(UINT,UINT);
 extern int intchisl(UINT);
 extern UINT sffx(UINT,UINT);
 void reotrezki(void);
 void regkletka (int,int,UINT,UINT);
 void izmkletka(UINT,UINT,UINT,UINT);
 UINT ukonc(UINT,UINT,UINT);
 UINT ugoriz(UINT, UINT, UINT, UINT);
 UINT uvniz(UINT,UINT,UINT);
 UINT oprtabl(UINT,UINT,UINT);
 void izobrprot(UINT*);
 void izobrvosst(void);
 void cvbuf(UINT);
 void cvkonc(UINT,UINT);
 void cvgoriz(UINT, UINT, UINT, UINT, UINT);
 void cvniz(UINT);
 void oprgrup(UINT*);
 void cvpjatna(void);
 void cvobjekti(void);
 void vtorotrezki(void);
 void ctchk(UINT,UINT);
 void glad1(void);
 void glad2(void);
 void glad3(void);
 void cvplus(UINT, UINT);
 void prot1(UINT,UINT);
 void prot2(UINT,UINT);
 void prot3(void);
 void prot4(void);
 UINT naprlin(UINT);
 UINT obrnaprlin(UINT);
 int minkvr(UINT,UINT);
 UINT cvklass;
 UINT prjamdlin;
 UINT cvnapr;
 UINT tekcvobj;

   // registri priema analiza dobavljaemogo pjatna:

 UINT ptn1; // staroe pjatno
 UINT endp; // pervaja neispolzuemaja jachejka v R
 UINT hrk1; // harakteristiki starogo pjatna
 UINT cvt1; // cvet starogo pjatna
 UINT grc1; // gruppa cvetnosti starogo pjatna
 UINT lin;  // razdeljajushaja linija
 UINT ptn2; // novoe pjatno
 UINT hrk2; // harakteristiki novogo pjatna
 UINT cvt2; // cvet novogo pjatna
 UINT grc2; // gruppa cvetnosti novogo pjatna
 UINT tekgrup; // smeshenie v CVOTR nabora cvetov
               // dlja klasterizacii objekta

 UINT CVGR[74] = {1,9,3,1,18,12,5,6,7,2, // 1 - 10
                 8,4,9,18,10,9,9,11,11,16, //11 - 20
                 9,12,8,13,13,2,14,9,13,15, // 21 - 30
                 8,16,13,15,7,4,10,17,9,6, // 31 - 40
                 6,13,10,17,15,2,7,10,6,2, // 41 - 50
                 2,15,15,15,15,16,2,7,2,4, // 51 - 60
                 16,3,14,3,2,13,11,2,2,2, // 61 - 70
                 5,14,6,17 // 71 - 74
};

UINT CVKL[18] = {5,5,2,4,6,3,4,1,2,1, // 1- 10
                 2,4,1,3,1,3,3,5 // 11 - 17
};

UINT SVCV[74] = {2,2,3,21,1,39,7,40,35,51, // 1 - 10
                 23,28,2,70,37,2,16,19,17,32, // 11 - 20
                 2,4,43,25,42,22,72,2,25,2, // 21 - 30
                 23,13,53,37,36,60,30,44,2,44, // 31 - 40
                 73,53,15,74,55,5,35,15,20,10, // 41 - 50
                 69,53,54,30,37,61,22,6,6,39, // 51 - 60
                 13,3,72,3,68,27,17,57,1,4, // 61 - 70
                 11,13,8,2 // 71 - 74
};

UINT TMCV[74] = {5,16,62,70,46,58,7,73,7,50, // 1 - 10
                 71,36,72,65,43,17,19,7,18,49, // 11 - 20
                 4,26,11,11,29,65,66,27,11,54, // 21 - 30
                 11,2,43,55,47,35,34,49,36,8, // 31 - 40
                 71,25,23,40,43,68,9,43,56,7, // 41 - 50
                 10,33,52,34,52,41,68,47,50,36, // 51 - 60
                 56,42,18,43,7,71,18,65,51,14, // 61- 70
                 71,27,41,44 // 71 - 74
};


  // registracija v massive tochki a ssilki na liniju b

 void Linijatochki(UINT a, UINT b)

  {UINT i,c,d,p;
   c = LN[a];
   i = a+3;
   while(LN[i] != 0)
   i++;
   LN[i] = b;
   i++;
   d = a+c;
   if(i < d)
    {LN[i] = 0;}
   else
    {LN[a] += 4;
     p = LN[0]; p--;
     LN[0] += 4;
     while(p >= i)
      {LN[p+4] = LN[p];
       p--;
      }
     LN[i] = 0;
     c = LN[2500];
     d = 2501;
     while(d < c)
      {p = LN[d+2];
       if(a < p)LN[d+2] += 4;
       p = LN[d+3];
       if(a < p)LN[d+3] += 4;
       d += LN[d];
      }
    }
  }

 void Doplin(UINT a)// a - smeshenie fragmenta linii v LN.
                    // Massiv etogo fragmenta udlinjaetsja
                    // na 10 tochek. Massivi fragmentov,
                    // sledujushie za nim, sdvigajutsja.
                    // Korrektirujutsja ssilki na fragment
                    // iz massiva tochek i buferov
                    // predidushego i tekushego otrezkov.

 {UINT b,c,d,e;
  b = LN[2500] - 1;
  c = a + LN[a];
  for(d = b; d >= c; d--)LN[d+10] = LN[d];
  LN[2500] += 10;
  LN[a] += 10;
  b = LN[0];   // korrekcia ssilok iz massiva tochek
  c = 1;
  while(c < b)
   {d = c + 3;
    while(LN[d] != 0)
     {if(LN[d] > a)
      LN[d] += 10;
      d++;
     }
    c += LN[c];
   }
  for(b = 0; b <= 7000; b += 7000)
   {c = R[b];
    d = b + 1;
    while(d < c)
     {e = R[d];
      if(e > a)
       {R[d] += 10; R[d+1] += 10;}
      d += 5;
     }
   }
 }

 void Stoplin(UINT a, UINT b, UINT c, UINT d,UINT m)
  // a - smeshenie fragmenta linii v LN; b - ordinata
  // tochki obriva fragmenta; c - smeshenie v R nachala
  // bufera predidushego stolbca. d - smeshenie v R cadra
  // dannogo fragmenta. m - indikator primikanija fragmenta
  // sprava (0 - ne primikaet, 1 - primikaet). Proishodit
  // zavershenie fragmenta so vvodom dlja ego konca novoj
  // tochki. Esli obriv proizoshel v seredine poslednego
  // vert. otrezka fragmenta, to dlja ostavshejsja chasti
  // etogo otrezka vvoditsja novij fragment, registriruemij
  // v bufere predidushego stolbca.

 {UINT e,f,i,j,k,s,t;
  e = LN[a+1]; k = 0xFFFFFFFF; // esli linija eshe ne pro-
  i = R[d+1]; j = i - R[d];  // dolgena na tekushij stol-
  if((e - 1) != j)  // bec, to k = 0xFFFFFFFF,
   {k = LN[i+1]; e--; // inache k = ordinata
    LN[a+1] -= 1;   // vihoda dlja tekushego stolbca
   }
  f = e - 7; // f - prirashenie abscissi
  e += a; e--; // dlja konca linii
  LN[e] = b;
  i = LN[a+2];
  f += LN[i+1]; // f - abscissa konca
  s = LN[a+3];
  if(s != 0)
   {if(LN[s+2] == b && (f == LN[s+1] || m == 0))return;
   }
  i = LN[0];
  LN[0] += 6;  // vvod novoj tochki dlja konca linii
  LN[i] = 6;
  LN[i+1] = f;
  LN[i+2] = b;
  LN[i+3] = a;
  LN[i+4] = 0;
  LN[a+3] = i;
  if(b == R[d+3] && k == 0xFFFFFFFF && s == 0)return;
  e = LN[2500]; // e - smeshenie novoj linii v LN
  LN[2500] += 16;
  LN[e] = 16;
  LN[e+2] = i;
  Linijatochki(i,e);
  LN[e+3] = s;
  LN[e+4] = LN[i+1];
  LN[e+5] = LN[i+2];
  if(s != 0)
   {j = s+3;
    while(LN[j] != a)j++;
    LN[j] = e;
   }
  t = e+6;
  if(s != 0 && f != LN[s+1] && R[d+3] == b)
   {LN[t] = LN[s+2]; t++;}
  LN[t] = R[d+3]; t++;
  if(k != 0xFFFFFFFF)
   {LN[t] = k; t++;}
  LN[e+1] = t - e;
  if(R[d+3] == b && k == 0xFFFFFFFF)
   {t = LN[e+2];
    LN[e+2] = LN[e+3];
    LN[e+3] = t;
    t = LN[e+2];
    LN[e+4] = LN[t+1];
    LN[e+5] = LN[t+2];
    return;
   }
  if(R[d+3] <= b) // linija v napravlenii snizu vverh
   {if(k == 0xFFFFFFFF && s == 0)
     {i = LN[0];
      LN[0] += 6;  // zakrivaetsja novij otrezok
      LN[i] = 6;
      LN[i+1] = f;
      LN[i+2] = R[d+3];
      LN[i+3] = e;
      LN[i+4] = 0;
      LN[e+3] = i;
     }
    R[d+3] = b;  // korrekcija bufera predid.stolbca
    j = R[c];
    j--;
    R[c] += 5;
    while(j >= d)
     {R[j+5] = R[j]; j--;}
    R[d] = e;
    R[d+1] = e+6;
    R[d+2] = b;
    R[d+3] = LN[i+2];
    R[d+4] = 1;
    if(k != 0xFFFFFFFF)
     {i = (c == 0 ? 7000 : 0);
      j = R[i];
      R[j - 5] = e;
      R[j - 4] = e+7;
     }
   }
  else // linija v napravlenii sverhu vniz
   {j = R[c];
    j--;
    R[c] += 5;
    while(j > d)
     {R[j+5] = R[j]; j--;}
    j = d+5;
    R[j] = e;
    R[j+1] = e+6;
    R[j+2] = b;
    R[j+3] = R[d+3];
    R[d+3] = b;
    R[j+4] = 1;
   }

 }

 UINT Novlin(UINT a, UINT b, UINT c, UINT d)
  // a - abscissa nachala, b - ordinata nachala,
  // c - ordinata tochki vihoda iz pervogo vert.
  // otrezka, d - 0 libo smeshenie v LN tochki -
  // nachala fragmenta. Vvodit novij fragment linii i
  // vozvrashaet ego smeshenie v LN.

 {UINT e,i;
  e = LN[2500];
  LN[2500] += 16;
  LN[e] = 16;
  if(d == 0)
   {LN[e+1] = 7;
    i = LN[0];
    LN[0] += 6;
    LN[i] = 6;
    LN[i+1] = a;
    LN[i+2] = b;
    LN[i+3] = e;
    LN[i+4] = 0;
    LN[e+2] = i;
    LN[e+4] = a;
    LN[e+5] = b;
    LN[e+6] = c;
   }
  else
   {LN[e+1] = 8;
    LN[e+2] = d;
    Linijatochki(d,e);
    LN[e+4] = LN[d+1];
    LN[e+5] = LN[d+2];
    LN[e+6] = LN[d+2];
    LN[e+7] = c;
   }
  LN[e+3] = 0;
  return e;
 }

 void Otogdlin(UINT a, UINT b)
  // a - smeshenie nachala massiva fragmenta linii;
  // b - diapazon otogdestvlenija. Predprinimaetsja
  // popitka otogdestvit konci fragmenta.

 {UINT i,c,d,e,n,p,q,r,u,v,t,m;
  d = 0; e = 0; n = 0; // d,e - abscissa i ordinata centra
                       // n - chislo primikajushih linij
  for(i = a+2; i < a+4; i++)
   {c = LN[i];  // tek. tochka
    c += 3;
    while(LN[c] != 0)
     {p = LN[c]; n++;
      if(LN[p+2] == LN[i])
       {d += LN[p+4];
        e += LN[p+5];
       }
      else
       {q = LN[p+1];
        r = q - 7;
        d += r;
        d += LN[p+4];
        q += p;
        e += LN[q-1];
       }
      c++;
     }
   }
  d /= n; e /= n;
  for(i = a+2; i < a+4; i++)
   {c = LN[i];  // tek. tochka
    c += 3;
    while(LN[c] != 0)
     {p = LN[c];
      if(LN[p+2] == LN[i])
       {u = LN[p+4];
        v = LN[p+5];
        if(u + b < d || d + b < u || e + b < v ||
           v + b < e)return;
       }
      else
       {q = LN[p+1];
        u = q - 7;
        u += LN[p+4];
        q += p;
        v = LN[q-1];
        if(u + b < d || d + b < u || e + b < v ||
           v + b < e)return;
       }
      c++;
     }
   }
  t = LN[a+2];
  LN[a+2] = 0;
  c = LN[a+3];
  if(t == c)
   {c += 3;
    while(LN[c] != a)c++;
    while(LN[c] != 0)
     {LN[c] = LN[c+1];
      c++;
     }
    return;
   }
  q = c;
  c += 3; n = 0;
  while(LN[c] != 0)
   {p = LN[c];
    if(p != a)
     {n++;
      for(i=p+2; i<p+4; i++)
       {if(LN[i] == t)n--;
        if(LN[i] == LN[a+3])LN[i] = t;
       }
     }
    else
     {i = c;
      while(LN[i] != 0)
       {LN[i] = LN[i+1];
        i++;
       }
      c--;
     }
    c++;
   }
  c = t+3; m = t;
  while(LN[c] != 0)c++;
  r = c - t; r += n; r++;
  if(LN[t] < r)
   {r -= LN[t];
    i = t + LN[t];
    LN[t] += r;
    if(t < q)q += r;
    p = LN[0]; p--;
    LN[0] += r;
    while(p >= i)
     {LN[p+r] = LN[p];
      p--;
     }
    u = LN[2500];
    v = 2501;
    while(v < u)
     {p = LN[v+2];
      if(t < p)LN[v+2] += r;
      p = LN[v+3];
      if(t < p)LN[v+3] += r;
      v += LN[v];
     }
   }
  q += 3;
  while(LN[q] != 0)
   {t = LN[q];
    LN[q] = 0;
    if(t != a)
     {i = 0;
      for(n = m+3; n < c; n++)
       {if(LN[n] == t)
         {i = 1; break;}
       }
      if(i == 0)
       {LN[c] = t;
        c++;
       }
     }
    q++;
   }
  LN[c] = 0;
  return;
 }

 UINT Razvertlin(UINT a, UINT m) // a - ssilka
    // na liniju v bufere linij; m - nachalo razvertki
    // linii v massive LL.
    // V massive LL nachinaja s m-j jachejki
    // sozdajetsja spisok posledovatelno prohodimih
    // tochek linii. Kagdaja tochka predstavlena dvumja
    // idushimi podrjad 32-bitnimi slovami - abscissoj i
    // ordinatoj. Vozvrashaet smeshenie pervoj svobodnoj
    // jachejki v LL.

 {UINT b,c,d,e,f,i,j,n;
  n = m;
  while(2500 < a)
   {b = LN[a+4];
    if(b & 0x80000000)
     {b &= 0x0000FFFF;
      d = LN[a+1];
      b += d;
      b -= 7; // b - abscissa nachala
      d += a; d--;
      c = LN[d]; // c - ordinata nachala
      f = a+5;
      for(i = d-1; f<= i; i--)
       {e = LN[i];
        if(e == c)
         {if(n == m || LL[n-2] != b || LL[n-1] != c)
           {LL[n] = b; LL[n+1] = c; n += 2;}
         }
        else
         {if(c < e)
           {for(j = c; j <= e; j++)
             {if(n == m || LL[n-1] != j || LL[n-2] != b)
               {LL[n] = b; LL[n+1] = j; n += 2;}
             }
           }
          else
           {for(j = c; j >= e; j--)
             {if(n == m || LL[n-1] != j || LL[n-2] != b)
               {LL[n] = b; LL[n+1] = j; n += 2;}
             }
           }
         }
        b--;
        c = e;
        e = LN[i-1];
        if(c < e)c++;
        else
         {if(e < c)c--;
         }
       }
     }
    else
     {b &= 0x0000FFFF;
      c = LN[a+5]; // b - tek. abscissa, c - tek.ordinata
      d = LN[a+1]; d += a;
      for(i = a+6; i < d; i++)
       {e = LN[i];
        if(e == c)
         {if(n == m || LL[n-2] != b || LL[n-1] != c)
           {LL[n] = b; LL[n+1] = c; n += 2;}
         }
        else
         {if(c < e)
           {for(j = c; j <= e; j++)
             {if(n == m || LL[n-1] != j || LL[n-2] != b)
               {LL[n] = b; LL[n+1] = j; n += 2;}
             }
           }
          else
           {for(j = c; j >= e; j--)
             {if(n == m || LL[n-1] != j || LL[n-2] != b)
               {LL[n] = b; LL[n+1] = j; n += 2;}
             }
           }
         }
        b++;
        c = e;
        e = LN[i+1];
        if(c < e)c++;
        else
         {if(e < c)c--;
         }
       }
     }
    a = LN[a+3];
   }
  return n;
 }


 void linfragm(UINT *a) // operator "risunok(linii...)"

  {UINT b,c,d,d1,d2,d3,d4,e1,e2,e3,e4,e5,f,*h,i,j,p1,p2,
    p3,p4,p5,p6,p7,p8,p9,*r,t1,t2,t3;
   b = *(a+1);
   c = Z[b+2]; rish = convchisl(c);
   rish *= 2; // rish - shirina risunka v bajtah
   c = Z[b+4]; risl = convchisl(c);
   risl *= 2; // risl - dlina koda risunka v bajtah
   d = *(a+2);
   d1 = Z[d+2] - 0x00200104;  // ramka
   d2 = Z[d+4] - 0x00200104;
   d3 = Z[d+6] - 0x00200104;
   d4 = Z[d+8] - 0x00200104;
    // dalee budet zapolnjatsja bufer fragmentov linij LN.
    // V nachale etogo bufera - massiv tochek. Pervaja
    // jachejka ego - smeshenie pervoj svobodnoj
    // jachejki. Dlja kagdoj tochki ee massiv
    // nachinaetsja s jachejki- dlini massiva tochki;
    // zatem idut stolbec - stroka; dalee - ssilki
    // (smeshenija v LN) na linii s koncom v etoj tochke.
    // Posle ssilok na linii stoit 0.
    // Nachinaja s 2500-j jachejki LN - massiv fragmentov
    // linij. Ego pervaja jachejka - smeshenie pervoj
    // svobodnoj jachejki; massiv kagdogo fragmenta
    // nachinaetsja s jachejki - dlini massiva fragmenta,
    // zatem - smeshenie ot nachala massiva do pervoj
    // nezanjatoj ego jachejki, dalee - ssilki na nachalo
    // i konec fragmenta (smeshenija v LN);
    // zatem: v mladshih 16 bitah - abscissa nachala
    // fragmenta, a v starshem bite - ukazatel orientacii
    // fragmenta (0 - prjamaja, 1 - obratnaja); zatem
    // ordinata nachala fragmenta; dalee - massiv ordinat
    // vihoda na konci vertikalnih otrezkov fragmenta,
    // prohodimih po mere vozrastanija abscissi.

   LN[0] = 1;
   LN[2500] = 2501;
   R[0] = 1; R[7000] = 7001;
    // v massive R - dva bufera prodolgenija linij -
    // tekushego stolbca i predidushego stolbca. Odin iz
    // nih nachinaetsja s 0-j, drugoj - s 7000-j jachejki.
    // V R[0],R[7000] - smeshenija pervih svobodnih
    // jacheek buferov; dalee - pjaterki (nachalo massiva
    // fragmenta v LN - sootv. tochke jachejka v etom
    // massive (smeshenie v LN) - ordinata vhoda - ordinata
    // vihoda - ukazatel nachala fragmenta (0) libo ego
    // prodolgenija (1) libo togo, chto fragment uge
    // prodolgen (2)).

   p1 = 0; // p1 - smeshenie v R nachala bufera
            // predidushego stolbca

   p5 = 7000; // p5 - smeshenie v R nachala bufera
                // tekushego stolbca
   for(e1 = d1; e1 <= d3; e1 ++)// cicle prosmotra
                                //stolbcov
                                // e1 - tekushij stolbec
    {e2 = 0xFFFFFFFF; // e2 - verhnij konec tekushego
                      // otrezka libo 0xFFFFFFFF
     t1 = e1 >> 3; // t1 - nomer bajta tekushego
                     // stolbca v stroke
     t2 = e1 & 0x7;
     f = 0x80;
     if(t2 != 0)f >>= t2; // f - maska stolbca
     e3 = d2;
     e3 *= rish; e3 += t1; // e3 - smeshenie bajta
                           // tekushego stolbca v RS;
     p2 = p1 +1; p3 = R[p1];
       // p2 - nachalo prosmotra bufera predidushego
       // stolbca, p3 - konec prosmotra
     R[p5] = p5 + 1; // sbros bufera tekushego stolbca
     p6 = p5 + 1; // p6 - pervaja svob.jachejka
                    // bufera tek.stolbca
     p4 = 0xFFFFFFFF;
     if(p2 < p3)
      {p4 = R[p2+2];
       if(p4 < R[p2+3])p4 = R[p2+3];
      } // p4 - ordinata nignego konca pervogo
        // neobrabotannogo otrezka predidushego stolbca
     for(e4 = d2; e4 <= d4; e4++, e3 += rish)
        // cicle prosmotra pikselej. e4 - tekushaja
        // stroka
      {e5 = RS[e3]; e5 &= f;
       if(e5 != 0)
        {if(e2 == 0xFFFFFFFF) // pustaja zona v
                               // tek.stolbce
          {if(p4 < e4)
            {if(R[p2+4] != 2) // konec linii
              {t1 = R[p2]; // t1 - smeshenie linii v LN
               t2 = R[p2+3];
               if(LN[t1+3] == 0)Stoplin(t1,t2,p1,p2,0);
              }
             p2 += 5;
             p4 = 0xFFFFFFFF;
             if(p2 < p3)
              {p4 = R[p2+2];
               if(p4 < R[p2+3])p4 = R[p2+3];
              }
            }
          }
         else // obrabotka vertikalnogo
              // otrezka. e2 - verhnij konec;
              // (e4 - 1) - nignij konec.
          {if(p4 < (e2-1)) // proverka prohogdenija
                           // tek. otrezka predidushego
                           // stolbca
            {if(R[p2+4] != 2) // konec linii
              {t1 = R[p2]; // t1 - smeshenie linii v LN
               t2 = R[p2+3];
               if(LN[t1+3] == 0)Stoplin(t1,t2,p1,p2,0);
              }
             p2 += 5;
             p4 = 0xFFFFFFFF;
             if(p2 < p3)
              {p4 = R[p2+2];
               if(p4 < R[p2+3])p4 = R[p2+3];
              }
            }
           if(p3 <= p2 ||(e4 < R[p2+2] &&
                e4 < R[p2+3]))
              // vvod novoj linii, esli novij otrezok
              // ne peresekaetsja so starimi
            {t1 = Novlin(e1,e2,e4-1,0);
              // t1 - smeshenie nachala novoj linii
             R[p5] += 5;  // registracija novoj linii
             R[p6] = t1;  // v bufere tek.stolbca
             R[p6+1] = t1+6;
             R[p6+2] = e2;
             R[p6+3] = e4 - 1;
             R[p6+4] = 0;
             p6 += 5;
             e2 = 0xFFFFFFFF;
            }
           else // novij otrezok pereseksja s otrezkom
                // predidushego stolbca
            {p7 = 0; // p7 - libo 0, libo smeshenie
                     // v LN linii, sootvetstvujushej
                     // otrezku ot e2 do e4-1
             while(p2 < p3 &&
                   (R[p2+2] <= e4 || R[p2+3] <= e4))
               // obrabotka ocherednogo starogo otrezka,
               // peresekajushegosja s novim
              {if(R[p2+2] >= R[p2+3])
                  // linija idet snizu vverh (nestrogo)
                {p8 = R[p2+2];  // ordinata vhoda
                 p9 = R[p2+3];  // ordinata vihoda
                 t1 = R[p2]; // smeshenie linii v LN
                 t2 = LN[t1+4];
                 t2 += LN[t1+1];
                 t2 -= 7;
                 if(p7 == 0) // novij otrezok poka ne
                               // javljaetsja liniej
                  {if(LN[t1+3] == 0 && t2 < e1 &&
                      (p9 == e4 || (p9+1) == e4))
                     // prodolgenie linii
                    {R[p2+4] = 2;
                     t2 = LN[t1+1];
                     if(t2 == LN[t1])Doplin(t1);
                     t2 += t1;
                     LN[t2] = e2;
                     LN[t1+1] += 1;
                     R[p5] += 5; // registracija linii
                     R[p6] = t1; // v bufere tek.stolbca
                     R[p6+1] = t2;
                     R[p6+2] = e4-1;
                     R[p6+3] = e2;
                     R[p6+4] = 1;
                     p6 += 5;
                     e2 = 0xFFFFFFFF;
                     break;
                    }
                   else // prodolgenie ne usmotreno
                    {if((R[p2+4] == 0 || p8 == p9) &&
                         t2 < e1 && LN[t1+3] == 0 &&
                        (p8 == e2 || p8+1 == e2))
                       // perestanovka koncov staroj
                       // linii i ee prodolgenie
                      {R[p2+4] = 2;
                       if(p8 != p9)
                        {t2 = LN[t1+2]; // perestanovka
                         LN[t2+2] = p9; // koncov linii
                         R[p2+2] = p9;
                         R[p2+3] = p8;
                         LN[t1+5] = p9;
                         LN[t1+6] = p8;
                        }
                       t2 = LN[t1+1];
                       if(t2 == LN[t1])Doplin(t1);
                       t2 += t1;
                       LN[t2] = e4-1;
                       LN[t1+1] += 1;
                       p7 = t1;
                       p2 += 5;
                      }
                     else // osobie sluchai
                      {t1 = (e2 < p9 ? p9 : (p8 < e2 ? p8 :
                        e2));
                        // tochka obriva staroj linii
                       t2 = R[p2]; //t2 - smeshenie
                                     // staroj linii v LN
                       i = LN[t2+2];
                       if(e2 < p8 || (e1-1) != LN[i+1])
                        {Stoplin(t2, t1, p1, p2,1);
                         if(t2 != R[p2])
                          {p2 += 5; p3 = R[p1];
                          }
                         i = LN[t2+3];
                        }
                       if(e2 < t1)  // otrezanie
                                      // verhnego konca
                        {t3 = Novlin(0,0,e2,i);
                         R[p5] += 5; // registracija
                         R[p6] = t3; // linii
                         R[p6+1] = t3 + 7; // v bufere
                         R[p6+2] = t1; // tek .stolbca
                         R[p6+3] = e2;
                         R[p6+4] = 1;
                         p6 += 5;
                        }
                       if(e4-1 == e2 && e2 < t1)
                        {e2 = 0xFFFFFFFF; break;}
                       t3 = Novlin(0,0,e4-1,i);
                        // t3 - linija novogo otrezka
                       if(e2 < t1)
                        e2 = t1; // novoe nachalo
                                  // otrezka
                       if((e4 - 1) <= R[p2+2])
                        {R[p5] += 5; // registracija
                         R[p6] = t3; // linii
                         R[p6+1] = t3 + 7; // v bufere
                         R[p6+2] = t1; // tek .stolbca
                         R[p6+3] = e4-1;
                         R[p6+4] = 1;
                         p6 += 5;
                         e2 = 0xFFFFFFFF;
                         break;
                        }
                       else
                        {p2 += 5; p7 = t3;
                        }
                      }
                    }
                   }
                  else // novij otrezok - linija
                   {t1 = R[p2]; // staraja linija
                    Stoplin(t1, p9, p1, p2,1);
                    t2 = LN[t1+3]; // t2 - konec staroj
                                   // linii
                    LN[p7+3] = t2;
                    Linijatochki(t2,p7);
                    t3 = LN[p7+1]; t3 += p7;
                    LN[t3-1] = (e4-1 < p9 ? e4-1 : p9);
                    R[p5] += 5; // registracija
                    R[p6] = p7; // linii p7
                    R[p6+1] = t3-1; // v bufere
                    R[p6+2] = e2; // tek .stolbca
                    R[p6+3] = (e4-1 < p9 ? e4-1 : p9);
                    R[p6+4] = 1;
                    p6 += 5; p7 = 0;
                    if((e4 - 1)<= p9)
                     {e2 = 0xFFFFFFFF;
                      break;
                     }
                    t1 = Novlin(0,0,e4-1,t2);
                    if(e2 < p9)e2 = p9;
                    if((e4 - 1) <= R[p2+2])
                     {R[p5] += 5; // registracija
                      R[p6] = t1; // linii
                      R[p6+1] = t1 + 7; // v bufere
                      R[p6+2] = p9; // tek .stolbca
                      R[p6+3] = e4-1;
                      R[p6+4] = 1;
                      p6 += 5;
                      e2 = 0xFFFFFFFF;
                      break;
                     }
                    else
                     {p2 += 5; p7 = t1;
                     }

                   }
                }
               else // linija idet strogo sverhu vniz
                {p8 = R[p2+2];  // ordinata vhoda
                 p9 = R[p2+3];  // ordinata vihoda
                 t1 = R[p2]; // smeshenie linii v LN
                 if(p7 == 0) // novij otrezok poka ne
                             // javljaetsja liniej
                  {if((p9 == e2 || (p9+1) == e2) &&
                       LN[t1+3] == 0)
                     // prodolgenie linii
                    {R[p2+4] = 2;
                     t2 = LN[t1+1];
                     if(t2 == LN[t1])Doplin(t1);
                     t2 += t1;
                     LN[t2] = e4-1;
                     LN[t1+1] += 1;
                     p7 = t1;
                     p2 += 5;
                    }
                   else // prodolgenie ne usmotreno
                    {if(R[p2+4] == 0 &&
                      (p8 == e4 || p8+1 == e4))
                      // perestanovka koncov staroj
                      // linii i ee prodolgenie
                      {R[p2+4] = 2;
                       t1 = R[p2];
                       t2 = LN[t1+2]; // perestanovka
                       LN[t2+2] = p9; // koncov linii
                       R[p2+2] = p9;
                       R[p2+3] = p8;
                       LN[t1+5] = p9;
                       LN[t1+6] = p8;
                       t2 = LN[t1+1];
                       if(t2 == LN[t1])Doplin(t1);
                       LN[t1+1] += 1;
                       t2 += t1;
                       LN[t2] = e2;
                       R[p5] += 5; // registracija linii
                       R[p6] = t1; // v bufere tek.stolbca
                       R[p6+1] = t2;
                       R[p6+2] = e4-1;
                       R[p6+3] = e2;
                       R[p6+4] = 1;
                       p6 += 5;
                       e2 = 0xFFFFFFFF;
                       break;
                      }
                     else // osobie sluchai
                      {t1 = ((e4 - 1) < p9 ? ((e4-1) < p8 ? p8 : e4-1):p9);
                        // tochka obriva staroj linii
                       t2 = R[p2]; //t2 - smeshenie
                                   // staroj linii v LN
                       Stoplin(t2, t1, p1, p2,1);
                       if(t1 < p9)
                        {p2 += 5; p3 = R[p1];
                        }
                       i = LN[t2+3];
                             // otrezanie verhnego konca
                       if(e2 <= t1)
                        {t3 = Novlin(0,0,e2,i);
                         R[p5] += 5; // registracija
                         R[p6] = t3; // linii
                         R[p6+1] = t3 + 7; // v bufere
                         R[p6+2] = t1; // tek .stolbca
                         R[p6+3] = e2;
                         R[p6+4] = 1;
                         p6 += 5;
                        }
                       if((e4 - 1) <= t1)
                        {e2 = 0xFFFFFFFF; break;}
                             // prodolgenie otrezka vniz
                       t3 = Novlin(0,0,e4-1,i);
                           // t3 - linija novogo otrezka
                       e2 = t1; // novoe nachalo
                                // otrezka
                       p2 += 5; p7 = t3;
                      }
                    }
                  }
                 else // novij otrezok - linija
                  {t1 = R[p2]; // staraja linija
                   if(((e4 - 1) == p8 || e4 == p8) &&
                      LN[t1+1] == 7)
                    {t2 = LN[t1+2]; // nachalo staroj linii
                     LN[p7+3] = t2;
                     Linijatochki(t2,p7);
                     t3 = LN[p7+1];
                     t3 += p7;
                     R[p5] += 5; // registracija
                     R[p6] = p7; // linii p7
                     R[p6+1] = t3-1; // v bufere
                     R[p6+2] = e2; // tek .stolbca
                     R[p6+3] = (e4-1);
                     R[p6+4] = 1;
                     p6 += 5; p7 = 0;
                     e2 = 0xFFFFFFFF;
                     break;
                    }
                   else
                    {i = ((e4 - 1) < p9 ? (e4 - 1) : p9);
                     // i - tochka obriva staroj linii
                     Stoplin(t1, i, p1, p2,1);
                     if((e4 - 1) < p9)
                      {p2 += 5; p3 = R[p1];
                      }
                     t2 = LN[t1+3]; // t2 - konec staroj
                                  // linii
                     LN[p7+3] = t2;
                     Linijatochki(t2,p7);
                     t3 = LN[p7+1]; t3 += p7;
                     LN[t3-1] = i;
                     R[p5] += 5; // registracija
                     R[p6] = p7; // linii p7
                     R[p6+1] = t3-1; // v bufere
                     R[p6+2] = e2; // tek .stolbca
                     R[p6+3] = i;
                     R[p6+4] = 1;
                     p6 += 5; p7 = 0;
                     if((e4 - 1)<= p9)
                      {e2 = 0xFFFFFFFF;
                       break;
                      }
                     t1 = Novlin(0,0,e4-1,t2);
                     e2 = i;
                     p2 += 5; p7 = t1;
                    }
                  }
                }
              }
             if(p7 != 0) // novaja linija v tek.stolbce
              {t3 = LN[p7+1]; t3 += p7; t3--;
               R[p5] += 5; // registracija linii
               R[p6] = p7; // v bufere tek.stolbca
               R[p6+1] = t3;
               R[p6+2] = e2;
               R[p6+3] = e4-1;
               R[p6+4] = 1;
               p6 += 5;
               e2 = 0xFFFFFFFF;
              }
             p4 = 0xFFFFFFFF;
             if(p2 < p3)
              {p4 = R[p2+2];
               if(p4 < R[p2+3])p4 = R[p2+3];
              }
            }
          }
        }
       else
        {if(e2 == 0xFFFFFFFF)e2 = e4;
        }
      }
     e2 = p1;
     p1 = p5;
     p5 = e2;
    }
   p1 = *(a+3) - 0x00200104; // diapazon otogdestvlenija
   t1 = LN[2500];
   if(p1 != 0 && t1 != 2501)
    {for(j = 2501; j < t1; j += LN[j])
      {if(LN[j+2] != 0)
        {p2 = LN[j+1];
         p3 = p2 - 6; // dlina linii
         p2 += j;
         p4 = LN[j+5];
         p5 = 1;  // nakopitel visoti linii
         for(i = j+6; i < p2; i++)
          {p6 = LN[i];
           p5 += (p6 < p4 ? (p4 - p6) : (p6 - p4));
           p4 = p6;
          }
         if(p3 <= p1 && p5 <= p1)Otogdlin(j,p1);
        }
      }
    }
   t1 = LN[0];  // cicle sostavlenija linii iz kuskov
   for(j = 1; j < t1; j += LN[j])
    {if(LN[j+3] != 0 && LN[j+4] != 0 && LN[j+5] == 0)
      {p1 = LN[j+3]; p2 = LN[j+4];
       if(LN[p1+2] != LN[p1+3] && LN[p2+2] != LN[p2+3])
        {if(j == LN[p1+2] && j == LN[p2+2])
          {p3 = p2;          // razvorachivaem liniju
           while(2500 < p3)
            {p4 = LN[p3+2];
             LN[p3+2] = LN[p3+3];
             LN[p3+3] = p4;
             LN[p3+4] ^= 0x80000000;
             p3 = LN[p3+2];
            }
          }
         if(j == LN[p1+3] && j == LN[p2+3])
          {p3 = p1;         // razvorachivaem liniju
           while(2500 < p3)
            {p4 = LN[p3+2];
             LN[p3+2] = LN[p3+3];
             LN[p3+3] = p4;
             LN[p3+4] ^= 0x80000000;
             p3 = LN[p3+3];
            }
          }
         if(j == LN[p1+2] && j == LN[p2+3])
          {p3 = LN[p1+3];
           while(2500 < p3)p3 = LN[p3+3];
           if(p3 != j)
            {LN[p1+2] = p2;
             LN[p2+3] = p1;
             LN[j+3] = 0;
            }
          }
         if(j == LN[p1+3] && j == LN[p2+2])
          {p3 = LN[p2+3];
           while(2500 < p3)p3 = LN[p3+3];
            if(p3 != j)
             {LN[p1+3] = p2;
              LN[p2+2] = p1;
              LN[j+3] = 0;
             }
          }
        }
      }
    }
   TT[0] = t1;
   for(j = 1; j < t1; j++)
    {TT[j] = 0;}
                    // v bufere TT sozdajutsja
                    // blanki massivov tochek
   j = 1;
   while(j < t1)
    {p1 = LN[j]; TT[j] = p1; TT[j+1] = LN[j+1];
     TT[j+2] = LN[j+2];
     j += p1;
    }
   i = 1;
   t2 = LN[2500];
   j = 2501;
   while(j < t2)
    {if(LN[j+2] != 0 && LN[j+2] < 2500)
      {p2 = LN[j+2];
       LL[i+1] = p2;
       p3 = p2+3;                 // cicle razvertki
       while(TT[p3] != 0)p3++;    // linij v LL
       TT[p3] = i;
       t3 = LN[j + 3];
       while(t3 > 2500)t3 = LN[t3+3];
       LL[i+2] = t3;
       if(t3 != p2)
        {p3 = t3+3;
         while(TT[p3] != 0)p3++;
         TT[p3] = i;
        }
       p1 = Razvertlin(j,i+3);
       LL[i] = p1 - i;
       i = p1;
      }
     j += LN[j];
    }
   LL[0] = i;

          // cicle formirovanija spiska tochek
   j = 1; // smeshenie tochki
   t2 = 0x00200105; // nomer tochki
   h = st;
   while(j < t1)
    {if(TT[j+3] != 0)
      {R[j] = t2; // nomera tochek zanosjatsja v R
       p1 = mem(10);
       *st = p1;
       st++;
       r = st;
       i = j+3;
       p1 = TT[i];
       while(p1 != 0)
        {*st = p1 | 0x00200000; st++; i++; p1 = TT[i];
        }
       p2 = text1(r);
       p1 = *(st-1);
       Z[p1 + 2] = TT[j+1] + 0x00200104;
       Z[p1 + 3] = 0;
       Z[p1 + 4] = TT[j+2] + 0x00200104;
       Z[p1 + 5] = 0;
	   Z[p1 + 6] = p2;
       Z[p1 + 7] = 0;
       t2++;
      }
     j += TT[j];
    }
   p2 = text1(h);
   opr(*(a+4),p2); // spisok tochek
   t1 = LL[0];
   j = 1;
   h = st;
   while(j < t1)
    {p1 = mem(10);
     t2 = LL[j + 1];
     Z[p1 + 2] = R[t2];
     Z[p1 + 3] = 0;
     t2 = LL[j + 2];
     Z[p1 + 4] = R[t2];
     Z[p1 + 5] = 0;
     Z[p1 + 6] = j | 0x00200000;
     Z[p1 + 7] = 0;
     *st = p1; st++;
     j += LL[j];
    }
   p2 = text1(h);
   opr(*(a+5),p2); // spisok linij
   LL[50000] = 50001;
   return;
  }
 void Bitmap(UINT* a) // operator "risunok(bitmap)"

  {UINT b,c,d,d1,d2,d3,f,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,
        f11,i,j,m;
   char g;
   unsigned char *h;
   h = (unsigned char*)RS;
   b = *(a+1);
   rish = convchisl(b); rish *= 2; // shirina v bajtah
   c = *(a+2);
   risl = convchisl(c); risl *= 2; // dlina bitmapa
                                   // v baitah
   d = risl - rish;
   d1 = rish-1;
   d2 = rish+1;
   d3 = 2*rish;
   for(i = 0; i < risl; i += rish) // cicle perenesenija
    {for(j = 0; j < rish; j++) // v RSA rezultata
                                // videlenia granic
      {m = i+j;
       f = (UINT)h[m];
       f2 = (i == 0 ? 0xFF : (UINT)h[m-rish]);
       f4 = (i < d ? (UINT)h[m+rish] : 0xFF);
       f1 = (f >> 1);
       if(j != 0)
        {f5 = (UINT)h[m-1]; f5 <<= 7; f1 |= f5;
        }
       else f1 |= 0x80;
       f3 = (f << 1);
       if(j < rish)
         {f5 = (UINT)h[m+1]; f5 >>= 7; f3 |= f5;
         }
       else f3 |= 1;
       f6 = (f2 >> 1);
       if(j != 0 && i != 0)
        {f5 = (UINT)h[m-d2]; f5 <<=7; f6 |= f5;
        }
       else f6 |= 0x80;
       f7 = (f2 << 1);
       if(j != 0 && i != 0)
        {f5 = (UINT)h[m-d1]; f5 >>=7; f7 |= f5;
        }
       else f7 |= 1;
       f8 = (f4 >> 1);
       if(j != 0 && i < d)
        {f5 = (UINT)h[m+d1]; f5 <<=7; f8 |= f5;
        }
       else f8 |= 0x80;
       f9 = (f4 << 1);
       if(j != 0 && i < d)
        {f5 = (UINT)h[m+d2]; f5 >>=7; f9 |= f5;
        }
       else f9 |= 1;
       f10 = (i < (d-1)? (UINT)h[m+d3] : 0xFF);
       f5 = f1 | f;
       f11 = f4 | f8;
       f5 |= f11;
       f11 = f3 | f9;
       f5 |= f11;
       f11 = (f2 & f10);
       f11 = ~f11;
       f5 |= f11;
       f5 = ~f5;
       f1 |= f2;
       f3 |= f4;
       f1 |= f3;
       f1 = ~f1;
       f6 &= f7;
       f8 &= f9;
       f6 &= f8;
       f6 = ~f6;
       f1 &= f6;
       f |= f1;
       f |= f5;
       RSA[m] = f;
      }
    }
   for(i = 0; i < risl; i++) // obmen RS i RSA
    {g = RS[i]; RS[i] = RSA[i];
     RSA[i] = g;
    }
   return;
  }





 void initsetka(UINT a, UINT b) // a - chetverka simv. chisel,
     // opredeljajushih analiziruemij podprjamougolnik
     // bufera risunkov. b - para simv. chisel,
     // opredeljajushih shag setki po gorizontali i po
     // vertikali. Inicializiruetsja pustaja setka:
     // v 0-ju jachejku massiva SE zanositsja smeshenie
     // pervoj svobodnoj ego jachejki; v 1-4 jachejki
	 // zanositsja chetverka chisel a; v 5-6 jachejki - para chisel b.
	 // V 7-ju jachejku zanositsja chislo kletok v stroke setki.
     // V 8-ju jachejku zanositsja chislo kletok v stolbce setki.
{UINT c1,c2,d1,d2,h1,h2,i,r1,
       r2,r3,r4;

  c1 = Z[a+2]; c1 -= 0x00200104; // c1,c2 - levij verhnij
  c2 = Z[a+4]; c2 -= 0x00200104; // ugol
  d1 = Z[a+6]; d1 -= 0x00200104; // d1,d2 - pravij nignij
  d2 = Z[a+8]; d2 -= 0x00200104; // ugol
  h1 = Z[b+2]; h1 -= 0x00200104; // h1 - goriz.shag
  h2 = Z[b+4]; h2 -= 0x00200104; // h2 - vertik.shag
  SE[1] = c1;
  SE[2] = c2;
  SE[3] = d1;
  SE[4] = d2;
  SE[5] = h1;
  SE[6] = h2;
  r1 = d1 - c1; r2 = r1/h1; r3 = r1%h1;
  if(r3 != 0)r2++; // r2 - chislo kletok v stroke
  SE[7] = r2;
  r3 = d2 - c2; r1 = r3/h2; r4 = r3%h2;
  if(r4 != 0)r1++; // r1 - chislo kletok v stolbce
  SE[8] = r1;
  r3 = r1*r2; r3 <<= 4; r3 += 9;
  SE[0] = r3;
  for(i = 9; i < r3; i += 16)
   {SE[i]=0;}
 }



void lomanaja(UINT* a)// operator "risunok(lomanaja ...)"

{UINT b,c,d,e,f,*h,i,i1,k1,k2,k3,n;
 int m1,m2,m3,m4,m5,m6,m7,m8;
 b = *(a+1);
 b &= 0x001FFFFF;
 c = LL[b]; c -= 3;
 b += 3; // b - nachalo massiva par koordinat
         // c - dlina massiva par koordinat
 f = b + c;
 f -= 2; // poslednjaja jachejka massiva
 d = (c >> 5);
 if(d < 4)d = 4;
 if(10 < d)d = 10;
 d <<= 1; // d - shag prosmotra massiva linii
 e = *(a+2); e += 2;

 m1 = intchisl(Z[e]); m2 = intchisl(Z[e+2]);
 m1 *= m1; m2 *= m2; //m1,m2 - kvadrati chislitelja i znamenatelja
                    // doli otklonenija.
 n = 0;           // v R sozdajetsja massiv par (smeshenie nachala -
                  // smeshenie konca)
                  // dlja prjamolinejnih fragmentov
                  // n - nomer pervoj svobodnoj jachejki v R
 k1 = b; // k1,k2 - nachalo i konec tek. otrezka
 k2 = b;
 while(k2 < f)
  {k2 += d;
   if(f < k2)
    {k2 = f;}
   m3 = (int)LL[k2+1] - (int)LL[k1+1]; //A = d-b
   m4 = (int)LL[k1] - (int)LL[k2]; //B = a-c
   m5 = (m3*m3) + (m4*m4); //C = A^2+B^2
   if(m5 != 0)
    {m6 = m1*m5; // E= m^2C
     m6 /= m2; // max dopustimoe otklonenie
     m7 = (int)LL[k1+1]*(int)LL[k2];
     m7 -= (int)LL[k1]*(int)LL[k2+1]; //D = bc-ad
	 for(i = k1+2; i < k2; i+= 2)
      {m8 = ((int)LL[i]*m3) + ((int)LL[i+1]*m4);
       m8 += m7;
	   m8 *= m8;
	   m8 /= m5;
	   if(m8 > m6)
	    {k3 = k2 - d;
	     if(k1 < k3)
		  {k2 = k3;}
         R[n] = k1, R[n+1] = k2; n += 2;
		 k1 = k2;
		 break;
	    }
      }
    }
   else
    {k3 = k2 - d;
	 if(k1 < k3)
	  {k2 = k3;}
     R[n] = k1; R[n+1] = k2; n += 2;
	 k1 = k2;
	}
  }
 if(k2 == f && (n == 0 || R[n-1] != f))
  {R[n] = k1; R[n+1] = f; n += 2;} // massiv otrezkov sozdan

 h = st; // nachalo formirovanija rezultata
 for(i = 0; i < n; i += 2)
  {b = mem(12);
   *st = b;
   st++;
   k1 = mem(8);
   i1 = R[i];
   Z[k1+2] = LL[i1]+0x00200104; Z[k1+3] = 0;
   Z[k1+4] = LL[i1+1]+0x00200104; Z[k1+5] = 0;
   c = *(st-1);
   Z[c+2] = k1; Z[c+3] = 0;
   i1 = R[i+1];
   k1 = mem(8);
   Z[k1+2] = LL[i1]+0x00200104; Z[k1+3] = 0;
   Z[k1+4] = LL[i1+1]+0x00200104; Z[k1+5] = 0;
   c = *(st-1);
   Z[c+4] = k1; Z[c+5] = 0;
   d = R[i+1] - R[i];
   d += 2; d >>= 1;
   e = loschisl(d);
   c = *(st-1);
   Z[c+6] = e; Z[c+7] = 0;
   k1 = R[i]; k2 = R[i+1];
   k3 = mem(10); // napravl.vektor v nachale
   *st = k3; st++;
   m3 = (int)LL[k2] - (int)LL[k1];
   m4 = (int)LL[k2+1] - (int)LL[k1+1];
   d = losint(m3);
   k3 = *(st-1);
   Z[k3+2] = d; Z[k3+3] = 0;
   e = losint(m4);
   k3 = *(st-1);
   Z[k3+4] = e; Z[k3+5] = 0;
   m5 = (m3*m3)+(m4*m4);
   d = losint(m5);
   k3 = *(st-1);
   Z[k3+6] = d; Z[k3+7] = 0;
   st--;
   c = *(st-1);
   Z[c+8] = k3; Z[c+9] = 0;
  }
 d = text1(h);
 opr(*(a+3),d);
 return;
}


void risotrezki(UINT* a)// operator "risunok(otrezki ...)"

{UINT b,c,d,e,f,*h,i,i1,k1,k2,k3,n;
 int m1,m2,m3,m4,m5,m6,m7,m8;
 b = *(a+1);
 b &= 0x001FFFFF;
 c = LL[b]; c -= 3;
 b += 3; // b - nachalo massiva par koordinat
         // c - dlina massiva par koordinat
 f = b + c;
 f -= 2; // poslednjaja jachejka massiva
 d = (c >> 5);
 if(d < 4)d = 4;
 if(10 < d)d = 10;
 d <<= 1; // d - shag prosmotra massiva linii
 e = *(a+2); e += 2;

 m1 = intchisl(Z[e]); m2 = intchisl(Z[e+2]);
 m1 *= m1; m2 *= m2; //m1,m2 - kvadrati chislitelja i znamenatelja
                    // doli otklonenija.
 n = 0;           // v R sozdajetsja massiv par (smeshenie nachala -
                  // smeshenie konca)
                  // dlja prjamolinejnih fragmentov
                  // n - nomer pervoj svobodnoj jachejki v R
 k1 = b; // k1,k2 - nachalo i konec tek. otrezka
 k2 = b;
 while(k2 < f)
  {k2 += d;
   if(f < k2)
    {k2 = f;}
   m3 = (int)LL[k2+1] - (int)LL[k1+1]; //A = d-b
   m4 = (int)LL[k1] - (int)LL[k2]; //B = a-c
   m5 = (m3*m3) + (m4*m4); //C = A^2+B^2
   if(m5 != 0)
    {m6 = m1*m5; // E= m^2C
     m6 /= m2; // max dopustimoe otklonenie
     m7 = (int)LL[k1+1]*(int)LL[k2];
     m7 -= (int)LL[k1]*(int)LL[k2+1]; //D = bc-ad
	 for(i = k1+2; i < k2; i+= 2)
      {m8 = ((int)LL[i]*m3) + ((int)LL[i+1]*m4);
       m8 += m7;
	   m8 *= m8;
	   m8 /= m5;
	   if(m8 > m6)
	    {k3 = k2 - d;
	     if(k1 < k3)
		  {k2 = k3;}
         R[n] = k1, R[n+1] = k2; n += 2;
		 k1 = k2;
		 break;
	    }
      }
    }
   else
    {k3 = k2 - d;
	 if(k1 < k3)
	  {k2 = k3;}
     R[n] = k1; R[n+1] = k2; n += 2;
	 k1 = k2;
	}
  }
 if(k2 == f && (n == 0 || R[n-1] != f))
  {R[n] = k1; R[n+1] = f; n += 2;} // massiv otrezkov sozdan

 h = st; // nachalo formirovanija rezultata
 for(i = 0; i < n; i += 2)
  {b = mem(12);
   *st = b;
   st++;
   k1 = mem(8);
   i1 = R[i];
   Z[k1+2] = LL[i1]+0x00200104; Z[k1+3] = 0;
   Z[k1+4] = LL[i1+1]+0x00200104; Z[k1+5] = 0;
   c = *(st-1);
   Z[c+2] = k1; Z[c+3] = 0;
   i1 = R[i+1];
   k1 = mem(8);
   Z[k1+2] = LL[i1]+0x00200104; Z[k1+3] = 0;
   Z[k1+4] = LL[i1+1]+0x00200104; Z[k1+5] = 0;
   c = *(st-1);
   Z[c+4] = k1; Z[c+5] = 0;
   k1 = R[i]; k2 = R[i+1];
   m3 = (int)LL[k2] - (int)LL[k1];
   m4 = (int)LL[k2+1] - (int)LL[k1+1];
   m5 = (m3*m3)+(m4*m4);
   m6 = sqrt(m5);
   e = losint(m6);
   c = *(st-1);
   Z[c+6] = e; Z[c+7] = 0;
   k3 = mem(10); // napravl.vektor v nachale
   *st = k3; st++;
   d = losint(m3);
   k3 = *(st-1);
   Z[k3+2] = d; Z[k3+3] = 0;
   e = losint(m4);
   k3 = *(st-1);
   Z[k3+4] = e; Z[k3+5] = 0;
   d = losint(m5);
   k3 = *(st-1);
   Z[k3+6] = d; Z[k3+7] = 0;
   st--;
   c = *(st-1);
   Z[c+8] = k3; Z[c+9] = 0;
  }
 d = text1(h);
 opr(*(a+3),d);
 return;
}
 void tchk(UINT a, UINT b, UINT c, UINT d, UINT e)
    // registracija v bufere risunkov tochki s koordinatami
    // d,e; a,b - stolbec i stroka levogo verhnego
    // ugla ramki; c - pravij stolbec ramki. Shirina ramki
    // kratna 16.
  {UINT f,h,p;
   unsigned char g;
   f = c - a; f++;
   f /= 8;
   h = e - b;
   f *= h;
   p = d - a;
   h = p / 8;
   f += h;
   g = 0x80;
   h = p%8;
   if(h != 0){g >>= h;}
   g = ~g;
   RS[f] &= g;
  }


void linsetka(UINT a, UINT b) // operator "risunok(Linija)"

{UINT d,e,f,g,h;
 int f1,f2,g1,g2,h1,h2,h3,h4,i1,i2,j1,j2,j3,j4,k1,k2,k3,k4;
 d = Z[a+4]; // smeshenie nabora par (lev.kraj otrezka - napr.prohogdenija)
 d += 2;
 h1 = (int)SE[1]; // abscissa levoj storoni ramki
 h2 = (int)SE[2]; // ordinata verhnej storoni ramki
 h3 = (int)SE[5]; // goriz. shag setki
 h4 = (int)SE[6]; // vertik. shag setki
 while(!(Z[d] & 0x80000000))
  {e = Z[d];
   h = Z[e+2]; g = Z[e+4]; e = Z[h]; // e - smeshenie pari koncov otrezka
   h -= 2; // h - ssilka na otrezok
   f = Z[e+2]; f = Z[f];  // g - napravlenie prohogdenija otrezka
   f1 = (int)(Z[f+2] - 0x00200104);
   f1 -= h1;
   f2 = (int)(Z[f+4] - 0x00200104);
   f2 -= h2; // f1,f2 - koordinati nachala otrezka otnositelno ramki
   f = Z[e+4]; f = Z[f];
   g1 = (int)(Z[f+2] - 0x00200104);
   g1 -= h1;
   g2 = (int)(Z[f+4] - 0x00200104);
   g2 -= h2; // g1,g2 - koordinati konca otrezka
   if(g == 0x00200104)
    {i1 = f1; i2 = f2;}
   else
    {i1 = g1; i2 = g2;}
   regkletka(i1,i2,h,b);
   if(f1 <= g1)
    {j1 = f1; j2 = f2; j3 = g1; j4 = g2;} // j1,j2 - koord. levogo konca
   else                                   // j3,j4 - koord. pravogo konca
    {j1 = g1; j2 = g2; j3 = f1; j4 = f2;}
   k1 = j1/h3; k1 *= h3; k1 += h3;
   k2 = j4 - j2; k3 = j3 - j1;
   while(k1 <= j3) // k1 - abscissa tochki peresechenija otrezka s vertik.
	              // liniej setki
    {k4 = (k1 - j1)*k2;
     k4 /=k3; k4 += j2; // k4 - ordinata tochki peresechenija
	 regkletka(k1,k4,h,b);
     k1 += h3;
    }
   if(f2 <= g2)
    {j1 = f1; j2 = f2; j3 = g1; j4 = g2;} // j1,j2 - koord. verhnego konca
   else                                   // j3,j4 - koord. nignego konca
    {j1 = g1; j2 = g2; j3 = f1; j4 = f2;}
   k1 = j2/h4; k1 *= h4; k1 += h4;
   k2 = j3 - j1; k3 = j4 - j2;
   while(k1 <= j4) // k1 - ordinata tochki peresechenija otrezka s goriz.
	              // liniej setki
    {k4 = (k1 - j2)*k2;
     k4 /=k3; k4 += j1; // k4 - abscissa tochki peresechenija
	 regkletka(k4,k1,h,b);
	 k1 += h4;
    }
   d += 2;
  }
 return;
}

void regkletka(int a, int b, UINT c, UINT d) // (a,b) - koordinati tochki,
                                  // c - smeshenie otrezka stand. elementa;
								  // d - ukazatel registracii/udalenija.
								  // Vipolnjaetsja registracija (libo udalenie)
								  // otrezka c v kletke tochki (a,b).
{UINT e,f;
 int e1,e2,e3,e4,h1,h2;
 h1 = (int)SE[5]; // goriz. shag setki
 h2 = (int)SE[6]; // vertik. shag setki
 e1 = a/h1;
 e2 = b/h2;
 e = (UINT)e1;
 f = (UINT)e2;
 izmkletka(e,f,c,d);
 e3 = a%h1;
 e4 = b%h2;
 if(e3 == 0 && e1 != 0)
  {izmkletka(e-1,f,c,d);
   if(e4 == 0 && (e2 != 0))
    {izmkletka(e,f-1,c,d);
     izmkletka(e-1,f-1,c,d);
    }
  }
 if(e4 == 0 && e3 != 0 && e2 != 0)
  {izmkletka(e,f-1,c,d);
  }
 return;
 }


void izmkletka(UINT a, UINT b, UINT c, UINT d) // (a,b) - kooridinati kletki:
                            // nomer po gorizontali i po vertikali, nachinaja s 0;
      					    // c - smeshenia otrezka stand. elementa;
						    // d - ukazatel registracii/udalenija.
						    // Vipolnjaetsja registracija (libo udalenie)
						    // otrezka c v kletke (a,b).


{UINT e,f,g,i,j,k;
 e = SE[7];
 i = a + (b * e); i <<= 4; i += 9; // i - smeshenie nachala bloka v massive SE
 f = 0; // indikator okonchanija
 j = i+16;
 while(f == 0)
  {g = SE[i];
   if(g == c)
    {if(d == 0x00200105)
      {f = 1;}
	 else
	  {k = i+1;
       while(k < j && SE[k-1] != 0)
	    {SE[k-1] = SE[k]; k++;
	     if(k == j)
		  {SE[k-1] = 0;}
	    }
	   f = 1;
      }
    }
   else
    {if(g != 0)
      {i++;
       if(j == i)
	    {f = 1;}
      }
	 else
	  {if(d == 0x00200105)
        {SE[i] = c; i++;
         if(i < j)
	      {SE[i] = 0;}
        }
       f = 1;
      }
    }
  }
 return;
}


UINT naprkletki(int a, int b, int c, int d, UINT e) // (a,b) - koordinati tochki A;
               // (c,d) - koordinati vektora r. Nahodjatsja pervie e kletok setki,
               // cherez kotorie prohodit luch, vihodjashij iz A v napravlenii r.
               // vozvrashaet nabor par koordinat etih kletok.
{UINT *g,g1,*i;
 int f1,f2,f3,f4,f5,f6,f7,f8,h1,h2,h3,h4;
 f1 = (int)SE[1]; // koordinati levogo verhnego ugla ramki
 f2 = (int)SE[2];
 f3 = (int)SE[5]; // shag setki po gorizontali
 f4 = (int)SE[6]; // shag setki po vertikali
 f7 = (int)SE[7];
 f8 = (int)SE[8];
 a -= f1;
 b -= f2;
 f5 = a/f3; f6 = b/f4; // koordinati ishodnoj kletki
 g = st;
 g1 = (UINT)f5;
 g1 += 0x00200104;
 *st = g1; st++;
 g1 = (UINT)f6;
 g1 += 0x00200104;
 *st = g1; st++;
 g1 = text1(g); e--;
 *st = g1; st++; // zaregistrirovali ishodnuju kletku
 if(abs(d) < abs(c))
  {h1 = (0 < c ? f3 : -f3);
   h2 = (0 < c ? 1 : -1);
   h3 = f5 * f3; h3 -= a; // tekushaja abscissa levoi storoni kletki
   while(e != 0)
    {f5 += h2;
     h3 += h1;
	 if(f5 < 0)
	  {e = 0;}
	 else
	  {if(f5 >= f7)
	    {e = 0;}
       else
	    {h4 = h3*d;
         h4 /= c;
		 h4 += b;
         h4 /= f4;
         i = st;
         g1 = (UINT)f5;
		 g1 += 0x00200104;
		 *st = g1; st++;
		 g1 = (UINT)h4;
		 g1 += 0x00200104;
		 *st = g1; st++;
		 g1 = text1(i);
		 *st = g1; st++;
		 e--;
        }
	  }
    }
  }
 else
  {h1 = (0 < d ? f4 : -f4);
   h2 = (0 < d ? 1 : -1);
   h3 = f6 * f4; h3 -= b; // tekushaja ordinata verhnej storoni kletki
   while(e != 0)
    {f6 += h2;
     h3 += h1;
	 if(f6 < 0)
	  {e = 0;}
	 else
	  {if(f6 >= f8)
	    {e = 0;}
       else
	    {h4 = h3*c;
         h4 /= d;
		 h4 += a;
         h4 /= f3;
         i = st;
         g1 = (UINT)h4;
		 g1 += 0x00200104;
		 *st = g1; st++;
		 g1 = (UINT)f6;
		 g1 += 0x00200104;
		 *st = g1; st++;
		 g1 = text1(i);
		 *st = g1; st++;
		 e--;
        }
	  }
    }
  }
 g1 = text1(g);
 return g1;
}

void extrnol(UINT*a) // operator izobragenie(0...)
{UINT b,c,e,i,j,p1,p2,p3,p4;
 unsigned char f;
 b = *(a+1) - 0x00200104; // shirina bitmapa
 c = *(a+2) - 0x00200104; // visota bitmapa
 b *= 4;
 e = b * c;
 j = 0;
 for(i = 0; i < e; i += 4, j++)
  {f = IZ[i];
   p1 = (UINT)f;
   f = IZ[i+1];
   p2 = (UINT)f;
   p2 <<= 8;
   f = IZ[i+2];
   p3 = (UINT)f;
   p3 <<= 16;
   p4 = ((p1 | p2) | p3);
   OBL1[j] = p4; OBL2[j] = 0;
  }
 return;
}

void reotrezki(void) // pereformiruet graf otrezkov posle korrekcii ih cvetov
 {UINT i,j,c,d,d1,d2,p;
  p = oblshirina - 1;
  for(i = 0; i < oblvisota; i++)
  {c = CVSTR[i]; // tekushaja pozicija v stroke
   d = 0; // indikator obriva
   d2 = c; // tochka sdviga vlevo
   while(d == 0)
    {if(CVOTR[c+1] != p && CVOTR[c+2] == CVOTR[c+11])
      {d1 = c+9;
       while(CVOTR[d1+1] != p && CVOTR[d1+11] == CVOTR[c+2])
        {d1 += 9; // d1 - poslednij prisoedinjaemij otrezok
        }
       CVOTR[c+1] = CVOTR[d1+1];
       if(d2 != c)
        {CVOTR[d2] = CVOTR[c];
         CVOTR[d2+1] = CVOTR[c+1];
         CVOTR[d2+2] = CVOTR[c+2];
        }
       for(j=3; j < 9; j++)
          {CVOTR[d2+j] = 0;}
       d2 += 9;
       if(CVOTR[d1+1] == p)
        {d = 1;}
       else
        {c = d1+9;
        }
      }
     else
      {if(d2 != c)
        {CVOTR[d2] = CVOTR[c];
         CVOTR[d2+1] = CVOTR[c+1];
         CVOTR[d2+2] = CVOTR[c+2];
        }
       for(j=3; j < 9; j++)
          {CVOTR[d2+j] = 0;}
       if(CVOTR[c+1] == p)
        {d = 1;}
       else
       {d2 += 9;
        c += 9;
       }
     }
    }

  }
 return;
 }

void cvsvjazi(void)// zavershaet sozdanie grafa otrezkov
 {UINT b,b1,b2,c,c1,c2,d,i,p1,p2;
  CVOTREND = CVEND;
  for(i = 0; i < (oblvisota-1); i++)
   {b = CVSTR[i]; // tekushaja pozicija v verhnej stroke
    c = CVSTR[i+1]; //tekushaja pozicija v nignej stroke
    b1 = b; // ishodnie pozicii otrezkov
    c1 = c;
    p2 = oblshirina - 1;
    d = 0; // indikator okonchanija
    while(d == 0)
     {if(CVOTR[b+2] == CVOTR[c+2])
       {CVOTR[CVOTREND] = c;
        CVOTR[CVOTREND+1] = 0;
        p1 = b+3;
        while(CVOTR[p1+1]!= 0)
         {p1 = CVOTR[p1+1];}
        CVOTR[p1+1] = CVOTREND;
        CVOTREND += 2;
        CVOTR[CVOTREND] = b;
        CVOTR[CVOTREND+1] = 0;

        p1 = c+2;
        while(CVOTR[p1+1]!= 0)
         {p1 = CVOTR[p1+1];}
        CVOTR[p1+1] = CVOTREND;
        CVOTREND += 2;
       }
      if(CVOTR[c+1] < CVOTR[b+1])
       {CVOTR[c+5] = b1;
        b1 = b; c += 9;
       }
      else
       {if(CVOTR[b+1] < CVOTR[c+1])
         {CVOTR[b+6] = c1;
          c1 = c; b += 9;
         }
        else
        {CVOTR[c+5] = b1;
         CVOTR[b+6] = c1;
         if(CVOTR[b+1] == p2)
          {d = 1;}
         else
          {b += 9; c += 9;
           b1 = b; c1 = c;
          }
        }
       }
     }

   }
 for(i = 0; i < oblvisota; i++)
  {b = CVSTR[i]; // tekushaja pozicija v stroke
   d = 0; // indikator konca stroki
   while(d == 0)
    {c = CVOTR[b+3];
     if(c == 0)
      {p1 = (CVOTR[b+1] - CVOTR[b]);
       p1 ++;
       CVOTR[CVOTREND] = p1;
       CVOTR[CVOTREND+1] = 0;
       CVOTR[b+7] = CVOTREND;
       CVOTREND += 2;
      }
     else
      {b1 = CVOTR[c];
       c1 = CVOTR[b1+7];
       while(CVOTR[c1+1] != 0)
        {c1 = CVOTR[c1+1];}
       CVOTR[b+7] = c1;
       p1 = (CVOTR[b+1] - CVOTR[b]);
       p1++;
       CVOTR[c1] = CVOTR[c1] + p1;
       while(CVOTR[c+1] != 0)
        {c = CVOTR[c+1];
         b2 = CVOTR[c];
         c2 = CVOTR[b2+7];
         while(CVOTR[c2+1] != 0)
          {c2 = CVOTR[c2+1];}
         if(c2 != c1)
          {CVOTR[c1] = CVOTR[c1] + CVOTR[c2];
           CVOTR[c2+1] = c1;
          }
        }
      }
     if(CVOTR[b+1] == p2)
      {d = 1;}
     else
      {b += 9;}
    }
   }
  for(i = 0; i < oblvisota; i++)
  {b = CVSTR[i]; // tekushaja pozicija v stroke
   d = 0; // indikator konca stroki
   while(d == 0)
    {c = CVOTR[b+7];
     while(CVOTR[c+1] != 0)
      {c = CVOTR[c+1];}
     CVOTR[b+7] = c;
     if(CVOTR[b+1] == p2)
      {d = 1;}
     else
      {b += 9;}
    }
  }
  return;
 }

 void cvizolir(UINT a, UINT b) // operator "izobragenie(izolir...)"
 {UINT b1,i,j,c,c1,c2,d,d1,d2,d3,d4,e,p,q,r,s1,s2,s3;
  for(i = 0; i < oblvisota; i++)
   {c = CVSTR[i]; // tekushaja pozicija v stroke
    d = 0; // indikator konca stroki
    p = oblshirina - 1;
    while(d == 0)
     {if(CVOTR[c+1] == p || CVOTR[c+10] == p)
       {d = 1;}
      else
       {if(CVOTR[c+8]== 0)
         {c1 = c+9; c2 = c+18;
          e = CVOTR[c+2]; // cvet fona
          q = CVOTR[c1+1] - CVOTR[c1];
          if(CVOTR[c2+1] != p && CVOTR[c2+11] == e)
           {q = CVOTR[c2+1] - CVOTR[c1]; c2 += 9;}
          if(CVOTR[c2+2]== e && CVOTR[c1+8] == 0 &&
           q < (c2 == c+18 ? 3 : 4)) // nachalo proslegivanija vverh i vniz
            {R[0] = c1; R[1] = c2 - 9;
             r = 2; // smeshenie v R pervoj jachejki posle nabora par smeshenij
                    // levogo i pravogo otrezkov pjatna
             s1 = 0; // indikator neizolirovannosti: 1 - ne izolir.
             for(j = 0; j < 2; j++) // j=0 - idem vverh, j=1 - vniz
              {d1 = R[0]; d2 = R[1];
               s2 = 0; // indikator zavershenija pjatna
               s3 = 0; // indikator obriva
               b1 = 0; // chislo projdennih strok
               while(s3 == 0 && b1 < b)
                {b1 ++;
                 d3 = (j == 0? CVOTR[d1+5] : CVOTR[d1+6]);
                 if(d3 == 0)
                  {s3 = 1;}
                 else
                  {if(CVOTR[d3+2] == e && CVOTR[d3+1] >= CVOTR[d2+1])
                    {s2 = 1; s3 = 1;}
                   else
                    {d4 = d3;
                     while(CVOTR[d4+1] < CVOTR[d2+1])
                      {d4 += 9;}
                     if(CVOTR[d3+2] == e)
                      {d1 = d3+9;}
                     else
                      {if(CVOTR[d3] != 0)
                         {if(CVOTR[d3-7] == e)
                           {d1 = d3;}
                          else
                           {if(CVOTR[d3 -9] !=0 && CVOTR[d3 - 16] == e)
                             {d1 = d3-9;}
                            else
                             {d1 = 0;}

                           }

                         }
                        else
                         {d1 = 0;}
                      }
                     if(CVOTR[d4+2] == e)
                      {d2 = d4-9;}
                     else
                      {if(CVOTR[d4+1] != p)
                         {if(CVOTR[d4+11] == e)
                           {d2 = d4;}
                          else
                           {if(CVOTR[d4 + 10] !=p && CVOTR[d4 + 20] == e)
                             {d2 = d4+9;}
                            else
                             {d2 = 0;}

                           }

                         }
                        else
                         {d2 = 0;}
                      }
                     if(d1 == 0 || d2 == 0)
                      {s3 = 1;}
                     else
                      {if(CVOTR[d2+1] - CVOTR[d1] >= a)
                        {s3 = 1;}
                       else
                        {R[r] = d1; R[r+1] = d2;
                         r += 2;
                        }
                      }

                    }
                  }
                }
               if(s2 == 0)
                {s1 = 1; break;}

              }
             if(s1 == 0) // najdeno izolirovannoe pjatno
              {for(j = 0; j < r; j +=2)
                {d1 = R[j]; d2 = R[j+1];
                 while(d1 <= d2)
                  {CVOTR[d1+8] = 1; d1 += 9;}
                }
              }
            }
         }
        c += 9;
       }
     }
   }
     // nachalo cicla pereformirovanija otrezkov
 for(i = 0; i < oblvisota; i++)
  {c = CVSTR[i]; // tekushaja pozicija v stroke
   d = 0; // indikator obriva
   d2 = c; // tochka sdviga vlevo
   while(d == 0)
    {if(CVOTR[c+1] != p && CVOTR[c+17] == 1)
      {d1 = c+18;
       while(CVOTR[d1+1] != p && (CVOTR[d1+17] == 1 || CVOTR[d1+11] == CVOTR[c+2]))
        {d1 += 9; // d1 - poslednij prisoedinjaemij otrezok
        }
       CVOTR[c+1] = CVOTR[d1+1];
       if(d2 != c)
        {CVOTR[d2] = CVOTR[c];
         CVOTR[d2+1] = CVOTR[c+1];
         CVOTR[d2+2] = CVOTR[c+2];
        }
       for(j=3; j < 9; j++)
          {CVOTR[d2+j] = 0;}
       d2 += 9;
       if(CVOTR[d1+1] == p)
        {d = 1;}
       else
        {c = d1+9;
        }
      }
     else
      {if(d2 != c)
        {CVOTR[d2] = CVOTR[c];
         CVOTR[d2+1] = CVOTR[c+1];
         CVOTR[d2+2] = CVOTR[c+2];
        }
       for(j=3; j < 9; j++)
          {CVOTR[d2+j] = 0;}
       if(CVOTR[c+1] == p)
        {d = 1;}
       else
       {d2 += 9;
        c += 9;
       }
     }
    }

  }
  cvsvjazi();
  return;
 }


 void cvgruppi(UINT a) // operator "izobragenie(gruppi...)"
 {UINT i,i1,i2,c,c1,d,d1,m,n,n1,n2,n3,p,p1,p2,q,q1,q2,
   q3,q4,q5,q6,q7,q8,r1,r2,r3;
  for(i = 0; i < oblvisota; i++)
   {c = CVSTR[i]; // tekushaja pozicija v stroke
    d = 0; // indikator konca stroki
    p = oblshirina - 1;
    while(d == 0)
     {p1 = CVOTR[c+7];
      p2 = CVOTR[c+2];
      if(CVOTR[p1] < a && !(p2 & 0x80000000))
       {q = 0; // zagotovka shesterki dlja tekushego otrezka
        if(CVOTR[c] != 0)
         {c1 = c - 9;
          q1 = CVOTR[c1+8];
          if(q1 != 0)
           {while(CVOTR[q1+5] != 0)
             {q1 = CVOTR[q1+5];}
            q2 = CVOTR[q1+4];
            if(CVGR[p2-1] == q2)
             {m = CVOTR[c+1] - CVOTR[c];
              m++;
              n = ZCV[p2-1];
              n1 = (n >> 16); // B
              n2 = (n >> 8) & 0xFF; //G
              n3 = n & 0xFF; //R
              CVOTR[q1] = CVOTR[q1] + (m * n1);
              CVOTR[q1+1] = CVOTR[q1+1] + (m * n2);
              CVOTR[q1+2] = CVOTR[q1+2] + (m * n3);
              CVOTR[q1+3] = CVOTR[q1+3] + m;
              q = q1;
             }
           }
         }
        q1 = CVOTR[c+1];
        q2 = CVOTR[c+5]; // pervij otrezok v verhnem rjadu,
                         // peresekajushijsja s tekushim

        if(q2 != 0)
         {d1 = 0; // indikator okonchanija
          while(d1 == 0)
          {q3 = CVOTR[q2+7];
           q4 = CVOTR[q2+2];
           if(CVOTR[q3] < a && !(q4 & 0x80000000))
            {q5 = CVOTR[q2+8];
             while(CVOTR[q5+5] != 0)
              {q5 = CVOTR[q5+5];} // q5 - shesterka otrezka q2
             if(q == 0)
              {q6 = CVOTR[q5+4]; // tekushij otrezok poka ne imeet shesterki
               if(CVGR[p2-1] == q6)
                {m = CVOTR[c+1] - CVOTR[c];
                 m++;
                 n = ZCV[p2-1];
                 n1 = (n >> 16); // B
                 n2 = (n >> 8) & 0xFF; //G
                 n3 = n & 0xFF; //R
                 CVOTR[q5] = CVOTR[q5] + (m * n1);
                 CVOTR[q5+1] = CVOTR[q5+1] + (m * n2);
                 CVOTR[q5+2] = CVOTR[q5+2] + (m * n3);
                 CVOTR[q5+3] = CVOTR[q5+3] + m;
                 q = q5;
                }
              }
             else  // tekushij otrezok uge imeet shesterku q
              {if(q != q5)
                {q6 = CVOTR[q+4];
                 q7 = CVOTR[q5+4];
                 if(q6 == q7)
                  {CVOTR[q] = CVOTR[q] + CVOTR[q5];
                   CVOTR[q+1] = CVOTR[q+1] + CVOTR[q5+1];
                   CVOTR[q+2] = CVOTR[q+2] + CVOTR[q5+2];
                   CVOTR[q+3] = CVOTR[q+3] + CVOTR[q5+3];
                   CVOTR[q5+5] = q;
                  }

                }
              }
            }
           if(CVOTR[q2+1] < q1)
            {q2 += 9;}
           else
            {d1 = 1;}
          }

         }
        if(q == 0)
         {m = CVOTR[c+1] - CVOTR[c];
          m++;
          n = ZCV[p2-1];
          n1 = (n >> 16); // B
          n2 = (n >> 8) & 0xFF; //G
          n3 = n & 0xFF; //R
          CVOTR[CVOTREND] = (m * n1);
          CVOTR[CVOTREND+1] = (m * n2);
          CVOTR[CVOTREND+2] = (m * n3);
          CVOTR[CVOTREND+3] = m;
          CVOTR[CVOTREND+4] = CVGR[p2-1];
          CVOTR[CVOTREND+5] = 0;
          q = CVOTREND;
          CVOTREND += 6;
         }
        CVOTR[c+8] = q;
       }
      if(CVOTR[c+1] == p)
       {d = 1;}
      else
       {c += 9;
       }
     }
   }
  for(i = 0; i < oblvisota; i++) // korekcija cvetnostej
   {c = CVSTR[i]; // tekushaja pozicija v stroke
    d = 0; // indikator konca stroki
    p = oblshirina - 1;
    while(d == 0)
     {q1 = CVOTR[c+8];
      if(q1 != 0)
       {while(CVOTR[q1+5] != 0)
         {q1 = CVOTR[q1+5];} // q1 - shesterka otrezka c
        if(CVOTR[q1+3] == 0)
         {CVOTR[c+2] = CVOTR[q1];}
        else
         {q2 = CVOTR[q1+3];
          q3 = CVOTR[q1]/q2;
          q4 = CVOTR[q1+1]/q2;
          q5 = CVOTR[q1+2]/q2;
          q6 = diskr(q5,q4,q3);
          if(q6 == 0)
           {q6 = (q3 << 16);
            q6 |= (q4 << 8);
            q6 |= q5;
            q6 |= 0x80000000;
           }
          CVOTR[c+2] = q6;
          CVOTR[q1+3] = 0;
          CVOTR[q1] = q6;
         }
       }
      if(CVOTR[c+1] == p)
       {d = 1;}
      else
       {c += 9;}
     }
   }
 reotrezki();
 cvsvjazi();
 return;
 }


 void cvniz(UINT a) // a - smeshenie linii v CVOTR. Prodolgaet ee na 1
                    // piksel vniz
 {UINT b;
  b = CVOTR[a+3];
  CVOTR[CVOTREND] = CVOTR[b];
  CVOTR[CVOTREND+1] = CVOTR[b+1]+1;
  CVOTR[CVOTREND+2] = b;
  CVOTR[CVOTREND+3] = 0;
  CVOTR[a+3]= CVOTREND;
  CVOTR[b+3]= CVOTREND;
  CVOTREND += 4;
  return;
 }

 void cvgoriz(UINT a, UINT b, UINT c, UINT d, UINT e) // a - smeshenie linii,
                       //b - abscissa levogo konca prisoedinjaemogo
                       // gorizontalnogo otrezka, c - abscissa pravogo konca,
                       // d - ordinata. Esli e = 0, otrezok prohoditsja
                       // sleva napravo, inache - sprava nalevo.
 {UINT p,q;
  p = CVOTREND;
  CVOTR[CVOTREND] = (e == 0 ? b : c);
  CVOTR[CVOTREND+1] = d;
  CVOTREND += 4;
  while(b != c)
   {if(e == 0){b++;}
    else{c--;}
    CVOTR[CVOTREND] = (e == 0 ? b : c);
    CVOTR[CVOTREND+1] = d;
    CVOTR[CVOTREND+2] = CVOTREND - 4;
    CVOTR[CVOTREND-1] = CVOTREND;
    CVOTREND += 4;
   }
  if(CVOTR[a+2] == 0)
   {CVOTR[a+2] = p;
    CVOTR[a+3] = CVOTREND - 4;
    CVOTR[p+2] = 0;
   }
  else
   {q = CVOTR[a+3];
    CVOTR[q+3] = p+4;
    CVOTR[p+6] = q;
    CVOTR[a+3] = CVOTREND - 4;
   }
  CVOTR[CVOTREND-1] = 0;

 return;
 }

void cvbuf(UINT a) // a - smeshenie v CVOTR pervogo otrezka stroki (posle uplotnenija
                   // massiva otrezkov). Dlja etoj stroki sozdajutsja pustie buferi.
{UINT d,p,u1,u2;
 p = oblshirina - 1;
 u1 = 5900000;
 u2 = 5930000;
 CVOTR[tekbuf] = 0;
 CVOTR[tekbuf+1] = 0;
 CVOTR[tekbuf+2] = 0;
 CVOTR[a+4] = tekbuf;
 tekbuf += 3;
 if(tekbuf == u2)
  {tekbuf = u1;}
 d = 0;
 while(d == 0)
  {CVOTR[tekbuf] = 0;
   CVOTR[tekbuf+1] = 0;
   CVOTR[tekbuf+2] = 0;
   CVOTR[a+5] = tekbuf;
   if(CVOTR[a+1]!= p)
    {CVOTR[a+10] = tekbuf;}
   tekbuf += 3;
   if(tekbuf == u2)
    {tekbuf = u1;}
   if(CVOTR[a+1]== p)
    {d = 1;}
   else
    {a += 6;}
  }
 return;
}

UINT uvniz(UINT a,UINT b,UINT i) // a- smeshenie otrezka. i - ordinata otrezka.
                          //Esli b = 0, vvodit novij uzel sleva sverhu ot nego,
                          // esli b = 1 - sprava sverhu.  Esli uzel uge bil, ispolzuet ego.
                          // Vniz na 1 piksel ot uzla provoditsja novaja linija.
                          // Vozvrashaet uzel.
{UINT c,d,e,e1,e2,f1,f2,f3,j,p;
 p = (b == 0 ? CVOTR[a+4] : CVOTR[a+5]); // bufer
 if(CVOTR[p+1]== 0)
  {c = (b == 0 ? CVOTR[a] : CVOTR[a+1]+1); // abscissa uzla
   d = CVOTREND; // novij uzel
   CVOTR[d] = c;
   CVOTR[d+1] = i;
   for(j = 2; j < 6; j++)
    {CVOTR[d+j] = 0;}
   CVOTREND += 6;
   CVOTR[p+1] = d;
  }
 else
  {d = CVOTR[p+1];
   c = CVOTR[d];
  }
 e = CVOTREND; // pervaja chetverka dlja novoj linii
 CVOTR[e] = c; CVOTR[e+1] = i;
 CVOTR[e+2] = 0;
 CVOTREND += 4;
 e1 = CVOTREND; // vtoraja chetverka linii
 CVOTR[e1] = c; CVOTR[e1+1] = i+1;
 CVOTR[e1+2] = e; CVOTR[e+3] = e1;
 CVOTR[e1+3] = 0;
 CVOTREND += 4;
 e2 = CVOTREND; // novaja linija
 CVOTR[p] = e2; // registracija linii v bufere
 f1 = CVOTR[a+3]; // pjatno tekushego otrezka
 f2 = 0; // drugoe pjatno
 if(b == 0 && CVOTR[a] != 0)
  {f2 = CVOTR[a-3];}
 if(b == 1 && CVOTR[a+1] != (oblshirina - 1))
  {f2 = CVOTR[a+9];}
 CVOTR[e2] = f1; CVOTR[e2+1] = f2;
 CVOTR[e2+2] = e; CVOTR[e2+3] = e1;
 CVOTR[e2+4] = d; CVOTR[e2+5] = 0;
 CVOTREND += 7;
 for(j = 2; j < 6; j++)
 if(CVOTR[d+j] == 0)
  {CVOTR[d+j] = e2; // ssilka iz uzla na liniju
   break;
  }
 f3 = CVOTREND; // registracija linii v pjatne f1
 CVOTR[f3] = e2;
 CVOTR[f3+1] = b;
 CVOTR[f3+2] = CVOTR[f1+2];
 CVOTREND += 3;
 CVOTR[f1+2] = f3;
 if(f2 != 0)
  {f3 = CVOTREND; // registracija linii v pjatne f2
   CVOTR[f3] = e2;
   CVOTR[f3+1] = 1-b;
   CVOTR[f3+2] = CVOTR[f2+2];
   CVOTREND += 3;
   CVOTR[f2+2] = f3;
  }
 return d;
}

UINT ugoriz(UINT a, UINT b, UINT c, UINT d) // a - uzel, b - abscissa
                                 //konca novoj gorizontalnoj linii, provodimoj
                                 // iz uzla a. Eta linija otdeljaet pjatno
                                 // verhnego otrezka c ot pjatna nignego
                                 // otrezka d (vozmogni sluchai ravenstva
                                 // c ili d nulju). Vozvrashaet novuju liniju.
{UINT e,f1,f2,f3,i,p;
 e = (CVOTR[a] < b ? 0 : 1); // napravlenie: 0 - vpravo, 1 - vlevo
 f1 = (c == 0 ? 0 : CVOTR[c+3]); // verhnee pjatno
 f2 = (d == 0 ? 0 : CVOTR[d+3]); // nignee pjatno
 f3 = CVOTREND; // novaja linija
 CVOTR[f3] = f1;
 CVOTR[f3+1] = f2;
 CVOTR[f3+2] = 0;
 CVOTR[f3+3] = 0;
 CVOTR[f3+4] = a;
 CVOTR[f3+5] = 0;
 CVOTREND += 7;
 for(i = 2; i < 6; i++)
  {if(CVOTR[a+i]== 0)
    {CVOTR[a+i] = f3; break;}
  }
 if(e == 0)
  {cvgoriz(f3,CVOTR[a],b,CVOTR[a+1],0);}
 else
  {cvgoriz(f3,b,CVOTR[a],CVOTR[a+1],1);}
 if(f1 != 0)
  {p = CVOTREND; // registracija linii v pjatne f1
   CVOTR[p] = f3;
   CVOTR[p+1] = e;
   CVOTR[p+2] = CVOTR[f1+2];
   CVOTREND += 3;
   CVOTR[f1+2] = p;
  }
 if(f2 != 0)
  {p = CVOTREND; // registracija linii v pjatne f2
   CVOTR[p] = f3;
   CVOTR[p+1] = 1-e;
   CVOTR[p+2] = CVOTR[f2+2];
   CVOTREND += 3;
   CVOTR[f2+2] = p;
  }
 return f3;
}

 void cvkonc(UINT a,UINT b) // a - linija, b- uzel, k kotoromu ona podhodit
                  // linija zavershaetsja na etom uzle
 {UINT i;
  CVOTR[a+5] = b;
  for(i = 2; i < 6; i++)
   {if(CVOTR[b+i]== 0)
     {CVOTR[b+i] = a;
      break;
     }

   }
  return;
 }

 UINT ukonc(UINT a,UINT b,UINT c)//a - linija, b- otrezok, c - ukazatel
                      // konca otrezka: 0 - levij, 1 - pravij. Vvodit novij uzel vnizu
                      // otrezka, zavershajushij liniju a. Vozvrashaet etot uzel.
 {UINT d,e,i,p;
  d = CVOTR[a+3];
  e = CVOTREND; // novij uzel
  CVOTR[e] = CVOTR[d];
  CVOTR[e+1] = CVOTR[d+1];
  CVOTR[e+2] = a;
  for(i = 3; i < 6; i++)
   {CVOTR[e+i] = 0;}
  CVOTREND += 6;
  CVOTR[a+5] = e;
  p = (c == 0 ? CVOTR[b+4] : CVOTR[b+5]); // bufer
  CVOTR[p+2] = e;
  return e;
 }

  void cvpjatna(void) // operator "izobragenie(cvpjatna...)"
 {UINT i,j,k,c,c1,d,d1,d2,p,p1,p2,p3,p4,p5,p6,p7,q1,q2,r,r1,r2,u1,u2;
  int s1,s2,s3,s4,s5,s6,s7;
  d1 = 1;
  u1 = 5900000;
  u2 = 5930000;
  p = oblshirina - 1;
  tekbuf = u1;
  for(i = 0; i < oblvisota; i++) // uplotnenie otrezkov
                                 // teper oni budut zadavatsja shesterkami:
                                 // (nachalo otrezka - konec otrezka - cvet -
                                 // pjatno otrezka - levij bufer - pravij bufer)

   {c = CVSTR[i]; // tekushaja pozicija v stroke
    CVSTR[i] = d1;
    d = 0; // indikator konca stroki
    while(d == 0)
     {CVOTR[d1]= CVOTR[c];
      CVOTR[d1+1] = CVOTR[c+1];
      CVOTR[d1+2] = CVOTR[c+2];
      CVOTR[d1+3] = CVOTR[c+7];
      CVOTR[d1+4] = 0;
      CVOTR[d1+5] = 0;
      d1 += 6;
      if(CVOTR[c+1]== p)
       {d = 1;}
      else
       {c += 9;}
     }
   }
  CVEND = d1;
  CVOTREND = CVEND;
  PTNBGN = u1;
  for(i = 0; i < oblvisota; i++) // cozdanie naborov dlja pjaten
   {c = CVSTR[i]; // tekushaja pozicija v stroke
    d = 0; // indikator konca stroki
    while(d == 0)
     {d1 = CVOTR[c+3];
      if(CVOTR[d1+1] == 0)
       {PTNBGN -= 4;
        CVOTR[PTNBGN] = CVOTR[c+2];
        CVOTR[PTNBGN + 1] = CVOTR[d1];
        CVOTR[PTNBGN + 2] = 0;
        CVOTR[PTNBGN + 3] = 0;
        CVOTR[d1+1] = PTNBGN;
        CVOTR[c+3] = PTNBGN;
       }
      else
       {CVOTR[c+3] = CVOTR[d1+1];}
      if(CVOTR[c+1]== p)
       {d = 1;}
      else
       {c += 6;}
     }
   }
           // nachinaja c 5900000-j jachejki massiva CVOTR,
           // raspolagajutsja bufera prodolgenija linij. Bufer
           // sootvetstvuet promegutku megdu dvumja sosednimi
           // otrezkami. On sostoit iz treh jacheek: (linija promegutka,
           // verhnij uzel, nignij uzel). Tak kak bufer nugen lish na
           // 2 sosednih gorizontalnih prosmotra otrezkov, massiv
           // zapolnjaetsja ciclicheski. Ispolzujutsja jachejki
           // ot 5900000 do 5929999.
 c = CVSTR[0];
 cvbuf(c);
 uvniz(c,0,0);
 d = 0;
 while(d == 0) // obrabotka verhnej stroki
  {d1 = uvniz(c,1,0);
   c1 = CVOTR[c+4];
   c1 = CVOTR[c1+1]; // levij uzel
   d2 = ugoriz(d1,CVOTR[c],0,c);
   cvkonc(d2,c1);
   if(CVOTR[c+1] == p)
    {d = 1;}
   else
    {c += 6;}
  }

 for(i = 0; i < oblvisota - 1; i++) // obrabotka pari smegnih strok
   {c = CVSTR[i]; // tekushaja pozicija v verhnej stroke pari
    d = 0; // indikator konca obrabotki stroki
    c1 = CVSTR[i+1]; // tekushaja pozicija v nignej stroke pari
    cvbuf(c1);
   while(d == 0)
    {if(CVOTR[c1] < CVOTR[c]) // nachalo nignego otrezka levee nachala verhnego
      {if(CVOTR[c1+1] < CVOTR[c+1]) // konec nignego otrezka levee konca verhnego
        {if(CVOTR[c1+3] != CVOTR[c+3])
          {p1 = CVOTR[c+4]; // levij bufer verhnego otrezka
           p2 = CVOTR[p1]; // linija sleva ot verhnego otrezka
           if(CVOTR[p2+5] == 0) // linija p2 ne zavershena
            {p3 = c - 6; // otrezok sleva ot c
             if(CVOTR[p3+2] == CVOTR[c1+2]) // cveta otrezkov p3 i c1 ravni
              {p4 = CVOTR[c1+1]+1;
               cvgoriz(p2, CVOTR[c], p4, i+1,0);
               p4 = c1+6; // otrezok sprava ot c1
               if(CVOTR[p4+2] == CVOTR[c+2])
                {cvniz(p2);
                 p5 = CVOTR[c1+5]; // bufer sprava ot c1
                 CVOTR[p5] = p2;
                }
               else
                {q1 = uvniz(c1,1,i+1);
                 cvkonc(p2,q1);
                }
              }

            }
           else // linija p2 zavershena
            {q1 = CVOTR[p2+5]; // uzel, zavershivshij liniju p2
             p3 = c1+6; // otrezok sprava ot c1
             p4 = CVOTR[c1+1]+1;
             p4 = ugoriz(q1,p4,c,c1); // novaja linija ot uzla q1
             if(CVOTR[p3+2] == CVOTR[c+2]) // linija p4 prodolgaetsja vniz
              {cvniz(p4);
               p5 = CVOTR[c1+5];
               CVOTR[p5] = p4;
              }
             else
              {q2 = uvniz(c1,1,i+1);
               cvkonc(p4,q2);
              }
            }
          }
        }
       else // verhnij otrezok vkljuchaetsja v nignij, prichem ego
            // nachalo raspologeno strogo pravee nachala nignego
        {p1 = CVOTR[c+4]; // bufer sleva ot c
         p2 = CVOTR[p1]; // linija sleva ot c
         if(CVOTR[p2+5]== 0) // linija p2 ne zavershena
          {if(CVOTR[c+2]!= CVOTR[c1+2]) // cveta verhnego i nignego
                                        //otrezkov raznie
            {p3 = c - 6; // otrezok sleva ot c
             if(CVOTR[c1+2] == CVOTR[p3 + 2])
              {p4 = CVOTR[c+1]+1;
               cvgoriz(p2,CVOTR[c], p4,i+1,0); // linija p2 prodolgaetsja vpravo
               p4 = CVOTR[c+5];// bufer sprava ot c
               p5 = CVOTR[p4]; // linija sprava ot c
               q1 = ukonc(p5,c,1); // vvoditsja uzel q1, zavershajushij liniju p5
               cvkonc(p2,q1); // linija p2 zavershaetsja v uzle q1
               if(CVOTR[c+1]== CVOTR[c1+1]) // sovpadenie pravih koncov c,c1
                {p6 = CVOTR[c1+5]; // bufer sprava ot c1
                 CVOTR[p6+1] = q1;
                 uvniz(c1,1,i+1);
                }
              }
            }
           else // c,c1 odnogo cveta i krajnie v stroke.
                // Linija sprava ot c prodolgaetsja vniz.
            {if(CVOTR[c+1]== p && CVOTR[c1+1] == p)
              {p3 = CVOTR[c+5];
               p4 = CVOTR[c1+5];
               p5 = CVOTR[p3];
               cvniz(p5);
               CVOTR[p4] = p5;
              }

            }
          }
         else // linija p2 zavershena
          {if(CVOTR[c+2]!= CVOTR[c1+2]) // cveta c i c1 raznie
            {q1 = CVOTR[p2+5]; // konec linii p2
             p3 = CVOTR[c+5]; // bufer sprava ot c
             p4 = CVOTR[p3]; // linija sprava ot c
             if(CVOTR[c1+1]!= CVOTR[c+1]) // verhnij otrezok konchaetsja
                                          // ranshe nignego
              {p5 = c+6; // otrezok sprava ot c
               if(CVOTR[p5 + 3] == CVOTR[c1+3]) // otrezki p5,c1 -
                                              //iz odnogo pjatna
                {cvgoriz(p4,CVOTR[c],CVOTR[p5],i+1,1);
                 cvkonc(p4,q1);
                }
               else
                {q2 = ukonc(p4,c,1); // linija p4 obrivaetsja v novom uzle q2
                 p6 = ugoriz(q2,CVOTR[c],c,c1); // novaja goriz.linija
                 cvkonc(p6,q1);
                }
              }
             else // pravie konci otrezkov c,c1 sovpadajut
              {q2 = ukonc(p4,c,1);
               p5 = CVOTR[c1+5];// bufer sprava ot c1
               CVOTR[p5+1] = q2;
               uvniz(c1,1,i+1);
               p6 = ugoriz(q2,CVOTR[c],c,c1);
               cvkonc(p6,q1);
              }
            }
           else
            {if(CVOTR[c+1]== p && CVOTR[c1+1] == p)
              {p3 = CVOTR[c+5];
               p4 = CVOTR[c1+5];
               p5 = CVOTR[p3];
               cvniz(p5);
               CVOTR[p4] = p5;
              }
            }
          }
        }
      }
     else // nachalo nignego otrezka ne levee nachala verhnego
      {if(CVOTR[c]== CVOTR[c1]) // nachala otrezkov sovpadajut
        {if(CVOTR[c+2] == CVOTR[c1+2]) // cveta otrezkov c,c1 odinakovi
          {if(CVOTR[c]!= 0) // otrezok c - ne krajnij sleva
            {p1 = c-6; // levij sosed c
             p2 = c1 - 6; // levij sosed c1
             if(CVOTR[p1+2] == CVOTR[p2 + 2]) // cveta p1,p2 ravni
              {p3 = CVOTR[c+4]; // bufer sleva ot c
               p4 = CVOTR[p3]; // linija sleva ot c
               cvniz(p4);
               p5 = CVOTR[c1+4]; // bufer sleva ot c1
               CVOTR[p5] = p4;
               if(CVOTR[c+1] == p && CVOTR[c1+1] == p)
                {p3 = CVOTR[c+5];
                 p4 = CVOTR[c1+5];
                 p5 = CVOTR[p3];
                 cvniz(p5);
                 p6 = CVOTR[p5+3];
                 p6 = CVOTR[p6+1];
                 CVOTR[p4] = p5;
                }
              }
            }
           else // otrezki c,c1 krajnie sleva
            {p1 = CVOTR[c+4];
             p2 = CVOTR[p1]; // linija sleva ot c
             cvniz(p2);
             p3 = CVOTR[c1+4];
             CVOTR[p3] = p2;
             if(CVOTR[c+1] == p && CVOTR[c1+1] == p)
              {p3 = CVOTR[c+5];
               p4 = CVOTR[c1+5];
               p5 = CVOTR[p3];
               cvniz(p5);
               CVOTR[p4] = p5;
              }
            }
          }
         else // cveta otrezkov c,c1 raznie
          {if(CVOTR[c] == 0) // c- krajnij sleva
            {p1 = CVOTR[c+4];
             p2 = CVOTR[p1]; // linija sleva ot c
             q1 = ukonc(p2,c,0); // novij uzel
             p3 = CVOTR[c1+4];
             CVOTR[p3+1] = q1;
             uvniz(c1,0,i+1);
            }
           else // c- ne krajnij sleva
            {p4 = c - 6;
             p5 = c1 - 6;
             if(CVOTR[p4+2] == CVOTR[p5+2])
              {p1 = CVOTR[c+4];
               p2 = CVOTR[p1]; // linija sleva ot c
               q1 = ukonc(p2,c,0); // novij uzel
               p3 = CVOTR[c1+4];
               CVOTR[p3+1] = q1;
               uvniz(c1,0,i+1);
              }
            }
          }
        }
       if(CVOTR[c+1] < CVOTR[c1+1]) //otrezok c konchaetsja
                                    //ranshe otrezka c1
        {p1 = c+6; // otrezok sprava ot c
         p2 = CVOTR[p1+4]; // bufer sleva ot p1
         p3 = CVOTR[p2]; // linija megdu c i p1
         if(CVOTR[p1+2] == CVOTR[c1+2]) // cveta otrezkov p1 i c1 ravni
          {cvgoriz(p3,CVOTR[c1],CVOTR[c+1]+1,i+1,1); // linija p3
                                            //prodolgaetsja vlevo
           if(CVOTR[c] < CVOTR[c1]) // otrezok c nachinaetsja
                                    //ranshe otrezka c1
            {p4 = c1 - 6; // otrezok sleva ot c1
             if(CVOTR[p4+2] == CVOTR[c+2]) // cveta otrezkov p4 i c ravni
              {cvniz(p3);
               p5 = CVOTR[c1+4]; // bufer sleva ot c1
               CVOTR[p5] = p3;
              }
             else
              {p5 = CVOTR[c1+4];
               q1 = CVOTR[p5+1]; // uzel v verhnej levoj
                                 //chasti otrezka c1
               cvkonc(p3,q1);
              }
            }
           else // otrezki c,c1 nachinajutsja odnovremenno
            {p4 = CVOTR[c1+4];  // bufer sleva ot c1
             q1 = CVOTR[p4+1]; // uzel sleva ot c,c1
             cvkonc(p3,q1);
            }
          }
         else // cveta otrezkov p1,c1 raznie
          {if(CVOTR[c+2] != CVOTR[c1+2]) // cveta c,c1 raznie
            {q1 = ukonc(p3,c,1); // linija p3 zavershaetsja
                                 // v novom uzle q1
             p4 = ugoriz(q1,CVOTR[c1],c,c1); // iz uzla q1 vlevo provoditsja
                                             // linija p4
             p5 = CVOTR[c1+4]; // bufer sleva ot c1;
             if(CVOTR[p5+1] == 0) // sleva sverhu ot c1 uzla net
              {cvniz(p4);
               CVOTR[p5] = p4;
              }
             else // sleva sverhu ot c1 uzel estb
              {q2 = CVOTR[p5+1]; // uzel
               cvkonc(p4,q2);
              }
            }
          }
        }
       else // otrezok c konchaetsja ne ranshe otrezka c1
        {if(CVOTR[c+2] != CVOTR[c1+2]) // cveta otrezkov c,c1 raznie
          {q1 = uvniz(c1,1,i+1); // uzel sprava sverhu ot c1
                                 // Iz nego vniz provedena linija

           p1 = ugoriz(q1,CVOTR[c1],c,c1); // iz uzla q1 vlevo provoditsja
                                           // novaja linija p1
           if(CVOTR[c+1] == CVOTR[c1+1]) // pravie konci c,c1 sovpali
            {p2 = CVOTR[c+5]; // pravij bufer otrezka c
             p3 = CVOTR[p2]; // linija sprava ot c
             cvkonc(p3,q1); // linija p3 zavershaetsja v uzle q1
            }
           p2 = CVOTR[c1+4]; // bufer sleva ot c1
           if(CVOTR[p2+1] == 0)// sleva sverhu ot c1 net uzla
            {cvniz(p1);
             CVOTR[p2] = p1;
            }
           else
            {q2 = CVOTR[p2+1];
             cvkonc(p1,q2);
            }
          }
         else
          {if(CVOTR[c+1] == CVOTR[c1+1] && CVOTR[c+1] == p)
            {p1 = CVOTR[c+5];
             p2 = CVOTR[p1];
             p6 = CVOTR[p2+3];
             p6 = CVOTR[p6+1];
             if(p6 != i+2)
              {cvniz(p2);
               p6 = CVOTR[p2+3];
               p6 = CVOTR[p6+1];
               p3 = CVOTR[c1+5];
               CVOTR[p3] = p2;
              }
            }
          }
        }
      }
     if(CVOTR[c+1] < CVOTR[c1+1])
      {c += 6;}
     else
      {if(CVOTR[c1+1] < CVOTR[c+1])
        {c1 += 6;}
       else
        {if(CVOTR[c+1] == p)
          {d = 1;}
         else
          {c += 6;
           c1 += 6;
          }
        }
      }
    }
   }
     // nachalo obrabotki poslednej stroki
  c = CVSTR[oblvisota-1];
  p1 = CVOTR[c+4];
  p2 = CVOTR[p1]; // linija sleva ot pervogo otrezka
  q1 = ukonc(p2,c,0);
  d = 0;
  while(d == 0)
   {p1 = CVOTR[c+5];
    p2 = CVOTR[p1];
    q2 = ukonc(p2,c,1);
    p3 = ugoriz(q2,CVOTR[c],c,0);
    cvkonc(p3,q1);
    q1 = q2;
    if(CVOTR[c+1] == p)
     {d = 1;}
    else
     {c += 6;}
   }

c = PTNBGN; // iskljuchenie fiktivnih uzlov
 while(c < u1)
  {d = CVOTR[c+2]; // nachalo cepochki troek dlja granichnih linij
   while(d != 0)
    {d1 = CVOTR[d]; // linija
     if(CVOTR[d1] != 0xFFFFFFFF && (CVOTR[d+1]== 0 || CVOTR[d1+1]== 0))
      {for(i = 4; i < 6; i++)// i = 4 - nachalo linii, i = 5 - konec
        {d2 = 0; // indikator okonchanija
         while(d2 == 0)
          {c1 = CVOTR[d1+i]; // uzel
           if(CVOTR[c1+4] == 0)
            {p1 = (CVOTR[c1+2] == d1 ? CVOTR[c1+3] : CVOTR[c1+2]);
             if(p1 != 0 && p1 != d1 && CVOTR[p1] != 0xFFFFFFFF) // smegnaja linija
              {if(CVOTR[p1+4] == c1) // linija p1 primikaet v svoem nachale
                {p5 = CVOTR[p1+5];
                 for(j = 2; j < 6; j++)
                  {if(CVOTR[p5+j] == p1)
                    {CVOTR[p5+j] = d1;}
                  }
                 if(i == 4)
                  {p2 = CVOTR[p1+3]; // poslednjaja chetverka
                   CVOTR[d1+4] = CVOTR[p1+5];
                   while(p2 != 0)
                    {p3 = CVOTR[p2+2];
                     CVOTR[p2+2] = CVOTR[p2+3];
                     CVOTR[p2+3] = p3;
                     p2 = p3;
                    }
                   p3 = CVOTR[p1+2];
                   p3 = CVOTR[p3+2];
                   CVOTR[p3+3] = CVOTR[d1+2];
                   p4 = CVOTR[d1+2];
                   CVOTR[p4+2] = p3;
                   CVOTR[d1+2] = CVOTR[p1+3];
                   CVOTR[p1] = 0xFFFFFFFF;
                  }
                 else
                  {p2 = CVOTR[p1+2];
                   p2 = CVOTR[p2+3];
                   CVOTR[p2+2] = CVOTR[d1+3];
                   p3 = CVOTR[d1+3];
                   CVOTR[d1+3] = CVOTR[p1+3];
                   CVOTR[p3+3] = p2;
                   CVOTR[d1+5] = CVOTR[p1+5];
                   CVOTR[p1] = 0xFFFFFFFF;
                  }
                }
               else // linija p1 primikaet v svoem konce
                {p5 = CVOTR[p1+4];
                 for(j = 2; j < 6; j++)
                  {if(CVOTR[p5+j] == p1)
                    {CVOTR[p5+j] = d1;}
                  }
                 if(i == 4)
                  {p2 = CVOTR[d1+2];
                   p2 = CVOTR[p2+3];
                   CVOTR[p2+2] = CVOTR[p1+3];
                   p3 = CVOTR[p1+3];
                   CVOTR[p3+3] = p2;
                   CVOTR[d1+4] = CVOTR[p1+4];
                   CVOTR[d1+2] = CVOTR[p1+2];
                   CVOTR[p1] = 0xFFFFFFFF;
                  }
                 else
                  {p2 = CVOTR[p1+2]; // pervaja chetverka
                   CVOTR[d1+5] = CVOTR[p1+4];
                   while(p2 != 0)
                    {p3 = CVOTR[p2+3];
                     CVOTR[p2+3] = CVOTR[p2+2];
                     CVOTR[p2+2] = p3;
                     p2 = p3;
                    }
                   p3 = CVOTR[p1+3];
                   p3 = CVOTR[p3+3];
                   CVOTR[p3+2] = CVOTR[d1+3];
                   p4 = CVOTR[d1+3];
                   CVOTR[p4+3] = p3;
                   CVOTR[d1+3] = CVOTR[p1+2];
                   CVOTR[p1] = 0xFFFFFFFF;
                  }
                }
              }
             else
              {d2 = 1;}
            }
           else
            {d2 = 1;}
          }
        }
      }
     d = CVOTR[d+2];
    }
   c += 4;
  }
 c = PTNBGN; // sozdanie massivov koordinat pikselej linij
 while(c < u1)
  {d = CVOTR[c+2]; // nachalo cepochki troek dlja granichnih linij
   while(d != 0)
    {d1 = CVOTR[d]; // linija
     if(CVOTR[d1] != 0xFFFFFFFF && (CVOTR[d+1] == 0 || CVOTR[d1+1] == 0))
      {p1 = CVOTR[d1+2];
       p2 = CVOTREND;
       while(p1 != 0)
        {CVOTR[p2] = CVOTR[p1];
         CVOTR[p2+1] = CVOTR[p1+1];
         p2 += 2;
         p1 = CVOTR[p1+3];
        }
       CVOTR[d1+3] = CVOTREND;
       CVOTR[d1+2] = p2; // smeshenie jachejki posle linii
       CVOTREND = p2;
      }
     d = CVOTR[d+2];
    }
   c += 4;
  }
 c = PTNBGN; // sozdanie zamknutih konturov
 while(c < u1)
  {d = CVOTR[c+2]; // nachalo cepochki troek dlja granichnih linij
   p1 = CVOTREND; // nachalo massiva massivov zamknutih konturov
                  // dlja pjatna c. V nachale kagdogo massiva zamknutogo
                  // kontura - smeshenie pervoj jachejki posle nego
   while(d != 0)
    {d1 = CVOTR[d]; // linija
     if(d1 != 0)
      {if(CVOTR[d1]== 0xFFFFFFFF)
        {CVOTR[d] = 0;}
       else
        {CVOTR[d] = 0;
         p2 = CVOTR[d1+3]; // massiv linii
         p3 = CVOTR[d1+2]; // pervaja jachejka posle nego
         if(CVOTR[p2] == CVOTR[p3 -2] && CVOTR[p2+1] == CVOTR[p3-1])
          {CVOTR[CVOTREND] = CVOTREND+3;
           CVOTR[CVOTREND+1] = d1;
           CVOTR[CVOTREND+2] = CVOTR[d+1];
           CVOTREND += 3;
          }
         else
          {p4 = CVOTR[d+1]; // v cicle nige d1 - tekushsja linija,
           d2 = 0; // indikator obriva
           r1 = CVOTREND;
           CVOTR[CVOTREND+1] = d1;
           CVOTR[CVOTREND+2] = p4;
           CVOTREND += 3;
           while(d2 == 0)
            {p6 = (p4 == 0 ? CVOTR[d1+5] : CVOTR[d1+4]); // uzel prodolgenija
             r = 0;
             for(j = 2; j < 6; j++)
              {q1 = CVOTR[p6+j];
               if(q1 != 0 && q1 != d1 && (CVOTR[q1] == c || CVOTR[q1+1] == c)
                 && (CVOTR[q1+4] != CVOTR[q1+5]))
                {R[r] = q1; r++;}
              }
             if(r == 1)
              {p5 = R[0];
               j = CVOTR[c+2];
               while(j != 0)
                {if(CVOTR[j] != 0)
                  {q1 = CVOTR[j];
                   if(q1 == p5)
                    {d1 = p5; p4 = CVOTR[j+1];
                     CVOTR[CVOTREND] = d1;
                     CVOTR[CVOTREND+1] = p4;
                     CVOTREND += 2;
                     CVOTR[j] = 0;
                     break;
                    }
                  }
                 j = CVOTR[j+2];
                }
               if(j == 0)
                {CVOTR[r1]= CVOTREND;
                 d2 = 1;
                }
              }
             else
              {if(r == 0)
                {CVOTR[r1] = CVOTREND;
                 d2 = 1;
                }
               else
                {s1 = (int)CVOTR[p6];  // abscissa i ordinata uzla
                 s2 = (int)CVOTR[p6+1];
                 p7 = CVOTR[d1+3]; // massiv linii d1
                 if(CVOTR[p7] == CVOTR[p6] && CVOTR[p7+1] == CVOTR[p6+1])
                  {s3 = (int)CVOTR[p7+2];
                   s4 = (int)CVOTR[p7+3];
                  }
                 else
                  {p7 = CVOTR[d1+2];   // s3,s4 - abscissa i ordinata tochki
                                      // linii d1, smegnoj s uzlom
                   p7 -= 4;
                   s3 = (int)CVOTR[p7];
                   s4 = (int)CVOTR[p7+1];
                  }
                 s3 = s1 - s3; // koordinati k uzlu ot d1
                 s4 = s2 - s4;
                 for(j = 0; j < r; j++)
                  {p5 = R[j];
                   p7 = CVOTR[p5+3]; // massiv linii p5
                   if(CVOTR[p7] == CVOTR[p6] && CVOTR[p7+1] == CVOTR[p6+1])
                    {s5 = (int)CVOTR[p7+2];
                     s6 = (int)CVOTR[p7+3];
                    }
                   else
                    {p7 = CVOTR[p5+2];   // s5,s6 - abscissa i ordinata tochki
                                      // linii p5, smegnoj s uzlom
                     p7 -= 4;
                     s5 = (int)CVOTR[p7];
                     s6 = (int)CVOTR[p7+1];
                    }
                   s5 = s5 - s1; // koordinati vektora ot uzla k p5
                   s6 = s6 - s2;
                   s7 = (s3*s6) - (s4*s5);
                   r2 = 0;
                   if(0 < s7)
                    {k = CVOTR[c+2];
                     while(k != 0)
                      {if(CVOTR[k] != 0)
                        {q1 = CVOTR[k];
                         if(q1 == p5)
                          {d1 = p5; p4 = CVOTR[k+1];
                           CVOTR[CVOTREND] = d1;
                           CVOTR[CVOTREND+1] = p4;
                           CVOTREND += 2;
                           CVOTR[k] = 0;
                           r2 = 1;
                           break;
                          }
                         }
                        k = CVOTR[k+2];
                      }
                     if(k == 0)
                      {CVOTR[r1]= CVOTREND;
                       d2 = 1;
                       break;
                      }
                     if(r2 == 1)
                      {break;}

                    }
                  }
                 if(j == r)
                  {CVOTR[r1] = CVOTREND;
                   d2 = 1;
                  }
                }
              }
            }
          }
        }
      }
     d = CVOTR[d+2];
    }
   j = 0; p2 = p1;
   while(p2 < CVOTREND) // v R sozdajetsja massiv par (goriz.razmah - kontur)
    {p3 = CVOTR[p2];
     c1 = p2;
     p2++;
     p4 = 100000; p5 = 0; // p4,p5 - min i max abscissi
     while(p2 < p3)
      {p6 = CVOTR[p2]; // linija
       p7 = CVOTR[p6+3]; // massiv linii
       q1 = CVOTR[p6+2]; // smeshenie posle massiva
       while(p7 < q1)
        {q2 = CVOTR[p7];
         if(q2 < p4){p4 = q2;}
         if(p5 < q2){p5 = q2;}
         p7 += 2;
        }
       p2 += 2;
      }
     p5 -= p4; // goriz.razmah kontura
     R[j] = p5; R[j+1] = c1; j += 2;
    }
   p2 = 0; p3 = 0;
   for(k = 0; k < j; k += 2)
    {if(R[k] > p2)
      {p2 = R[k]; p3 = R[k+1];
      }
    }
   CVOTR[c+2] = p3; // vneshnjaja granica pjatna
   p4 = CVOTREND;
   p2 = p1;
   CVOTREND++;
   while(p2 < p4)
    {if(p2 != p3)
      {CVOTR[CVOTREND] = p2;
       CVOTREND++;
      }
     p2 = CVOTR[p2];
    }
   CVOTR[p4] = CVOTREND;
   if(CVOTREND == p4+1)
    {CVOTREND = p4; CVOTR[c+3] = 0;}
   else
    {CVOTR[c+3] = p4;}
   c += 4;
  }

return;
}


void cviskljuch(UINT a) // operator "izobragenie(iskljuch...)"
 {UINT i,j,k,c,d,d1,e,m,m1,m2,m3,n,n1,n2,n3,p,p1,p2,p3,q1,q2,q3,q4;

  for(i = 0; i < oblvisota; i++) // cicle formirovanija chetverok (cvet toj ge gruppi - cvet togo ge klassa - cvet drugoj
                                 // gruppi (esli net pervih dvuh) - summarnoe otklonenie naborov RGB)
                                 // dlja pjaten, smegnih s dannim i bolshih ego. Ssilka na chetverku
                                                                  // - iz vtorogo elementa pari C8.

     {c = CVSTR[i]; // tekushaja pozicija v stroke
      d = 0; // indikator konca stroki
      p = oblshirina - 1;
      while(d == 0)
       {p1 = CVOTR[c+7];
        p2 = CVOTR[c+2];
        if(CVOTR[p1] < a && !(p2 & 0x80000000))
         {n = ZCV[p2-1];
          n1 = (n >> 16); // B
          n2 = (n >> 8) & 0xFF; //G
          n3 = n & 0xFF; //R
          for(k = 0; k < 2; k++) // rassmotrenie levogo i pravogo sosedej
           {e = 0;
            if(k == 0 && CVOTR[c] != 0)
             {e = c-9;}
            if(k == 1 && CVOTR[c+1] != p)
             {e = c+9;}
            if(e != 0)
             {p3 = CVOTR[e+7];
              q1 = CVOTR[e+2];
              if(!(q1 & 0x80000000) && CVOTR[p3] > CVOTR[p1])
               {q2 = CVOTR[p1+1];
                if(q2 == 0)
                 {m = ZCV[q1-1];
                  m1 = (m >> 16); // B
                  m2 = (m >> 8) & 0xFF; //G
                  m3 = m & 0xFF; //R
                  m1 = (m1 > n1? m1 - n1 : n1 - m1);
                  m2 = (m2 > n2? m2 - n2 : n2 - m2);
                  m3 = (m3 > n3? m3 - n3 : n3 - m3);
                  m1 += m2;
                  m1 += m3;
                  m2 = CVOTREND;
                  CVOTR[m2+3] = m1;
                  q3 = CVGR[p2-1];
                  q4 = CVGR[q1-1];
                  if(q3 == q4)
                   {CVOTR[m2] = q1;
                    CVOTR[m2+1] = 0;
                    CVOTR[m2+2] = 0;
                   }
                  else
                   {if(CVKL[q3-1]== CVKL[q4-1])
                     {CVOTR[m2] = 0;
                      CVOTR[m2+1] = q1;
                      CVOTR[m2+2] = 0;
                     }
                    else
                     {CVOTR[m2] = 0;
                      CVOTR[m2+1] = 0;
                      CVOTR[m2+2] = q1;
                     }
                   }
                  CVOTREND += 4;
                  CVOTR[p1+1] = m2;
                 }
                else
                 {q3 = CVGR[p2-1];
                  q4 = CVGR[q1-1];
                  if(q3 == q4 || (CVOTR[q2] == 0 && (CVKL[q3-1] == CVKL[q4-1] ||
                    CVOTR[q2+1] == 0)))
                   {m = ZCV[q1-1];
                    m1 = (m >> 16); // B
                    m2 = (m >> 8) & 0xFF; //G
                    m3 = m & 0xFF; //R
                    m1 = (m1 > n1? m1 - n1 : n1 - m1);
                    m2 = (m2 > n2? m2 - n2 : n2 - m2);
                    m3 = (m3 > n3? m3 - n3 : n3 - m3);
                    m1 += m2;
                    m1 += m3;
                    if(q3 == q4)
                     {if(CVOTR[q2]== 0)
                       {CVOTR[q2] = q1; CVOTR[q2+3] = m1;}
                      else
                       {if(m1 < CVOTR[q2+3])
                         {CVOTR[q2] = q1;
                          CVOTR[q2+3] = m1;
                         }
                       }
                     }
                    else
                     {if(CVKL[q3-1] == CVKL[q4-1])
                       {if(CVOTR[q2+1] == 0)
                         {CVOTR[q2+1] = q1;
                          CVOTR[q2+3] = m1;
                         }
                        else
                         {if(m1 < CVOTR[q2+3])
                           {CVOTR[q2+1] = q1;
                            CVOTR[q2+3] = m1;
                           }
                         }
                       }
                      else
                       {if(m1 < CVOTR[q2+3])
                        {CVOTR[q2+2] = q1;
                         CVOTR[q2+3] = m1;
                        }
                       }
                     }
                   }
                 }
               }
             }
           }
          for(k = 0; k < 2; k++) // rassmotrenie verhnih libo nignih sosedej
           {e = (k == 0 ? CVOTR[c+5]: CVOTR[c+6]);
            if(e != 0)
             {d1 = 0;
              while(d1 == 0)
               {if(CVOTR[c+1] < CVOTR[e])
                 {d1 = 1;}
                else
                 {p3 = CVOTR[e+7];
                  q1 = CVOTR[e+2];
                  if(!(q1 & 0x80000000) && q1 != p2 && CVOTR[p1] < CVOTR[p3])
                   {q2 = CVOTR[p1+1];
                    if(q2 == 0)
                     {m = ZCV[q1-1];
                      m1 = (m >> 16); // B
                      m2 = (m >> 8) & 0xFF; //G
                      m3 = m & 0xFF; //R
                      m1 = (m1 > n1? m1 - n1 : n1 - m1);
                      m2 = (m2 > n2? m2 - n2 : n2 - m2);
                      m3 = (m3 > n3? m3 - n3 : n3 - m3);
                      m1 += m2;
                      m1 += m3;
                      m2 = CVOTREND;
                      CVOTR[m2+3] = m1;
                      q3 = CVGR[p2-1];
                      q4 = CVGR[q1-1];
                      if(q3 == q4)
                       {CVOTR[m2] = q1;
                        CVOTR[m2+1] = 0;
                        CVOTR[m2+2] = 0;
                       }
                      else
                       {if(CVKL[q3-1]== CVKL[q4-1])
                         {CVOTR[m2] = 0;
                          CVOTR[m2+1] = q1;
                          CVOTR[m2+2] = 0;
                         }
                        else
                         {CVOTR[m2] = 0;
                          CVOTR[m2+1] = 0;
                          CVOTR[m2+2] = q1;
                         }
                       }
                      CVOTREND += 4;
                      CVOTR[p1+1] = m2;
                     }
                    else
                     {q3 = CVGR[p2-1];
                      q4 = CVGR[q1-1];
                      if(q3 == q4 || (CVOTR[q2] == 0 && (CVKL[q3-1] == CVKL[q4-1] ||
                        CVOTR[q2+1] == 0)))
                        {m = ZCV[q1-1];
                         m1 = (m >> 16); // B
                         m2 = (m >> 8) & 0xFF; //G
                         m3 = m & 0xFF; //R
                         m1 = (m1 > n1? m1 - n1 : n1 - m1);
                         m2 = (m2 > n2? m2 - n2 : n2 - m2);
                         m3 = (m3 > n3? m3 - n3 : n3 - m3);
                         m1 += m2;
                         m1 += m3;
                         if(q3 == q4)
                          {if(CVOTR[q2]== 0)
                            {CVOTR[q2] = q1; CVOTR[q2+3] = m1;}
                           else
                            {if(m1 < CVOTR[q2+3])
                              {CVOTR[q2] = q1;
                               CVOTR[q2+3] = m1;
                              }
                            }
                          }
                        else
                         {if(CVKL[q3-1] == CVKL[q4-1])
                           {if(CVOTR[q2+1] == 0)
                             {CVOTR[q2+1] = q1;
                              CVOTR[q2+3] = m1;
                             }
                            else
                             {if(m1 < CVOTR[q2+3])
                               {CVOTR[q2+1] = q1;
                                CVOTR[q2+3] = m1;
                               }
                             }
                           }
                          else
                           {if(m1 < CVOTR[q2+3])
                             {CVOTR[q2+2] = q1;
                              CVOTR[q2+3] = m1;
                             }
                           }
                         }
                        }
                     }
                   }
                 }
                if(CVOTR[e+1] == p)
                 {d1 = 1;}
                else
                 {e += 9;}
               }
             }
           }
         }
        if(CVOTR[c+1] == p)
         {d = 1;}
        else
         {c += 9;}
       }
     }
   for(i = 0; i < oblvisota; i++) // cicle rasstanovki novih cvetov
    {c = CVSTR[i]; // tekushaja pozicija v stroke
     d = 0; // indikator konca stroki
     p = oblshirina - 1;
     while(d == 0)
      {p1 = CVOTR[c+7];
       p2 = CVOTR[p1+1];
       if(p2 != 0)
        {if(CVOTR[p2]!= 0)
          {CVOTR[c+2] = CVOTR[p2];}
         else
          {if(CVOTR[p2+1] != 0)
            {CVOTR[c+2] = CVOTR[p2+1];}
           else
            {CVOTR[c+2] = CVOTR[p2+2];}
          }
        }
       if(CVOTR[c+1] == p)
        {d = 1;}
       else
        {c += 9;}
      }
    }
   reotrezki();
   cvsvjazi();
  return;
 }

 UINT prjam(UINT a, UINT b, UINT c, UINT d) // a,b - smeshenija v massive
         // linii absciss ili ordinat; massiv linii raspolagaetsja ot c do d.
         // vozvrashaet summu dlin prjamolinejnih otrezkov linii do tochki a
         // i posle tochki b

{UINT p,q,r;
 p = 0;
 q = 0;
 r = CVOTR[a];
 while(a > c && q == 0)
  {if(CVOTR[a] == r)
    {p++;}
   else
    {q = 1;}
   a -= 2;
  }
 q = 0;
 while(b < d && q == 0)
  {if(CVOTR[b] == r)
    {p++;}
   else
    {q = 1;}
   b += 2;
  }
 return p;
}


 void ctchk(UINT a, UINT b) // po smesheniju a v CVOTR nahoditsja
                  // para koordinat pikselja. V sootvetstvujushuju
                  // jachejku karti OBL3 zanositsja znachenie b.
 {UINT c;
  c = CVOTR[a+1]*(oblshirina+1);
  c += CVOTR[a];
  OBL3[c] = b;
  return;
 }


 UINT naprlin(UINT a) // a - smeshenie v CVOTR pari koordinat
                // pikselja nekotoroj linii, ne javljajushegosja nachalom
                //etoj linii. Vozvrashaet napravlenie perehoda k
                // k etomu pikselju ot predidushego: 1 - vpravo, 2 - vlevo,
                // 3 - vverh, 4 - vniz.
 {UINT b;
  b = a - 2;
  if(CVOTR[a] == CVOTR[b])
   {if(CVOTR[a+1] > CVOTR[b+1])
     {return 4;}
    else
     {return 3;}
   }
  else
   {if(CVOTR[a] > CVOTR[b])
     {return 1;}
    else
     {return 2;}
   }
  return 0;
 }

 UINT obrnaprlin(UINT a) // a - smeshenie v CVOTR pari koordinat
                // pikselja nekotoroj linii, ne javljajushegosja koncom
                //etoj linii. Vozvrashaet napravlenie perehoda k
                // k etomu pikselju ot sledujushego: 1 - vpravo, 2 - vlevo,
                // 3 - vverh, 4 - vniz.
 {UINT b;
  b = a + 2;
  if(CVOTR[a] == CVOTR[b])
   {if(CVOTR[a+1] > CVOTR[b+1])
     {return 4;}
    else
     {return 3;}
   }
  else
   {if(CVOTR[a] > CVOTR[b])
     {return 1;}
    else
     {return 2;}
   }
  return 0;
 }

UINT cotr(UINT a, UINT b, UINT c) // a - smeshenie otrezka v CVOTR.
                  // Esli b = 0, rassmatrivaetsja otrezok togo ge cveta,
                  // raspologennij v predidushej stroke i peresekajushijsa
                  // s a, inache - v sledujushej stroke. Esli c = 0,
                  // beretsja pervij takoj otrezok; esli c = 1 - poslednij.
                  // Vozvrashaet smeshenie v CVOTR najdennogo otrezka. Esl ego net,
                  // vozvrashaet 0.

{UINT d;
 if(b == 0)
  {d = CVOTR[a+3];
   if(d != 0)
    {if(c == 0)
      {return CVOTR[d];}
     else
      {while(CVOTR[d+1] != 0)
        {d = CVOTR[d+1];}
       return CVOTR[d];
      }
    }
  }
 else
  {d = CVOTR[a+4];
   if(d != 0)
    {if(c == 0)
      {return CVOTR[d];}
     else
      {while(CVOTR[d+1] != 0)
        {d = CVOTR[d+1];}
       return CVOTR[d];
      }
    }
  }
 return 0;
}

void cvsokrash(void) // operator "izibragenie(sokrashlin)"

{UINT c,d,i,p,p1,p2,p3,p4,p5,q1,q2,r,r1;
 for(i = 0; i < oblvisota; i++) // cicle udalenija vistupov vverh
  {c = CVSTR[i]; // tekushaja pozicija v stroke
   d = 0; // indikator konca stroki
   p = oblshirina - 1;
   while(d == 0)
    {r = CVOTR[c];
     if(r == CVOTR[c+1])
      {q1 = CVOTR[c+2];
       p1 = CVOTR[c+6];
       r1 = CVOTR[c+7];
       if(p1 != 0 && !(q1 & 0x80000000)&& CVOTR[p1+2] == q1 && CVOTR[p1] < r &&
          r < CVOTR[p1+1] && CVOTR[r1] > 30)
        {p2 = c - 9;
         p3 = c + 9;
         q2 = CVOTR[p2+2];
         if(q2 == CVOTR[p3+2])
          {p4 = CVOTR[c+5];
           if(p4 != 0 && CVOTR[p4+2] != q1)
            {CVOTR[c+2] = q2;}
           else
            {if(p4 != 0 && CVOTR[p4]== r && CVOTR[p4+1] == r && CVOTR[p4-7] == q2 &&
                CVOTR[p4+11] == q2)
              {p5 = CVOTR[p4+5];
               if(p5 != 0 && CVOTR[p5+2] != q1)
                {CVOTR[c+2] = q2;
                 CVOTR[p4+2] = q2;
                }
              }
            }
          }
        }
      }
     if(CVOTR[c+1] == p)
      {d = 1;}
     else
      {c += 9;}
    }
  }
 for(i = 0; i < oblvisota; i++) // cicle udalenija vistupov vniz
  {c = CVSTR[i]; // tekushaja pozicija v stroke
   d = 0; // indikator konca stroki
   p = oblshirina - 1;
   while(d == 0)
    {r = CVOTR[c];
     if(r == CVOTR[c+1])
      {q1 = CVOTR[c+2];
       p1 = CVOTR[c+5];
       r1 = CVOTR[c+7];
       if(p1 != 0 && !(q1 & 0x80000000) && CVOTR[p1+2] == q1 && CVOTR[p1] < r &&
          r < CVOTR[p1+1] && CVOTR[r1] > 30)
        {p2 = c - 9;
         p3 = c + 9;
         q2 = CVOTR[p2+2];
         if(q2 == CVOTR[p3+2])
          {p4 = CVOTR[c+6];
           if(p4 != 0 && CVOTR[p4+2] != q1)
            {CVOTR[c+2] = q2;}
           else
            {if(p4 != 0 && CVOTR[p4]== r && CVOTR[p4+1] == r && CVOTR[p4-7] == q2 &&
                CVOTR[p4+11] == q2)
              {p5 = CVOTR[p4+6];
               if(p5 != 0 && CVOTR[p5+2] != q1)
                {CVOTR[c+2] = q2;
                 CVOTR[p4+2] = q2;
                }
              }
            }
          }
        }
      }
     if(CVOTR[c+1] == p)
      {d = 1;}
     else
      {c += 9;}
    }
  }
 for(i = 0; i < oblvisota; i++) // cicle udalenija gorizontalnih vpadin vpravo
   {c = CVSTR[i]; // tekushaja pozicija v stroke
   d = 0; // indikator konca stroki
   p = oblshirina - 1;
   while(d == 0)
    {q1 = cotr(c,0,1);
     if(q1 != 0)
      {q2 = cotr(c,1,1);
       if(q2 != 0)
        {r = CVOTR[c+7];
         if(r != 0 && CVOTR[r] > 30)
          {p1 = CVOTR[q1+1];
           p2 = CVOTR[c+1];
           p3 = CVOTR[q2+1];
           if(p1 < p2 && p3 < p2 && p2 < p)
            {p4 = (p1 < p3 ? p3 : p1);
             if(p2 - p4 < 4)
              {CVOTR[c+1] = p4;
               CVOTR[c + 9] = p4+1;
              }
            }
          }
        }
      }
     if(CVOTR[c+1] == p)
      {d = 1;}
     else
      {c += 9;}
    }
  }
 for(i = 0; i < oblvisota; i++) // cicle udalenija gorizontalnih vpadin vlevo
  {c = CVSTR[i]; // tekushaja pozicija v stroke
   d = 0; // indikator konca stroki
   p = oblshirina - 1;
   while(d == 0)
    {q1 = cotr(c,0,0);
     if(q1 != 0)
      {q2 = cotr(c,1,0);
       if(q2 != 0)
        {r = CVOTR[c+7];
         if(r != 0 && CVOTR[r] > 30)
          {p1 = CVOTR[q1];
           p2 = CVOTR[c];
           p3 = CVOTR[q2];
           if(p2 < p1 && p2 < p3 && 0 < p2)
            {p4 = (p1 < p3 ? p1 : p3);
             if(p4 - p2 < 4)
              {CVOTR[c] = p4;
               CVOTR[c - 8] = p4-1;
              }
            }
          }
        }
      }
     if(CVOTR[c+1] == p)
      {d = 1;}
     else
      {c += 9;}
    }
  }
 reotrezki();
 cvsvjazi();
 return;
}

UINT prjamgr(UINT a) // a - linija.
    // Esli linija pochti gorizontalnaja, vozvrashaet 1. Esli ona
    // pochti vertikalnaja, vozvrashaet 2. Inache vozvrashaet 0.
    // Peremennoj "prjamdlin" prisvaivaetsja dlina linii
    // bez ucheta dlin bokovih otklonenij.


{UINT b,c,d,e,f,g;
b = CVOTR[a+2];
c = CVOTR[a+3];
d = b - c;
d /= 2; // dlina linii
b -= 2;
e = CVOTR[c+1];
f = CVOTR[b+1];
g = (e > f ? e-f : f-e);
if(5*g >= 3*d)
 {prjamdlin = g;
  return 2;
 }
e = CVOTR[c];
f = CVOTR[b];
g = (e > f ? e-f : f-e);
if(5*g >= 3*d)
 {prjamdlin = g;
  return 1;
 }
 return 0;
}

UINT celm(UINT a, UINT b) // a - cvet, b - smeshenie v CVOTR gruppi
          //cvetov (v pervoj jachejke - smeshenie pervoj jachejki posle
          // gruppi)/ Esli a imeetsja v gruppe b, vozvrashaet 1, inache - 0.
{UINT c;

c = CVOTR[b];
b++;
while(b < c)
 {if(a == CVOTR[b])
   {return 1;}
   b++;
 }
 return 0;
}

UINT cvkl(UINT a, UINT b) // a,b - smeshenija v CVOTR dvuh grupp
      // cvetov. Esli a vkljuchaetsja v b, vozvrashaet 1, inache - 0.

{UINT c,d;

 c = CVOTR[a];
 a++;
 while(a < c)
  {d = CVOTR[a];
   d = celm(d,b);
   if(d == 0)
    {return 0;}
   a++;
  }
 return 1;
}

void prot1(UINT a, UINT b) // iniciiruetsja protokol. a - tip protokola,
    // b - startovoe pjatno. tipi protokolov: 1 - 1-j cicle, 2 - 2-j cicl, 3 - 3-j cicle,
    // 4 - 4-j cicle, 5 - dopoln 1a, 6- dopoln 1b, 7- dopoln 2
    // v nachale protokola idet jachejka s 1 v starshem bite (u ostalnih jacheek
    // protokola on nulevoj). V mladshih bitah - nomer tipa. Zatem - startovoe pjatno;
    // zatem - trojki (pjatno - granica - objekt). V sluchae tipa 3 posle startovogo pjatna idet
    // cvnapr.

  {PROT[PROTEND] = a;
   PROT[PROTEND] |= 0x80000000;
   PROT[PROTEND+1] = b;
   if(a == 3)
    {PROT[PROTEND+2] = cvnapr;
     PROTEND ++;
    }
   PROTEND += 2;
   return;
  }

void prot2(UINT a, UINT b) // dobavlenie k protokolu trojki (pjatno a - linija b - 0)
{PROT[PROTEND] = a;
 PROT[PROTEND+1] = b;
 PROT[PROTEND+2] = 0;
 PROTEND += 3;
}

void prot3(void) // rasstanovka ssilok na objekti v protokolah

{UINT c,d,e;
 c = 0;
 while(c < PROTEND)
  {d = PROT[c];
   d &= 0xFFF;
   if(d == 3)
    {c += 3;
    }
   else
    {c += 2;}
   while(!(PROT[c] & 0x80000000))
    {e = PROT[c]; // pjatno
     e = CVOTR[e]; // harakt.pjatna
     e = OBL4[e+3]; // objekt
     PROT[c+2] = e;
     c += 3;
    }
  }
 return;
}

void prot4(void) // sbros poslednego protokola
{while(PROTEND != 0 && !(PROT[PROTEND] & 0x80000000))
  {PROTEND --;
  }
 return;
}

void dopobj(UINT a, UINT b) // objekt b dobavljaetsja k objektu a. Pervaja
                            // jachejka objekta b zanuljaetsja.
{UINT c,d,e,e1,f,f1,g,g1,h,h1,p,q,r,s,s1;
 CVOBJ[b] = 0;
 c = CVOBJ[b+1];
 CVOBJ[a+1] += c;
 d = CVOBJ[a+2];
 e = CVOBJ[b+2];
 CVOBJ[a+2] = e;  // objedinenie spiskov pjaten
 while(e != 0)
  {f = CVOBJ[e];
   g = CVOTR[f];
   OBL4[g+3] = a; // ssilka iz pjatna objekta b perenositsja na objekt a
   e1 = e;
   e = CVOBJ[e+1];
  }
 CVOBJ[e1+1] = d;
 d = CVOBJ[a+3];
 e = CVOBJ[b+3];
 f = CVOBJ[d];
 g = CVOTR[f]; // sostavlenie novogo spiska cvetov
 h = CVOTREND; // novij spisok cvetov
 f++;
 CVOTREND++;
 while(f < g)
  {CVOTR[CVOTREND] = CVOTR[f];
   f++;
   CVOTREND++;
  }
 CVOBJ[d] = h;
 f1 = CVOBJ[e];
 g1 = CVOTR[f1];
 f1++;
 while(f1 < g1)
  {p = CVOTR[f1];
   q = h;
   r = 0;
   while(q < CVOTREND)
    {if(CVOTR[q] == p)
      {r = 1;
       break;
      }
     else
      {q++;}
    }
   if(r == 0)
    {CVOTR[CVOTREND] = p;
     CVOTREND++;
    }
   f1++;
  }
 CVOTR[h] = CVOTREND;
 f = CVOBJ[d+1];
 g = CVOTR[f]; // sostavlenie novogo spiska kolichestv cvetov
 h1 = CVOTREND; // novij spisok kolichestv cvetov
 f1 = CVOTR[h] - h;
 f1 += h1;
 CVOTR[h1] = f1;
 g1 = h1+1;
 while(g1 < f1)
  {CVOTR[g1] = 0;
   g1++;
  }
 f++;
 CVOTREND++;
 while(f < g)
  {CVOTR[CVOTREND] = CVOTR[f];
   f++;
   CVOTREND++;
  }
 CVOBJ[d+1] = h1;
 CVOTREND = CVOTR[h1];
 f1 = CVOBJ[e+1];
 g1 = CVOTR[f1];
 s = CVOBJ[e];
 s++;
 f1++;
 while(f1 < g1)
  {p = CVOTR[f1]; // kolichestvo cveta udaljaemogo pjatna
   s1 = CVOTR[s]; // cvet udaljaemogo pjatna
   q = h+1;
   r = h1+1;
   while(r < CVOTREND)
    {if(CVOTR[q] == s1)
      {CVOTR[r] += p;
       break;
      }
     else
      {q++;
       r++;
      }
    }
   f1++; s++;
  }
 return;
}


UINT cvdlin(UINT a, UINT b) // vozvrashaet summarnuju dlinu granic pjatna a s pjatnami,
  // imejushimi cvet b

 {UINT i,j,c,d,e,f;
  i = CVOTR[a+2];
  j = CVOTR[i];
  i++;
  c = 0;
  while(i < j)
   {d = CVOTR[i];
    e = (CVOTR[d]  == a ? CVOTR[d+1] : CVOTR[d]);
    if(e != 0)
     {f = CVOTR[e];
      if(OBL4[f] == b)
       {f = CVOTR[d+2] - CVOTR[d+3];
        f /= 2;
        c += f;
       }
     }
    i += 2;
   }
   return c;
 }

UINT cvdlin1(UINT a, UINT b) // vozvrashaet summarnuju dlinu granic pjatna a s pjatnami,
  // imejushimi cvet b i otnosjashimisja k formiruemomu objektu.

 {UINT i,j,c,d,e,f;
  i = CVOTR[a+2];
  j = CVOTR[i];
  i++;
  c = 0;
  while(i < j)
   {d = CVOTR[i];
    e = (CVOTR[d]  == a ? CVOTR[d+1] : CVOTR[d]);
    if(e != 0)
     {f = CVOTR[e];
      if(OBL4[f] == b && OBL4[f+3] == (OBJBGN - 4))
       {f = CVOTR[d+2] - CVOTR[d+3];
        f /= 2;
        c += f;
       }
     }
    i += 2;
   }
   return c;
 }

UINT cvdlin2(UINT a, UINT b) // vozvrashaet summarnuju dlinu granic pjatna a s pjatnami,
  // otnosjashimisja k objektu b.

 {UINT i,j,c,d,e,f;
  i = CVOTR[a+2];
  j = CVOTR[i];
  i++;
  c = 0;
  while(i < j)
   {d = CVOTR[i];
    e = (CVOTR[d]  == a ? CVOTR[d+1] : CVOTR[d]);
    if(e != 0)
     {f = CVOTR[e];
      if(OBL4[f+3] == b)
       {f = CVOTR[d+2] - CVOTR[d+3];
        f /= 2;
        c += f;
       }
     }
    i += 2;
   }
   return c;
 }


void CV1(void) //analiz dobavljaemogo pjatna
        // na 1-m cicle formirovanija objektov

{UINT a,b,c,d,e,f,g,h,h1,h2,q,q1;
 if(OBL4[hrk2+3] != 0)
  {return;}
 if(grc1 == grc2)
  {return;}
 if(CVOTR[ptn2+1] > 5000 || CVOTR[ptn1+1] > 5000)
  {return;}
 c = CVOTR[lin+6];
 if(OBL4[c] == 1)
  {return;}
 c = CVOTR[lin+2];
 c -= CVOTR[lin+3];
 c /= 2; // dlina linii
 d = OBL4[hrk2+2];
 if(6*c < d)
  {c = 0; // opredelenie summarnoj dlini c granic 2-go pjatna
          // s pjatnami gruppi grc1.
   e = CVOTR[ptn2+2];
   f = CVOTR[e];
   e++;
   while(e < f)
    {g = CVOTR[e]; // linija granici 2-go pjatna
     h = (CVOTR[g] == ptn2 ? CVOTR[g+1]: CVOTR[g]); //smegnoe pjatno
     if(h != 0)
      {h1 = CVOTR[h];
       h1 = OBL4[h1];
       h2 = CVOTR[g+6];
       if(h1 != 0 && OBL4[h2] == 0 && !(h1 & 0x80000000) && CVGR[h1-1] == grc1)
        {h1 = CVOTR[g+2] - CVOTR[g+3];
         h1 /= 2;
         c += h1;
        }
      }
     e+= 2;
    }
   if(6*c < d)
    {return;}
  }
 a = celm(cvt2, tekgrup);
 if(a == 1)
  {OBL4[hrk2+3] = OBJBGN-4;
   R[endp] = ptn2;
   endp++;
   prot2(ptn2,lin);
   return;
  }
 return;
}

void CV2(void) // analiz dobavljaemogo pjatna
            // na 2-m cicle formirovanija objektov
{UINT a,b,c,d,e,f,g,h,h1,h2,q,q1;
 if(OBL4[hrk2+3] != 0)
  {return;}
 if(grc1 == grc2)
  {return;}
 if(CVOTR[ptn2+1] > 5000)
  {return;}
 c = CVOTR[lin+6];
 if(OBL4[c] == 1)
  {return;}
 c = CVOTR[lin+2];
 c -= CVOTR[lin+3];
 c /= 2; // dlina linii
 d = OBL4[hrk2+2];
 if(6*c < d)
  {c = 0; // opredelenie summarnoj dlini c granic 2-go pjatna
          // s pjatnami gruppi grc1.
   e = CVOTR[ptn2+2];
   f = CVOTR[e];
   e++;
   while(e < f)
    {g = CVOTR[e]; // linija granici 2-go pjatna
     h = (CVOTR[g] == ptn2 ? CVOTR[g+1]: CVOTR[g]); //smegnoe pjatno
     if(h != 0)
      {h1 = CVOTR[h];
       h1 = OBL4[h1];
       h2 = CVOTR[g+6];
       if(h1 != 0 && OBL4[h2] == 0 && !(h1 & 0x80000000) && CVGR[h1-1] == grc1)
        {h1 = CVOTR[g+2] - CVOTR[g+3];
         h1 /= 2;
         c += h1;
        }
      }
     e+= 2;
    }
   if(6*c < d)
    {return;}
  }
 a = celm(cvt2, tekgrup);
 if(a == 1)
  {OBL4[hrk2+3] = OBJBGN-4;
   R[endp] = ptn2;
   endp++;
   prot2(ptn2,lin);
   return;
  }
 return;
}

void CV3(void) // analiz dobavljaemogo pjatna
            // na 3-m cicle formirovanija objektov

{UINT a,b,c,d,e,f;
 a = CVOTR[lin+6];
 if(OBL4[a] != 0)
  {return;}
 if(CVOTR[ptn2+1] > 2000)
  {return;}
 b = celm(cvt2, CVOTREND);
 c = (cvnapr == 1 ? SVCV[cvt2-1] : TMCV[cvt2-1]);
 d = celm(c, CVOTREND);
 if(b == 1 || d == 1)
  {OBL4[hrk2+3] = tekcvobj;
     R[endp] = ptn2;
     endp++;
     prot2(ptn2,lin);
     if(b == 0)
      {d = CVOTR[CVOTREND];
       CVOTR[d] = cvt2;
       CVOTR[CVOTREND] = d+1;
      }
   return;
  }
 return;
}

void CV4(void) // analiz dobavljaemogo pjatna
            // na 4-m cicle formirovanija objektov

{UINT a,b,c,d,e;
 if(grc2 == grc1)
  {a = lindelta(lin);
   b = cvdlin1(ptn2, cvt1);
   c = CVOTR[lin+2] - CVOTR[lin+3];
   c /= 2;
   e = cvdlin(ptn2, cvt1);
   d = cvdlin(ptn1, cvt2);
   if(a <= 30 || ((5*b >= 2*OBL4[hrk2+2] || (7*b >= 2*OBL4[hrk2+2] &&
     3*e >= 2*OBL4[hrk2+2])) && 10*c > OBL4[hrk2+2])||
      (8*c > OBL4[hrk1+2] && 5*d >= 2*OBL4[hrk1+2]))

    {OBL4[hrk2+3] = OBJBGN-4;
     R[endp] = ptn2;
     endp++;
     prot2(ptn2,lin);
    }
  }
 return;
}

void novobjekt(UINT a, UINT j) // a - smeshenie v CVOTR cvetnogo pjatna,
 // ne vkljuchennogo v objekt. Predprinimaetsja popitka sozdat
 // objekt, analiziruja okrestnost dannogo pjatna. j - nomer cicla formirovanija
 // objektov.

{UINT b,c,d,e,f,g,h,h1,h2,h3,h4,i,p,q,q1,q2,u,u1,u2;
 R[0] = a;
 switch(j)
  {case 1:
   b = CVOTR[a];
   if(OBL4[b+4] == 0)
    {return;}
   else
    {tekgrup = OBL4[b+4];
    }
   break;
   case 2:
   b = CVOTR[a+1];
   if(b < 5000)
    {return;}
   b = CVOTR[a];
   b = OBL4[b+3];
   if(b == 0)
    {return;}
   c = CVOBJ[b+3];
   tekgrup = CVOBJ[c];
   tekcvobj = b;
   break;
   case 3:
   b = CVOTR[a]; // harakteristiki pjatna
   h1 = OBL4[b]; // cvet pjatna
   if(OBL4[b+3]!= 0 || h1 == 0 || h1 & 0x80000000)
    {return;}
   if(CVOTR[a+1] > 2000)
    {return;}
   u = CVGR[h1-1];
   u = CVKL[u-1]; // klass cveta
   cvnapr = 0; // ukazatel zatemnenija (1) libo zasvetlenija (2)
   c = CVOTR[a+2];
   d = CVOTR[c];
   c++;
   while(c < d)
    {e = CVOTR[c]; // linija - granica pjatna
     g = CVOTR[e+6]; // harakteristiki linii
     g = OBL4[g];
     f = (CVOTR[e] == a ? CVOTR[e+1] : CVOTR[e]); // smegnoe pjatno
     if(f != 0 && g == 0)
      {g = CVOTR[f];
       g = OBL4[g+3]; // objekt
       if(g != 0)
        {h = CVOBJ[g+3];
         h = CVOBJ[h]; // cveta objekta
         h2 = celm(h1,h);
         h3 = SVCV[h1 - 1];
         h3 = celm(h3,h);
         h4 = TMCV[h1 -1];
         h4 = celm(h4,h);
         i = CVOTR[h];
         p = h+1;
         u1 = 0;
         u2 = 0;
         while(p < i)
          {q = CVOTR[p];
           q1 = CVGR[q-1];
           q1 = CVKL[q1-1];
           if(q1 != u)
            {q2 = (h3 == 1? SVCV[q-1] : TMCV[q-1]);
             if(q2 == h1)
              {u2 = 1;
               break;
              }
             u1 = 1;
             break;
            }
           p++;
          }
         if((u1 == 0 || u2 == 1) && h2 == 0 && (h3 == 1 || h4 == 1))
          {p = cvdlin2(a,g);
           if(4*p >= OBL4[b+2])
            {cvnapr = (h3 == 1 ? 1 : 2);
             p = CVOTREND;
             h2 = CVOTR[h];
             h3 = h;
             while(h3 < h2)
              {CVOTR[p] = CVOTR[h3];
               p++; h3++;
              }
             CVOTR[CVOTREND] = p+1;
             CVOTR[p] = h1; // nachinaja s CVOTREND - rabochaja gruppa cvetov
             tekcvobj = g;
             break;
            }
          }
        }

      }
     c += 2;
    }
   if(cvnapr == 0)
    {return;}
   case 4:
   if(CVOTR[a+1] < 15)
   {return;}
   break;
  }
 endp = 1; // pervaja svobodnaja jachejka v R
 c = 0; // pervaja ne obrabotannaja jachejka v R
 u = OBJBGN - 4;
 u1 = CVOTR[a];
 OBL4[u1+3] = u;
 prot1(j,a);
 while(c < endp)
  {ptn1 = R[c]; // pjatno
   c++;
   hrk1 = CVOTR[ptn1]; // harakteristiki pjatna
   cvt1 = OBL4[hrk1]; // cvet pjatna;
   if(cvt1 != 0 && !(cvt1 & 0x80000000))
    {grc1 = CVGR[cvt1-1]; // gruppa cveta
     e = CVOTR[ptn1+2];
     f = CVOTR[e]; // linii granici pjatna
     e++;
     while(e < f)
      {lin = CVOTR[e]; // linija
       ptn2 = (CVOTR[lin] == ptn1 ? CVOTR[lin+1] : CVOTR[lin]); // smegnoe pjatno
       if(ptn2 != 0)
        {hrk2 = CVOTR[ptn2]; // harakteristiki
         cvt2 = OBL4[hrk2]; // cvet
         if(cvt2 != 0 && !(cvt2 & 0x80000000) && OBL4[hrk2+3] == 0)
          {grc2 = CVGR[cvt2-1];
           cvptn[j-1]();
          }
        }
       e += 2;
      }
     d = CVOTR[ptn1+3];
     if(d != 0)
      {p = CVOTR[d];
       d++;
       while(d < p)
        {e = CVOTR[d];
         f = CVOTR[e];
         e++;
         while(e < f)
          {lin = CVOTR[e]; // linija
           ptn2 = (CVOTR[lin] == ptn1 ? CVOTR[lin+1] : CVOTR[lin]); // smegnoe pjatno
           if(ptn2 != 0)
            {hrk2 = CVOTR[ptn2]; // harakteristiki
             cvt2 = OBL4[hrk2]; // cvet
             if(cvt2 != 0 && !(cvt2 & 0x80000000) && OBL4[hrk2+3] == 0)
              {grc2 = CVGR[cvt2-1];
               cvptn[j-1]();
              }
            }
           e += 2;
          }
         d++;
        }
      }

    }
  }
 h3 = 0;
 switch(j)
  {case 1:
   if(endp > 5)
    {h3 = 1;}
   break;
   case 2:
   if(endp > 1)
    {for(i = 0; i < endp; i++)
      {h = R[i];
       cvplus(h,tekcvobj);
      }
     return;
    }
   else
    {for(i = 0; i < endp; i++)
      {h = R[i];
       h1 = CVOTR[h];
       OBL4[h1+3] = 0;
      }
     return;
    }
   break;
   case 3:
   if(endp > 1)
    {for(i = 0; i < endp; i++)
      {h = R[i];
       cvplus(h,tekcvobj);
      }
     return;
    }
   else
    {for(i = 0; i < endp; i++)
      {h = R[i];
       h1 = CVOTR[h];
       OBL4[h1+3] = 0;
      }
     return;
    }
   break;
   case 4:
   if(endp > 1)
    {h3 = 1;}
   break;
  }

 if(h3 == 1)
  {CVOBJ[u] = j;
   OBJBGN -= 4;
   h1 = 0;
   h2 = u+2;
   for(i = 0; i < endp; i++)
    {h3 = R[i];
     CVOBJ[h2] = CVOBJEND;
     CVOBJ[CVOBJEND] = h3;
     CVOBJ[CVOBJEND+1] = 0;
     h2 = CVOBJEND+1;
     CVOBJEND += 2;
     h1 += CVOTR[h3+1];
    }
   CVOBJ[u+1] = h1;
   CVOBJ[u+3] = CVOBJEND; // nabor harakteristik objekta
   CVOBJ[CVOBJEND] = 0; // smeshenie v CVOTR spiska cvetov objekta
   CVOBJ[CVOBJEND+1] = 0; // smeshenie v CVOTR spiska kolichestv pikselej
                          // zadannogo cveta
   CVOBJEND += 2;
   switch(j)
    {case 1:
     CVOBJ[CVOBJEND-2] = tekgrup;
     break;
     case 2:
     break;
     case 3:
     break;
     case 4:
     break;
    }
  }
 else
  {for(i = 0; i < endp; i++)
    {h = R[i];
     h1 = CVOTR[h];
     OBL4[h1+3] = 0;
    }
   prot4();
  }
 return;
}

UINT oprtabl(UINT a, UINT b, UINT c) // a,b - smeshenija v CVOTR
                         // spiskov ravnoj dlini. V nachale spiska -
                         // smeshenie pervoj jachejki posle ego konca
                         // Esli v spiske a est element c, to
                         // vozvrashaet element spiska b, imejushij
                         // tot ge nomer. Inache vozvrashaet 0xFFFFFFFF.
{UINT d,e;
 d = 0xFFFFFFFF;
 e = CVOTR[a];
 a++;
 b++;
 while(a < e)
  {if(CVOTR[a] == c)
    {d = CVOTR[b];
     return d;
    }
   else
    {a++; b++;
    }
  }
 return d;
}

void cvplus(UINT a, UINT b) // dobavlenije pjatna a k objektu b

{UINT c;
 c = CVOTR[a];
 OBL4[c+3] = b;
 c = CVOBJ[b+2];
 CVOBJ[CVOBJEND]= a;
 CVOBJ[CVOBJEND+1] = c;
 CVOBJ[b+2] = CVOBJEND;
 CVOBJEND += 2;
 return;
}

void cvdopoln(UINT a) // dobavlenie pjaten k objektam posle a-go
 // cicla formirovanija objektov

{UINT b,c,d,e,e1,f,f1,g,h,h1,h2,h3,i,j,p,p1,p2,p3,p4,p5,q,q1,q2,q3,q4;
 switch(a)
 {case 1:
  for(i = 0; i < LINEND; i++)
   {b = OBL4[i]; // linija
    p = CVOTR[b+6]; // harakteristiki linii
    if(OBL4[p] == 0)
     {for(j = 0; j < 2; j++)
       {if(j == 0)
         {c = CVOTR[b];
          d = CVOTR[b+1];
         }
        else
         {c = CVOTR[b+1]; // c  - pjatno objekta
          d = CVOTR[b];
         }
        if(c != 0 && d != 0 && CVOTR[d+1] < 62 && 2 < CVOTR[d+1])
         {e = CVOTR[c];
          f = OBL4[e+3]; // objekt 1-go pjatna
          e1 = CVOTR[d]; // harakteristiki 2-go pjatna
          f1 = OBL4[e1+3];
          if(f != 0 && f1 == 0 && OBL4[e+4] != 0)
           {g = OBL4[e]; // cvet 1-go pjatna
            h = CVOTR[d+2];
            h1 = CVOTR[h];
            h++;
            h3 = CVOBJ[f+3];
            h2 = CVOBJ[h3]; // spisok cvetov objekta 1-go pjatna
            while(h < h1)
             {p = CVOTR[h]; //linija - granica 2-go pjatna
              p1 = (CVOTR[p] == d ? CVOTR[p+1] : CVOTR[p]); // smegnoe pjatno
              p2 = CVOTR[p+6];
              if(p1 != 0 && OBL4[p2] == 0)
               {p2 = CVOTR[p1];
                p3 = celm(OBL4[p2],h2);
                if(OBL4[p2+3] == 0 && p3 == 1)
                 {p4 = CVOTR[p1+1];
                  q4 = 0;
                  if(p4 > 3000)
                   {p5 = oprtabl(h2,CVOBJ[h3+1],OBL4[p2]);
                    if(p5 != 0xFFFFFFFF && CVOBJ[f+1] > 9*p5)
                     {q4 = 1;}
                   }
                  if(q4 == 0)
                   {if(OBL4[e1+3]== 0)
                     {cvplus(d,f);
                      prot1(5,c);
                      prot2(d,b);
                     }
                    cvplus(p1,f);
                    prot2(p1,p);
                   }
                 }
               }
              h += 2;
             }
           }
         }
       }
     }
   }
  for(i = 0; i < LINEND; i++)
   {b = OBL4[i]; // linija
    p = CVOTR[b+6];
    if(OBL4[p] == 0)
     {for(j = 0; j < 2; j++)
       {if(j == 0)
         {c = CVOTR[b];
          d = CVOTR[b+1];
         }
        else
         {c = CVOTR[b+1]; // 1-e pjatno
          d = CVOTR[b];  // 2-e pjatno
         }
        if(c != 0 && d != 0 && CVOTR[d+1] < 1000)
         {e = CVOTR[c];
          f = OBL4[e+3]; // objekt 1-go pjatna
          e1 = CVOTR[d];
          f1 = OBL4[e1+3];
          if(f != 0 && f1 == 0)
           {h = CVOTR[d+2];
            h1 = CVOTR[h];
            h++;
            p = 0;
            while(h < h1)
             {h2 = CVOTR[h]; // linija
              p1 = (CVOTR[h2] == d ? CVOTR[h2+1] : CVOTR[h2]);
              p3 = CVOTR[h2+6];
              if(p1 != 0 && CVOTR[p1+1] != 1)
               {p2 = CVOTR[p1];
                if(OBL4[p2+3] != f || OBL4[p3]== 1)
                 {p = 1;
                  break;
                 }
               }
              h += 2;
             }
            if(p == 0)
             {cvplus(d,f);
              prot1(6,c);
              prot2(d,b);
             }
           }
         }
       }
     }
   }
  break;
  case 2:
  for(i = 0; i < LINEND; i++)
   {b = OBL4[i]; // linija
    p = CVOTR[b+6]; // harakt.linii
    if(OBL4[p] == 0)
     {for(j = 0; j < 2; j++)
       {if(j == 0)
         {c = CVOTR[b];
          d = CVOTR[b+1];
         }
        else
         {c = CVOTR[b+1]; // 1-e pjatno
          d = CVOTR[b];  // 2-e pjatno
         }
        e = CVOTR[c];  // harakt.1-go pjatna
        f = OBL4[e+3]; // objekt 1-go pjatna
        e1 = CVOTR[d]; // harakt. 2-go pjatna
        f1 = OBL4[e1+3]; // objekt 2-go pjatna
        if(f != 0 && f1 != 0 && f != f1 && CVOBJ[f]!= 0 && CVOBJ[f1]!= 0)
         {h = CVOBJ[f+3];
          h1 = CVOBJ[f1+3];
          if(h != 0 && h1 != 0)
          {h2= CVOBJ[h];
           h3 = CVOBJ[h1];
           p1 = cvkl(h2,h3);
           if(p1 == 1)
            {dopobj(f1,f);
             break;
            }
          }
         }
       }
     }
   }
  break;
  case 3:
  for(i = 0; i < LINEND; i++)
   {b = OBL4[i]; // linija
    p = CVOTR[b+6]; // harakt.linii
    if(OBL4[p] == 0)
     {for(j = 0; j < 2; j++)
       {if(j == 0)
         {c = CVOTR[b];
          d = CVOTR[b+1];
         }
        else
         {c = CVOTR[b+1]; // 1-e pjatno
          d = CVOTR[b];  // 2-e pjatno
         }
        if(c != 0 && d != 0 && CVOTR[d+1] < 1000)
         {e = CVOTR[c];  // harakt.1-go pjatna
          f = OBL4[e+3]; // objekt 1-go pjatna
          e1 = CVOTR[d]; // harakt. 2-go pjatna
          f1 = OBL4[e1+3];
          if(f != 0 && f1 == 0)
           {p = 0; // indikator dobavlenija
            CVOTR[CVOTREND] = CVOTREND+2;
            CVOTR[CVOTREND+1] = d;
            q = CVOTREND+1;
            q1 = CVOTR[d+1]; // summa razmerov otobrannih pjaten
            prot1(7,c);
            prot2(d,b);
            while(p == 0 && q < CVOTR[CVOTREND])
             {q2 = CVOTR[q]; // tek.pjatno
              h = CVOTR[q2+2];
              h1 = CVOTR[h];
              h++;
              while(h < h1)
               {h2 = CVOTR[h]; // linija - granica tek.pjatna
                p1 = (CVOTR[h2] == q2 ? CVOTR[h2+1] : CVOTR[h2]); // smegnoe pjatno
                p3 = CVOTR[h2+6];
                if(OBL4[p3] == 1)
                 {p = 1;
                  break;
                 }
                q3 = celm(p1, CVOTREND);
                if(p1 != 0 && q3 == 0 && CVOTR[p1+1] != 1)
                 {p2 = CVOTR[p1];
                  if(OBL4[p2+3] != f)
                   {if(OBL4[p2+3] != 0)
                     {p = 1;
                      break;
                     }
                    q1 += CVOTR[p1+1];
                    if(q1 > 1000)
                     {p = 1;
                      break;
                     }
                    q3 = CVOTR[CVOTREND];
                    if(q3 > CVOTREND+9)
                     {p = 1;
                      break;
                     }
                    CVOTR[q3] = p1;
                    CVOTR[CVOTREND] = q3+1;
                    prot2(p1,h2);
                   }
                 }
                h += 2;
               }
              q++;
             }
            if(p == 0)
             {q = CVOTREND+1;
              q1 = CVOTR[CVOTREND];
              while(q < q1)
               {q2 = CVOTR[q];
                cvplus(q2,f);
                q++;
               }
             }
            else
             {prot4();}
           }
         }
       }
     }
   }
  break;
  case 4:
  break;
 }
 return;
}

void chislcvetov(void) // vo 2-h jachejkah harakteristik objektov
                       // sozdajutsja spiski kolichestv cvetov
{UINT a,b,c,d,e,f,g,h,i,j,k,m,n;
 for(a = OBJBGN; a < 3900000; a+= 4)
  {b = CVOBJ[a+3];
   c = CVOBJ[b]; // smeshenie v CVOTR spiska cvetov
   if(c != 0)
    {d = CVOTREND;
     CVOBJ[b+1] = d; // smeshenie v CVOTR spiska kolichestv cvetov
     n = CVOTR[c] - c;
     m = d+n;
     CVOTR[d] = m;
     d++;
     while(d < m)
      {CVOTR[d] = 0;
       d++;
      }
     d = CVOTREND + 1;
     e = CVOBJ[a+2]; // smesheinie v CVOBJ spiska pjaten;
     while(e != 0)
      {f = CVOBJ[e]; //pjatno
       g = CVOTR[f];
       g = OBL4[g]; // cvet pjatna
       h = CVOTR[f+1]; // chislo pikselej pjatna
       i = CVOTR[c];
       for(j = c+1; j < i; j++)
        {if(CVOTR[j] == g)
          {k = j-c;
           k += CVOTREND;
           CVOTR[k] += h;
           break;
          }
        }
       e = CVOBJ[e+1];
      }
     CVOTREND += n;
    }
  }
}

void cvobjekti(void) // operator "izobragenie(objekti)"

{UINT a,b,c,d,e,f,g,i,j;
 CVOBJEND = 2;
 OBJBGN = 3900000;
 PROTEND = 0;
 for(j = 1; j < 5; j++) // j - nomer cicla formirovanija objektov
  {for(i = PTNBGN; i < 5900000; i += 4)
    {a = CVOTR[i];
     b = OBL4[a+3];
     if(j == 2 || b == 0)
      {novobjekt(i,j);}
    }
   if(j == 1)
   {chislcvetov();
   }
   cvdopoln(j);
  }
 prot3();
 return;
}

void pjatngrup(void) // operator "izobragenie(gruppirovki)"

{UINT c,c1,c2,d,d1,e,e1,e2,f,g,g1,g2,h,h1,h2,h3,i,j,k,m,m1,n,p,p1,p2,q;
 for(i = 0; i < oblvisota; i++)
  {c = CVSTR[i]; // tekushaja pozicija v stroke
   d = 0; // indikator konca stroki
   p = oblshirina - 1;
   while(d == 0)
    {if(CVOTR[c+1] == p || CVOTR[c+7] == p || CVOTR[c+13] == p)
      {d = 1;}
     else
      {c1 = CVOTR[c+2]; // pervij cvet
       if(c1 == 0 || c1 & 0x80000000)
        {c += 6;}
       else
        {c2 = CVGR[c1-1]; // pervaja gruppa cveta
         e1 = CVOTR[c+8]; // vtoroj cvet
         f = CVOTR[c+14]; // tretij cvet
         if(e1 == 0 || e1 & 0x80000000 || CVGR[e1-1] == c2 ||
            f == 0 || f & 0x80000000 || (CVGR[f-1] != c2))
          {c += 6;}
         else
          {e2 = CVGR[e1-1]; // vtoraja gruppa cveta
           g = c+12; // tekushij otrezok
           g1 = c2; // tekushaja gruppa cveta
           k = 1; // chislo povtorenij tekushej gruppi cveta
           d1 = 0;
           n = 0; // chislo izmenenij gruppi cveta
           while(d1 == 0)
            {if(CVOTR[g+1] == p)
              {d1 = 1;}
             else
              {g += 6;
               h = CVOTR[g+2]; // cvet novogo otrezka
               if(h != 0 && !(h & 0x80000000))
                {h1 = CVGR[h-1]; // gruppa cveta novogo otrezka
                 if(h1 == g1)
                  {k++;
                   if(k > 2)
                    {d1 = 2;}
                  }
                 else
                  {g2 = (g1 == c2 ? e2 : c2);
                   if(h1 == g2)
                    {k = 1;
                     n++;
                     g1 = h1;
                    }
                   else
                    {d1 = 1; g -= 6;}
                  }
                }
              }
            }
           if(n > 8)
            {p1 = 0;
             p2 = 0;
             for(j = c; j <= g; j += 6)
              {h = CVOTR[j+1] - CVOTR[j];
               if(h > 13)
                {p1 = 1; break;}
               if(h > 9)
                {p2 ++;}
               h = CVOTR[j+3];
               if(CVOTR[h+1] > 10000)
                {p1 = 1; break;}
              }
             if(p1 == 0 && d1 == 2) // proverka otsutstvija dlinnogo hvosta
                         // sprava otrezkov odnoj cvetnoj gruppi
              {d1 = 0;
               g1 = g;
               while(d1 == 0)
                {if(CVOTR[g1+1] == p)
                  {d1 = 1;}
                 else
                  {g1 += 6;
                   h = CVOTR[g1+2];
                   if(h != 0 && !(h & 0x80000000) && CVGR[h-1] != h1)
                    {g1 -= 6; d1 = 1;}
                  }
                }
               h = CVOTR[g1+1] - CVOTR[g-12];
               if(h > 20)
                {p1 = 1;}
              }
             if(p1 == 0 && p2 < 2)
              {m1 = 0;
               m = CVOTREND+1;
               CVOTR[CVOTREND] = m;
               for(j = c; j <= g; j += 6) //  sozdajetsjja gruppa cvetov
                {h = CVOTR[j+2];
                 if(h != 0 && !(h & 0x80000000))
                  {d1 = celm(h, CVOTREND);
                   if(d1 == 0)
                    {CVOTR[m] = h;
                     m++;
                     CVOTR[CVOTREND] = m;
                    }
                  }
                }
               for(j = c; j <= g; j += 6) // sozdanie ssilok na novuju gruppu
                                // iz pjaten
                {h = CVOTR[j+3];
                 h = CVOTR[h];
                 h1 = OBL4[h+4];
                 if(h1 == 0)
                  {OBL4[h+4] = CVOTREND;
                   m1 = 1;
                   OBL4[h+5] = 1;
                  }
                 else
                  {d1 = cvkl(CVOTREND, h1);
                   if(d1 == 1)
                    {OBL4[h+5] += 1;}
                   else
                    {d1 = cvkl(h1, CVOTREND);
                     if(d1 == 1)
                      {OBL4[h+4] = CVOTREND;
                       m1 = 1;
                       OBL4[h+5] += 1;
                      }
                     else
                      {OBL4[h+4] = 0;
                       OBL4[h+5] = 0;
                      }
                    }
                  }
                }
               if(m1 == 1)
                {CVOTREND = m;}
              }
            }
           if(CVOTR[g+1] == p)
            {d = 1;}
           else
            {c = g + 6;}
          }
        }
      }
    }
  }
 for(i = PTNBGN; i < 5900000; i += 4) // otbrasivanie tonkih grupp
  {c = CVOTR[i];
   d = OBL4[c+4];
   if(d != 0 && OBL4[c+5] < 3)
    {OBL4[c+4] = 0;
     OBL4[c+5] = 0;
    }
  }

 return;
}

void linrazlichni(void) // operator "izobragenie(razlichni).

{UINT a,b,c,d,e,f,g,h,i,i1,j,j1,k,k1,k2,m,p;
 for(i = PTNBGN; i < 5900000; i += 4)
  {a = CVOTR[i+2];
   b = CVOTR[a];
   c = a+1;
   j = 0;
   while(c < b)
    {d = CVOTR[c];
     e = prjamgr(d);
     R[j] = e;
     R[j+1] = prjamdlin;
     j += 2;
     c += 2;
    }
   k = 0;
   while(k < j)
    {f = R[k];
     if(f != 0)
      {g = R[k+1];
       h = 0;
       k1 = k+2;
       while(k1 < j && h == 0)
        {if(R[k1]!= f)
          {h = 1;}
         else
          {g += R[k1+1];
           k1 += 2;
          }
        }
       if(g > 20)
        {m = a+1;
         m += k;
         for(k2 = k; k2 < k1; k2 +=2,m += 2)
          {p = CVOTR[m];
           p = CVOTR[p+6];
           OBL4[p] = 1;
          }
        }
       k = k1;
      }
     else
      {k += 2;}
    }
  }
 return;
}

void (*cvptn[])() = {CV1,CV2,CV3,CV4};

UINT smprot(UINT a) // a- pjatno. Esli ono vozniklo v
                     // protokole, to vozvrashaet smeshenie v
                     // PROT ego trojki (pjatno - linija - objekt).
                     // Inache vozvrashaet 0
{UINT b,c;
 b = 0;
 while(b < PROTEND)
  {c = PROT[b];
   c &= 0xFFF;
   b += 2;
   if(c == 3)
    {b++;}
   while(b < PROTEND && !(PROT[b] & 0x80000000))
    {if(PROT[b] == a)
      {return b;}
     b += 3;
    }
  }
 return 0;
}

UINT tipprot(UINT a) // a- smeshenie v PROT. Vozvrashaet tip
                     // protokola, k kotoromu otnositsja a.
{while(!(PROT[a] & 0x80000000))
  {a --;}
 a = PROT[a] & 0xFFF;
 return a;
}

void izobrprot(UINT* a) // operator "izobragenie(protokol...)"

 {UINT b,b1,c,c1,d,e,f,f1,*g,*g1,h,h1,h2;
  b = *(a+1); //nomer pjatna
  b -= 0x00200104;
  b *= 4;
  b += PTNBGN; // b- pjatno
  c = smprot(b); // smeshenie v PROT ssilki na pjatno
  e = PROTEND;
  if(c != 0)
   {d = 0;
    c1 = c;
    f = PROT[c+1]; // linija
    f1 = CVOTR[f+6]; // harakteristiki linii
    OBL4[f1+1] = 1;
    h = PROT[c];
    h = CVOTR[h+2];
    h1 = CVOTR[h];
    h++;
    while(h < h1)
     {h2 = CVOTR[h]; // linija granici pjatna
      if(h2 != f)
       {f1 = CVOTR[h2+6];
        OBL4[f1+1] = 2;
       }
      h += 2;
     }
    while(d == 0)
     {PROT[e] = PROT[c1];
      PROT[e+1] = PROT[c1+1];
      PROT[e+2] = tipprot(c1);
      e += 3;
      f = PROT[c1+1]; // linija
      b1 = (CVOTR[f] == PROT[c1] ? CVOTR[f+1] : CVOTR[f]); // smegnoe pjatno
      if(b1 == 0)
       {d = 1;}
      else
       {c1 = smprot(b1);
        if(c1 == 0)
         {d = 1;}
       }
     }
   } // teper posle PROTEND do e nahoditsja
     // cepochka troek (pjatno - linija - tip protokola)
  c += 3;
  while(c < PROTEND)
   {while(c < PROTEND && !(PROT[c] & 0x80000000))
     {c1 = PROT[c]; // pjatno
      f = CVOTR[c1]; // harakteristiki pjatna
      OBL4[f+3] = 0; // otbrasivaetsja objekt
      c += 3;
     }
    if(c < PROTEND)
     {c1 = PROT[c] & 0xFFF;
      c += 2;
      if(c1 == 2)
       {c++;}
     }
   } // otbrosheni objekti pjaten posle tekushego analiziruemogo pjatna
 b1 = PROTEND;
 g = st;
 while(b1 < e)
  {c = PROT[b1]; // pjatno
   c -= PTNBGN;
   c /= 4;
   c += 0x00200104;
   *st = c;
   st++;
   b1 += 3;
  }
 c = text1(g);
 opr(*(a+2),c);
 b1 = PROTEND+1;
 while(b1 < e)
  {c = PROT[b1]; // linija
   c1 = (c >> 16);
   c1 += 0x00200104;
   c &= 0xFFFF;
   c += 0x00200104;
   g1 = st;
   *st = c1; st++;
   *st = c; st++;
   c1 = text1(g1);
   *st = c1;
   st++;
   b1 += 3;
  }
 c = text1(g);
 opr(*(a+3),c);
 b1 = PROTEND+2;
 while(b1 < e)
  {c = PROT[b1]; // nomer protokola
   c += 0x00200104;
   *st = c;
   st++;
   b1 += 3;
  }
 c = text1(g);
 opr(*(a+4),c);
 return;
 }

 void izobrvosst(void) // vosstanavlivaet objekti pjaten pri otladke

 {UINT a,b,c;
  a = 0;
  while(a < PROTEND)
   {while(a < PROTEND && !(PROT[a] & 0x80000000))
     {b = PROT[a]; // pjatno
      c = CVOTR[b]; // harakteristiki pjatna
      OBL4[c+3] = PROT[a+2]; // otbrasivaetsja objekt
      a += 3;
     }
    if(a < PROTEND)
     {b = PROT[a] & 0xFFF;
      a += 2;
      if(b == 3)
       {a++;}
     }
   }
  for(a = 0; a < LINEND; a++)
   {b = OBL4[a]; // linija
    b = CVOTR[b+6];
    OBL4[b+1] = 0;
   }
  return;
 }

void oprgrup(UINT *a) // operator "izobragenie(klass...)"

{UINT b,c,d;
 b = *(a+1);
 b = convchisl(b);
 c = CVGR[b-1];
 d = loschisl(c);
 opr(*(a+2),d);
 c = CVKL[c-1];
 d = loschisl(c);
 opr(*(a+3),d);
 return;
}

UINT razvlin(UINT a) // a - smeshenie pjatna v CVOTR.
                     // V nachale massiva CLIN sozdaetsja posledovatelnost
                     // chetverok (abscissa - ordinata - smeshenie linii v CVOTR -
                     // - 0 libo smeshenie uzla v CVOTR) dlja tochek
                     // zamknutoj granici pjatna, prohodimoj tak, chto pjatno
                     // ostajetsja sleva. Vozvrashaet pervuju svobodnuju jachejku
                     // massiva CLIN. Dalee nazivaem sozdannij massiv razvertkoj
                     // granici pjatna a.
 {UINT b,c,d,e,f,g,h;
  b = 0;
  c = CVOTR[a+2]; // vnesh.granica
  d = CVOTR[c];
  c++; // tek linija
  while(c < d)
   {e = CVOTR[c]; // linija
    f = CVOTR[c+1]; // napravlenie obhoda
    if(f == 0)
     {g = CVOTR[e+3]; // tek.piksel
      h = CVOTR[e+2];
      if(b != 0)
       {g += 2;}
      while(g < h)
       {CLIN[b] = CVOTR[g];
        CLIN[b+1] = CVOTR[g+1];
        CLIN[b+2] = e;
        CLIN[b+3] = (b == 0 ? CVOTR[e+4] : 0);
        b += 4;
        g += 2;
       }
      CLIN[b-1] = CVOTR[e+5];
     }
    else
     {g = CVOTR[e+2] - 2;
      h = CVOTR[e+3];
      if(b != 0)
       {g -= 2;}
      while(g >= h)
       {CLIN[b] = CVOTR[g];
        CLIN[b+1] = CVOTR[g+1];
        CLIN[b+2] = e;
        CLIN[b+3] = (b == 0 ? CVOTR[e+5] : 0);
        b += 4;
        g -= 2;
       }
      CLIN[b-1] = CVOTR[e+4];
     }
    c += 2;
   }
  return b;
 }

UINT prlin(UINT a) // a - smeshenie v CLIN pervoj svobodnoj
                   // jachejki posle razvertki granici pjatna.
                   // Nachinaja s a, v CLIN
                   // sozdajetsja massiv chetverok (napravlenie -
                   // chislo perehodov ve tom napravlenii - smeshenie
                   // v CLIN chetverki razvertki dlja nachala otrezka - smeshenie v CLIN
                   // chetverki dlja konca otrezka).
                   // Vozvrashaet pervuju svobodnuju jachejku v CLIN.
                   // Napravlenija: 0 - vpravo, 1 - vverh, 2 - vniz,
                   // 3 - vlevo. Massiv chetverok dalee nazivetsja
                   // sokrashennoj razvertkoj.

{UINT b,c,d,e1,e2,e3,e4,f,m,n;
 b = 0; // nachalo ocherednogo otrezka (v razvertke granici)
 c = 4; // tekushaja chetverka
 d = a;
 e1 = CLIN[0]; // abscissa i ordinata
 e2 = CLIN[1]; // predidushego piksela
 n = 0; // napravlenie
 m = 0; // dlina otrezka
 while(c < a)
  {e3 = CLIN[c];
   e4 = CLIN[c+1];
   f = (e1 == e3 ? (e2 > e4 ? 1 : 2) : (e1 > e3 ? 3 : 0)); // napravlenie
   if(m == 0)
    {m = 1;
     n = f;
    }
   else
    {if(n == f)
      {m ++;}
     else
      {CLIN[d] = n;
       CLIN[d+1] = m;
       CLIN[d+2] = b;
       CLIN[d+3] = c-4;
       d += 4;
       b = c-4;
       n = f;
       m = 1;
      }
    }
   e1 = e3; e2 = e4;
   c += 4;
  }
 return d;
}

UINT gldln(UINT a, UINT b) // a - nachalo sokrashennoj razvertki, b-
                        // pervaja jachejka posle nego. Iskljuchajutsja
                        // vistupi na 1/ Vozvrashaet novuju pervuju jachejku posle
                        // sokrashennoj razvertki
{UINT c,d,e,f,p,q;
 c = a;
 while(c+16 < b)
  {d = CLIN[c]; // osnovnoe napravlenie
   if(CLIN[c+8]== d && CLIN[c+16] == d)
    {e = CLIN[c+4]; f = CLIN[c+12];
     if(e+f == 3 && f != d)
      {p = CLIN[c+5]; // razmeri vistupov
       q = CLIN[c+13];
       if(p == 1)
        {if(q == 1)
          {CLIN[c+4]= 0xFFFFFFFF; // otbrasivaem trojku
           CLIN[c+12]= 0xFFFFFFFF;
           c += 16;
          }
         else
          {if(q == 2)
            {CLIN[c+4] = 0xFFFFFFFF;
             CLIN[c+13] = 1;
             c += 16;
            }
           else
            {c += 4;}
          }
        }
       else
        {if(p == 2 && q == 1)
          {CLIN[c+5] = 1;
           CLIN[c+12] = 0xFFFFFFFF;
           c += 16;
          }
         else
          {c += 4;}
        }
      }
     else
      {c += 4;}
    }
   else
    {c += 4;}
  }
 c = a;
 d = c;
 while(d < b)
  {if(CLIN[d] == 0xFFFFFFFF)
    {d += 4;}
   else
    {if(c == d)
      {d += 4;}
     else
      {if(CLIN[c] == CLIN[d])
        {e = CLIN[d+1];
         CLIN[c+1] += e;
         CLIN[c+3] = CLIN[d+3];
         d += 4;
        }
       else
        {if(CLIN[c] + CLIN[d] == 3)
          {if(CLIN[c+1] >= CLIN[d+1])
            {e = CLIN[d+1];
             CLIN[c+1] -= e;
             CLIN[c+3] = CLIN[d+3];
            }
           else
            {e = CLIN[d+1] - CLIN[c+1];
             CLIN[c+1] = e;
             CLIN[c] = CLIN[d];
             CLIN[c+3] = CLIN[d+3];
            }
           d += 4;
          }
         else
          {CLIN[c+4] = CLIN[d];
           CLIN[c+5] = CLIN[d+1];
           CLIN[c+6] = CLIN[d+2];
           CLIN[c+7] = CLIN[d+3];
           c += 4; d += 4;
          }
        }
      }
    }
  }
 c += 4;
 return c;
}

UINT zigzag(UINT a, UINT b) //a,b - smeshenija
   // nachala i konca  sozdannogo operatorom "monot" massiva.
   // Predprinimaetsja iskljuchenie iz etogo massiva
   // zigzagov - par protivopologno napravlennih posledovatelnih otrezkov s blizkimi
   // nachalom i koncom. Vozvrashaet smeshenie novogo konca massiva

 {UINT c,c1,c2,d,d1,e,f1,f2,f3,f4,p,r;
  if(b - a < 16)
   {return b;}
  c = a;
  while(c+4 < b)
   {d = CLIN[c];
    e = CLIN[c+4];
    if(e == d)
     {c += 4;}
    else
     {c1 = (c > a ? c-4 : b-4);
      c2 = (c < b-8 ? c + 8 : a);
      d1 = CLIN[c1];
      if(CLIN[c2] != d1)
       {c += 4;}
      else
       {f1 = CLIN[c1+3];
        f1 = CLIN[f1+3]; // konec c1
        f2 = CLIN[c+3];
        f2 = CLIN[f2+3]; // konec c
        f3 = CLIN[c2+2];
        f3 = CLIN[f3+2]; // nachalo c2
        f4 = CLIN[c2+3];
        f4 = CLIN[f4+3]; // konec c2
        p = 0; // indikator zigzaga
        switch(d1)
         {case 0: // vpravo
          r = (CLIN[f1+1] < CLIN[f3+1] ? CLIN[f3+1] - CLIN[f1+1] :
                 CLIN[f1+1] - CLIN[f3+1]);
          if((d != d1 || CLIN[f2] < CLIN[f4]) && CLIN[f3] > CLIN[f1] &&
               r < 4)
            {p = 1;}
          break;
          case 1:  // vverh
          r = (CLIN[f1] < CLIN[f3] ? CLIN[f3] - CLIN[f1] :
                 CLIN[f1] - CLIN[f3]);
          if((d != d1 || CLIN[f2+1] > CLIN[f4+1]) && CLIN[f3+1] < CLIN[f1+1] &&
               r < 4)
            {p = 1;}
          break;
          case 2: // vniz
          r = (CLIN[f1] < CLIN[f3] ? CLIN[f3] - CLIN[f1] :
                 CLIN[f1] - CLIN[f3]);
          if((d != d1 || CLIN[f2+1] < CLIN[f4+1]) && CLIN[f3+1] > CLIN[f1+1] &&
               r < 4)
            {p = 1;}
          break;
          case 3: // vlevo
          r = (CLIN[f1+1] < CLIN[f3+1] ? CLIN[f3+1] - CLIN[f1+1] :
                 CLIN[f1+1] - CLIN[f3+1]);
          if((d != d1 || CLIN[f2] > CLIN[f4]) && CLIN[f3] < CLIN[f1] &&
               r < 4)
            {p = 1;}
          break;
         }
        if(p == 1)
         {CLIN[c] = 0xFFFFFFFF;
          CLIN[c+4] = 0xFFFFFFFF;
         }
        c += 8;
       }
     }
   }
  c = b-4;
  d = CLIN[c];
  e = CLIN[a];
  if (d != 0xFFFFFFFF && e != 0xFFFFFFFF && d != e && c - a >= 16)
   {c1 = c-4;
    c2 = a+4;
    d1 = CLIN[c1];
    if(CLIN[c2] == d1)
     {f1 = CLIN[c1+3];
      f1 = CLIN[f1+3]; // konec c1
      f2 = CLIN[c+3];
      f2 = CLIN[f2+3]; // konec c
      f3 = CLIN[c2+2];
      f3 = CLIN[f3+2]; // nachalo c2
      f4 = CLIN[c2+3];
      f4 = CLIN[f4+3]; // konec c2
      p = 0; // indikator zigzaga
      switch(d)
       {case 0: // vpravo
        r = (CLIN[f1+1] < CLIN[f3+1] ? CLIN[f3+1] - CLIN[f1+1] :
                CLIN[f1+1] - CLIN[f3+1]);
        if((d != d1 || CLIN[f2] < CLIN[f4]) && CLIN[f3] > CLIN[f1] &&
           r < 4)
         {p = 1;}
        break;
        case 1:  // vverh
        r = (CLIN[f1] < CLIN[f3] ? CLIN[f3] - CLIN[f1] :
               CLIN[f1] - CLIN[f3]);
        if((d != d1 || CLIN[f2+1] > CLIN[f4+1]) && CLIN[f3+1] < CLIN[f1+1] &&
            r < 4)
         {p = 1;}
        break;
        case 2: // vniz
        r = (CLIN[f1] < CLIN[f3] ? CLIN[f3] - CLIN[f1] :
               CLIN[f1] - CLIN[f3]);
        if((d != d1 || CLIN[f2+1] < CLIN[f4+1]) && CLIN[f3+1] > CLIN[f1+1] &&
            r < 4)
          {p = 1;}
        break;
        case 3: // vlevo
        r = (CLIN[f1+1] < CLIN[f3+1] ? CLIN[f3+1] - CLIN[f1+1] :
               CLIN[f1+1] - CLIN[f3+1]);
        if((d != d1 || CLIN[f2] > CLIN[f4]) && CLIN[f3] < CLIN[f1] &&
            r < 4)
         {p = 1;}
        break;
       }
      if(p == 1)
       {CLIN[c] = 0xFFFFFFFF;
        CLIN[a] = 0xFFFFFFFF;
       }
     }
   }
  c = a;
  d = a;
  while(d < b)
   {if(CLIN[d] == 0xFFFFFFFF)
     {d += 4;}
    else
     {if(c == d)
       {c += 4;
        d += 4;
       }
      else
       {CLIN[c] = CLIN[d];
        CLIN[c+1] = CLIN[d+1];
        CLIN[c+2] = CLIN[d+2];
        CLIN[c+3] = CLIN[d+3];
        c += 4;
        d += 4;
       }
     }
   }
  return c;
 }

UINT monot(UINT a, UINT b, UINT c, UINT d, UINT e) // a - ukazatel gorizontalnoj (0)
        // libo vertikalnoj (1) monotonnosti. b, c - nachalo i konec v CLIN sokrashennoj
        // razvertki. d - pervaja svobodnaja jachejka v CLIN. e - minmalnaja dlina
        // otrezka monotonnosti. V CLIN nachinaja s d sozdajetsja massiv chetverok
        // (napravlenie - dlina otrezka monotonnosti v etom napravlenii - smeshenie v
        // sokrashennoj razvertke nachalnogo piksela otrezka - smeshenie v nej ge
        // poslednego piksela. Vozvrashaet smeshenie v CLIN pervoj svobodnoj jachejki.
        // Dannij massiv nazivaem dalee massivom monotonnosti tipa a.
{UINT f,g,h,p,q;
 q = d;
 f = b;
 while(f < c)
  {if(CLIN[f] != a && CLIN[f] + a != 3)
    {f += 4;}
   else
    {g = CLIN[f]; // tekushee napravlenie
     p = CLIN[f+1]; // summarnaja dlina
     h = f;
     while(h+8 < c)
      {if(CLIN[h+8] == g)
        {p += CLIN[h+9];
         h += 8;
        }
       else
        {if(p >= e)
          {CLIN[d] = g;
           CLIN[d+1]= p;
           CLIN[d+2] = f;
           CLIN[d+3] = h;
           d += 4;
          }
         p = 0;
         f = h+8;
         break;
        }
      }
     if(p >= e)
      {CLIN[d] = g;
       CLIN[d+1] = p;
       CLIN[d+2] = f;
       CLIN[d+3] = (CLIN[c-4] == g ? c-4 : c - 8);
       d += 4;
      }
     if(p != 0)
     {f = c;}
    }
  }
 f = CLIN[q];
 for(p = 4; p < 9; p += 4)
  {h = c-p;
   if(CLIN[h] == f)
    {CLIN[q+1] += CLIN[h+1];
     CLIN[q+2] = h;
     break;
    }
  }
 return d;
}


UINT glavnapr(UINT a) // a - smeshenie v massive monotonnosti nekotorogo otrezka.
 // Esli ego protjagennost v napravlenii soglasno pervoj jachejke bolshe protjagennosti
 // v ortogonalnom napravlenii, vozvrashaet 1, inache 0.

 {UINT b,c,d,e;
  b = CLIN[a+2];
  b = CLIN[b+2]; // pervij piksel
  c = CLIN[a+3];
  c = CLIN[c+3]; // poslednij piksel
  d = (CLIN[b] >= CLIN[c]? CLIN[b] - CLIN[c] : CLIN[c] - CLIN[b]);
  e = (CLIN[b+1] >= CLIN[c+1]? CLIN[b+1] - CLIN[c+1] : CLIN[c+1] - CLIN[b+1]);
  if(CLIN[a] == 0 || CLIN[a] == 3)
   {if(e > d)
     {return 0;}
   }
  else
   {if(d > e)
     {return 0;}
   }
  return 1;
 }

UINT monotsoed(UINT a, UINT b) // a,b - smeshenija v massive monotonnosti
 // dvuh otrezkov. Esli promegutkom posle a do b mogno prenebrech,
 // vozvrashaet 1, inache 0.

 {UINT c,d,e,f,g;
  c = CLIN[a+2];
  c = CLIN[c+2]; //pervij piksel 1-go otrezka
  d = CLIN[a+3];
  d = CLIN[d+3]; // poslednij piksel 1-go otrezka
  e = CLIN[b+2];
  e = CLIN[e+2]; // pervij piksel 2-go otrezka
  if(CLIN[a] == 0 || CLIN[a]== 3) // gorizontalnij sluchaj
   {f = (CLIN[c+1] >= CLIN[e+1]? CLIN[c+1] - CLIN[e+1] :
         CLIN[e+1] - CLIN[c+1]); // vertikalnoe prirashenie
    if(f > 2*CLIN[a+1])
     {return 0;}
    if(CLIN[a] == 0)
     {g = (CLIN[e] >= CLIN[d] ? 0 : CLIN[d] - CLIN[e]);
      if(4*g > CLIN[b+1])
       {return 0;}
     }
    else
     {g = (CLIN[d] >= CLIN[e] ? 0 : CLIN[e] - CLIN[d]);
      if(4*g > CLIN[b+1])
       {return 0;}
     }
   }
  else    // vertikalnij sluchaj
   {f = (CLIN[c] >= CLIN[e]? CLIN[c] - CLIN[e] :
         CLIN[e] - CLIN[c]); // gorizontalnoe prirashenie
    if(f > 2*CLIN[a+1])
     {return 0;}
    if(CLIN[a] == 2)
     {g = (CLIN[e+1] >= CLIN[d+1] ? 0 : CLIN[d+1] - CLIN[e+1]);
      if(4*g > CLIN[b+1])
       {return 0;}
     }
    else
     {g = (CLIN[d+1] >= CLIN[e+1] ? 0 : CLIN[e+1] - CLIN[d+1]);
      if(4*g > CLIN[b+1])
       {return 0;}
     }
   }
  return 1;
 }

UINT dlinmonot(UINT a, UINT b, UINT c, UINT d)  //soedinenie razorvannih otrezkov monotonnosti
 // a - ukazatel gorizontalnoj (0) libo vertikalnoj (1) monotonnosti, b i c - nachalo i konec
 // v CLIN massiva monotonnosti tipa a. d - pervaja svobodnaja jachejka v CLIN.
 // Nachinaja s d, sozdajetsja massiv chetverok togo ge tipa, chto v massive monotonnosti.
 // Oni poluchajutsja objedineniem neskolkih idushih podrjad otrezkov monotonnosti. Osobo
 // rassmatrivaetsja sluchaj objedinenija pervogo i poslednego otrezkov.
 // Vozvrashaet smeshenie v CLIN pervoj svobodnoj jachejki.

{UINT e,f,g,h,h1,p;
 e = d;
 f = b;
 while(f+4 < c)
  {if(glavnapr(f) == 0)
    {f += 4;}
   else
    {h = CLIN[f];
     g = f + 4;
     p = CLIN[f+1]; // summarnaja dlina otrezka monotonnosti
     while(g < c)
      {h1 = CLIN[g];
       if(h != h1 || glavnapr(g)== 0 || monotsoed(g-4,g) == 0) // zavershenie otrezka
        {CLIN[e] = CLIN[f];
         CLIN[e+1] = p;
         CLIN[e+2] = CLIN[f+2];
         CLIN[e+3] = CLIN[g-1];
         e += 4;
         f = g;
         break;
        }
       else
       {p += CLIN[g+1];
        g += 4;
       }
      }
     g -= 4;
     if(g > f)
      {CLIN[e] = CLIN[f];
       CLIN[e+1] = p;
       CLIN[e+2] = CLIN[f+2];
       CLIN[e+3] = CLIN[g+3];
       e += 4;
       f = c;
      }
    }
  }
 if(f <c)
  {CLIN[e] = CLIN[f];
   CLIN[e+1] = CLIN[f+1];
   CLIN[e+2] = CLIN[f+2];
   CLIN[e+3] = CLIN[f+3];
   e += 4;
  }
 if(CLIN[d] == CLIN[e-4] && glavnapr(e-4) == 1
     && monotsoed(e-4,d) == 1)
  {CLIN[d+1] = CLIN[d+1] + CLIN[e-3];
   CLIN[d+2] = CLIN[e-2];
   e -= 4;
  }
 return e;
}

UINT izgib(UINT a, UINT b) //a,b - smeshenija
   // nachala i konca  sozdannogo operatorom "dlinmonot" massiva.
   // Predprinimaetsja iskljuchenie iz etogo massiva
   // izgibov - malih fragmnetov napravlenija, protivopolognogo dvum
   // sosednim bolshim fragmentam. Vozvrashaet smeshenie novogo konca massiva.

{UINT c,d,e,f;
 c = a;
 while(c < b)
  {d = CLIN[c]; // napravlenie
   e = c + 4;
   if(e == b)
    {e = a;} // e - vstrechnij uchastok
   if(CLIN[e] != d)
    {f = e + 4;
     if(f == b)
      {f = a;}
     if(CLIN[f] == d && 5*CLIN[e+1] < CLIN[c+1] + CLIN[f+1]
         && 2*CLIN[c+1] > 3*CLIN[e+1] && 2*CLIN[f+1] > 3*CLIN[e+1])
      {CLIN[f+1] += CLIN[a+1];
       CLIN[f+2] = CLIN[a+2];
       CLIN[a] = 0xFFFFFFFF;
       CLIN[e] = 0xFFFFFFFF;
       c += 8;
      }
     else
        {c += 4;}
    }
   else
   {c += 4;}
  }
  c = a;
  d = a;
  while(d < b)
   {if(CLIN[d] == 0xFFFFFFFF)
     {d += 4;}
    else
     {if(c == d)
       {c += 4;
        d += 4;
       }
      else
       {CLIN[c] = CLIN[d];
        CLIN[c+1] = CLIN[d+1];
        CLIN[c+2] = CLIN[d+2];
        CLIN[c+3] = CLIN[d+3];
        c += 4;
        d += 4;
       }
     }
   }
 return c;
}


void sokrazv(UINT *a)  // operator "izobragenie(sokrash...)"

{UINT b,c,d,*e,*f,i,p,p1,q,k1,k2,k3,k4,m;
 b = *(a+1);
 b -= 0x00200104;
 b *= 4;
 b += PTNBGN;
 c = razvlin(b);
 m = c;
 d = prlin(c);
 d = gldln(c,d);
 k1 = monot(0,c,d,d,5);
 k1 = zigzag(d,k1);
 k2 = monot(1,c,d,k1,5);
 k2 = zigzag(k1,k2);
 k3 = dlinmonot(0,d,k1,k2);
 k4 = dlinmonot(1,k1,k2,k3);
 k3 = izgib(k2,k3);
 k4 = izgib(k3,k4);
 e = st;
 while(c < d)
  {f = st;
   p = CLIN[c];
   q = (p == 0 ? 0x002012F6 : (p == 1 ? 0x00200A6B :
   (p == 2 ? 0x00200AF7 : 0x002012F5)));
   *st = q;
   st++;
   p = CLIN[c+1];
   p = loschisl(p);
   *st = p;
   st++;
   p = CLIN[c+2];
   q = CLIN[p];
   q = loschisl(q);
   *st = q;
   st++;
   q = CLIN[p+1];
   q = loschisl(q);
   *st = q;
   st++;
   p = CLIN[c+3];
   q = CLIN[p];
   q = loschisl(q);
   *st = q;
   st++;
   q = CLIN[p+1];
   q = loschisl(q);
   *st = q;
   st++;
   p = text1(f);
   *st = p;
   st++;
   c += 4;
  }
 p = text1(e);
 opr(*(a+2),p);
 for(i = 0; i < 2; i++)
  {c = (i == 0 ? d : k1);
   d = (i == 0 ? k1 : k2);
   e = st;
   while(c < d)
   {f = st;
    p = CLIN[c];
    q = (p == 0 ? 0x002012F6 : (p == 1 ? 0x00200A6B :
     (p == 2 ? 0x00200AF7 : 0x002012F5)));
    *st = q;
    st++;
    p = CLIN[c+1];
    p = loschisl(p);
    *st = p;
    st++;
    p = CLIN[c+2];
    p = CLIN[p+2];
    p1 = CLIN[p];
    p1 = loschisl(p1);
    *st = p1;
    st++;
    p1 = CLIN[p+1];
    p1 = loschisl(p1);
    *st = p1;
    st++;
    p /= 4;
    p1 = loschisl(p);
    *st = p1;
    st++;
    p = CLIN[c+3];
    p = CLIN[p+3];
    p1 = CLIN[p];
    p1 = loschisl(p1);
    *st = p1;
    st++;
    p1 = CLIN[p+1];
    p1 = loschisl(p1);
    *st = p1;
    st++;
    p /= 4;
    p1 = loschisl(p);
    *st = p1;
    st++;
    p = text1(f);
    *st = p;
    st++;
    c += 4;
   }
   p = text1(e);
   if(i == 0)
    {opr(*(a+3),p);}
   else
    {opr(*(a+4),p);}
  }
 for(i = 0; i < 2; i++)
  {c = (i == 0 ? k2 : k3);
   d = (i == 0 ? k3 : k4);
   e = st;
   while(c < d)
   {f = st;
    p = CLIN[c];
    q = (p == 0 ? 0x002012F6 : (p == 1 ? 0x00200A6B :
     (p == 2 ? 0x00200AF7 : 0x002012F5)));
    *st = q;
    st++;
    p = CLIN[c+1];
    p = loschisl(p);
    *st = p;
    st++;
    p = CLIN[c+2];
    p = CLIN[p+2];
    p1 = CLIN[p];
    p1 = loschisl(p1);
    *st = p1;
    st++;
    p1 = CLIN[p+1];
    p1 = loschisl(p1);
    *st = p1;
    st++;
    p /= 4;
    p1 = loschisl(p);
    *st = p1;
    st++;
    p = CLIN[c+3];
    p = CLIN[p+3];
    p1 = CLIN[p];
    p1 = loschisl(p1);
    *st = p1;
    st++;
    p1 = CLIN[p+1];
    p1 = loschisl(p1);
    *st = p1;
    st++;
    p /= 4;
    p1 = loschisl(p);
    *st = p1;
    st++;
    p = text1(f);
    *st = p;
    st++;
    c += 4;
   }
   p = text1(e);
   if(i == 0)
    {opr(*(a+5),p);}
   else
    {opr(*(a+6),p);}
  }
 p = m/4;
 p = loschisl(p);
 opr(*(a+7),p);
 return;
}


void cvlinsist(UINT *a) // operator "izobragenie(linsist...)"

{UINT b,c,i,k1,k2,k3,k4,m,n;
 b = *(a+1);
 b = convchisl(b);
 for(i = PTNBGN; i < 5900000; i += 4)
  {c = CVOTR[i+1];
   if(b <= c)
    {m = razvlin(i);
     n = prlin(m);
     n = gldln(m,n);
     k1 = monot(0,m,n,n,5);
     k1 = zigzag(n,k1);
     k2 = monot(1,m,n,k1,5);
     k2 = zigzag(k1,k2);
     k3 = dlinmonot(0,n,k1,k2);
     k4 = dlinmonot(1,k1,k2,k3);
     k3 = izgib(k2,k3);
     k4 = izgib(k3,k4);
    }
  }
 return;
}
