public int Breadth_First_Search(int root, int lab)
        {
            int    light, gvP, Index, Len = 1000, Nei;
            bool   rv;
            iVect2 P = new iVect2(0, 0);
            CQue   Q = new CQue(Len);

            light = Grid[root];
            if (Lab[root] == 0)
            {
                Lab[root] = lab;
            }

            Q.Put(root);
            while (!Q.Empty()) //=============================
            {
                Index = Q.Get();
                gvP   = Grid[Index];
                P.Y   = Index / width; P.X = Index - width * P.Y;
                for (int n = 0; n < 8; n++) //====================
                {
                    Nei = NeighbEqu(Index, n, width, height);
                    rv  = EquNaliDir(P, n, gvP);
                    if (Nei < 0)
                    {
                        continue;
                    }
                    if (Grid[Nei] == light && Lab[Nei] == 0 && rv)
                    {
                        Lab[Nei] = lab;
                        Q.Put(Nei);
                    }
                }     //============== end for (n... ==============
            } //================ end while ====================
            return(1);
        } //****************** end Breadth-First-Search *************
        } //***************** end EquNaliDir ****************************

        public int ComponentsE(Form1 fm1)
        { /* Labels connected components of "this" in "this->Lab" and returns
           *  the number of components. Uses the EquNaLi connectedness. --*/
            int    Dir, light, i, nComp = 0, rv, x1 = 0, y1 = 0;
            bool   adjac;
            iVect2 P = new iVect2(0, 0);

            for (int k = 0; k < width * height; k++)
            {
                Lab[k] = k;
            }

            int Len = height, jump, nStep = 50;

            if (Len > 2 * nStep)
            {
                jump = Len / nStep;
            }
            else
            {
                jump = 2;
            }
            fm1.progressBar1.Step = 1;
            for (int y = 0; y < height; y++) //==================================================
            {
                if ((y % jump) == jump - 1)
                {
                    fm1.progressBar1.PerformStep();
                }
                for (int x = 0; x < width; x++) //===========================================
                {
                    i     = x + width * y;      // "i" is the index of the actual pixel
                    light = Grid[i];
                    P.X   = x; P.Y = y;
                    int nmax;
                    if (y == 0)
                    {
                        nmax = 0;
                    }
                    else
                    {
                        nmax = 3;
                    }
                    for (int n = 0; n <= nmax; n++)     //==== the four preceding neighbors =========
                    {
                        switch (n)
                        {
                        case 0: x1 = x - 1; y1 = y; break;           // West

                        case 1: x1 = x - 1; y1 = y - 1; break;       // North-West

                        case 2: x1 = x;   y1 = y - 1; break;         // North

                        case 3: x1 = x + 1; y1 = y - 1; break;       // North-East
                        }
                        if (x1 < 0 || x1 >= width)
                        {
                            continue;
                        }
                        Dir = n + 4;
                        int indN      = x1 + width * y1;
                        int lightNeib = Grid[indN];
                        if (lightNeib != light)
                        {
                            continue;
                        }
                        if ((Dir & 1) == 0)
                        {
                            adjac = true;
                        }
                        else
                        {
                            adjac = EquNaliDir(P, Dir, light);
                        }
                        if (adjac)
                        {
                            rv = SetEquivalent(i, indN); // Sets Lab[i] or Lab[indN] equal to Root
                        }
                    }                                    //==================== end for (int n ... =============================
                } //====================== end for (int x ... ===============================
            } //======================== end for (int y ... =================================
            nComp = SecondRun(); // Writes indices of components from 1 to nComp to "Comp".
            return(nComp);       // nComp+1 is the number of indices
        } //***************************** end ComponentsE ***********************************
        public bool EquNaliDir(iVect2 P, int Dir, int ColorP)
        { /* Returns 'true' if the pixel lying in the direction "dir" (0 to 7)
           * from the pixel P is connected with P accordimg to the EquNaLi membership rule.
           * Can be called for any pixel, not only in the neighborhood of a singular point.
           * Standard coordinates. "ColorP" is the color of P. --*/
            int cntP = 0, cntN = 0, col1 = -1, col2 = -1, colN = -1, x, y;

            if (N_Bits == 24)
            {
                MessageBox.Show("EquNaliDir is not designed for color images; return -1");
                return(false);
            }
            switch (Dir)
            {
            case 0: if (P.X + 1 + width * P.Y < width * height)
                {
                    colN = Grid[P.X + 1 + width * P.Y];
                }
                else
                {
                    colN = 0;
                }
                return(colN == ColorP);

            case 1: if (P.X < width - 1 && P.Y < height - 1)
                {
                    colN = Grid[P.X + 1 + width * (P.Y + 1)];
                }
                if (colN != ColorP)
                {
                    return(false);
                }
                if (P.X < width - 1)
                {
                    col1 = Grid[P.X + 1 + width * P.Y];
                }
                if (P.Y < height - 1)
                {
                    col2 = Grid[P.X + width * (P.Y + 1)];
                }
                if (col1 != col2 || col1 == ColorP)
                {
                    return(true);
                }
                break;

            case 2: if (P.Y < height - 1)
                {
                    colN = Grid[P.X + width * (P.Y + 1)];
                }
                return(colN == ColorP);

            case 3: if (P.X > 0 && P.Y < height - 1)
                {
                    colN = Grid[P.X - 1 + width * (P.Y + 1)];
                }
                if (colN != ColorP)
                {
                    return(false);
                }
                if (P.X > 0)
                {
                    col1 = Grid[P.X - 1 + width * P.Y];
                }
                if (P.X > 0)
                {
                    col2 = Grid[P.X + width * (P.Y + 1)];
                }
                if (col1 != col2 || col1 == ColorP)
                {
                    return(true);
                }
                break;

            case 4: if (P.X > 0)
                {
                    colN = Grid[P.X - 1 + width * P.Y];
                }
                return(colN == ColorP);

            case 5: if (P.X > 0 && P.Y > 0)
                {
                    colN = Grid[P.X - 1 + width * (P.Y - 1)];
                }
                if (colN != ColorP)
                {
                    return(false);
                }
                if (P.X > 0)
                {
                    col1 = Grid[P.X - 1 + width * P.Y];
                }
                if (P.Y > 0)
                {
                    col2 = Grid[P.X + width * (P.Y - 1)];
                }
                if (col1 != col2 || col1 == ColorP)
                {
                    return(true);
                }
                break;

            case 6: if (P.Y > 0)
                {
                    colN = Grid[P.X + width * (P.Y - 1)];
                }
                return(colN == ColorP);

            case 7: if (P.X < width - 1 && P.Y > 0)
                {
                    colN = Grid[P.X + 1 + width * (P.Y - 1)];
                }
                if (colN != ColorP)
                {
                    return(false);
                }
                if (P.X < width - 1)
                {
                    col1 = Grid[P.X + 1 + width * P.Y];
                }
                if (P.Y > 0)
                {
                    col2 = Grid[P.X + width * (P.Y - 1)];
                }
                if (col1 != col2 || col1 == ColorP)
                {
                    return(true);
                }
                break;
            } //:::::::::::::::::::::: end switch ::::::::::::::::::::::::::::::::::

            int imin, jmin;

            if (Dir == 3 || Dir == 5)
            {
                imin = -2;
            }
            else
            {
                imin = -1;
            }
            if (Dir == 5 || Dir == 7)
            {
                jmin = -2;
            }
            else
            {
                jmin = -1;
            }
            for (int j = jmin; j < jmin + 4; j++) //============
            {
                y = P.Y + j;
                if (y < 0 || y >= height)
                {
                    continue;
                }
                for (int i = imin; i < imin + 4; i++) //=========
                {
                    x = P.X + i;
                    if (x < 0 || x >= width)
                    {
                        continue;
                    }
                    int col = Grid[x + width * y];
                    if (col == ColorP)
                    {
                        cntP++;
                    }
                    if (col == col1)
                    {
                        cntN++;
                    }
                } //============= end for (int i... =======
            }     //=============== end for (int j... =========
            if (cntP == cntN)
            {
                return(ColorP > col1);
            }
            if (cntP < cntN)
            {
                return(true);
            }
            return(false);
        } //***************** end EquNaliDir ****************************