/// <summary>
        /// Finds the maximum sum rectangle with contiguous elements except the given element.
        /// </summary>
        /// <param name="a">Input array.</param>
        /// <param name="elementToExclude">The element to exclude.</param>
        /// <returns>
        /// Rectangle object
        /// (contains the indexes marking top-left, top-right, bottom-left, bottom-right corners of the rectangle) if the max sum rectangle found;
        /// Null otherwise.
        /// Note: This method will ignore the rectangle row/column if it contains the element that was asked to exclude.
        /// </returns>
        /// <remarks>This method will ignore the rectangle row/column if it contains the element that was asked to exclude.</remarks>
        /// <seealso cref="ArrayOperations.FindMaxSumSubArrayByKadanesAlgorithmCustom(int[], int)"/>
        public static Rectangle FindMaxSumRectangleWithContiguousElementsExcept(int[,] a, int elementToExclude)
        {
            int cols            = a.GetLength(1),
                rows            = a.GetLength(0);
            bool rectangleFound = false;

            Rectangle result = new Rectangle();

            for (int leftPointer = 0; leftPointer < cols; leftPointer++)
            {
                int[]  colSumArray         = new int[rows];
                bool[] AreZerosExistsInRow = new bool[rows];

                for (int rightPointer = leftPointer; rightPointer < cols; rightPointer++)
                {
                    for (int i = 0; i < rows; i++)
                    {
                        if (a[i, rightPointer] == elementToExclude)
                        {
                            AreZerosExistsInRow[i] = true;
                            // if the total till previous column is > 0.. but we have azero in the current row/column. Hence ignore the previous total.
                            colSumArray[i] = 0;
                        }
                        else if (!AreZerosExistsInRow[i])
                        {
                            colSumArray[i] += a[i, rightPointer];
                        }
                    }

                    var maxSumSubArray = ArrayOperations.FindMaxSumSubArrayByKadanesAlgorithmCustom(colSumArray, elementToExclude);

                    if (maxSumSubArray.Sum > result.Sum)
                    {
                        result.Sum = maxSumSubArray.Sum;
                        result.ColumnStartIndex = leftPointer;
                        result.ColumnEndIndex   = rightPointer;
                        result.RowStartIndex    = maxSumSubArray.SubArrayIndexes[0].Item1;
                        result.RowEndIndex      = maxSumSubArray.SubArrayIndexes[0].Item2;
                        rectangleFound          = true;
                    }
                }
            }

            if (rectangleFound)
            {
                return(result);
            }
            else
            {
                return(null);
            }
        }
        /// <summary>
        /// Finds the maximum sum rectangle.
        /// </summary>
        /// <param name="a">Input array.</param>
        /// <returns>Rectangle object
        /// (contains the indexes marking top-left, top-right, bottom-left, bottom-right corners of the rectangle) if the max sum rectangle found;
        /// Null otherwise.
        /// </returns>
        /// <seealso cref="ArrayOperations.FindMaxSumSubArrayByKadanesAlgorithm(int[])"/>
        public static Rectangle FindMaxSumRectangle(int[,] a)
        {
            int cols            = a.GetLength(1),
                rows            = a.GetLength(0);
            bool rectangleFound = false;

            Rectangle result = new Rectangle();

            for (int leftPointer = 0; leftPointer < cols; leftPointer++)
            {
                /* reset the array that stores the sum of elements in the rows
                 * (and presents columns from left pointer to right pointer)
                 * */
                int[] colSumArray = new int[rows];

                for (int rightPointer = leftPointer; rightPointer < cols; rightPointer++)
                {
                    for (int i = 0; i < rows; i++)
                    {
                        colSumArray[i] += a[i, rightPointer];
                    }

                    var maxSumSubArray = default(SubArraySumResult);

                    maxSumSubArray = ArrayOperations.FindMaxSumSubArrayByKadanesAlgorithm(colSumArray);

                    if (maxSumSubArray.Sum > result.Sum)
                    {
                        result.Sum = maxSumSubArray.Sum;
                        result.ColumnStartIndex = leftPointer;
                        result.ColumnEndIndex   = rightPointer;
                        result.RowStartIndex    = maxSumSubArray.SubArrayIndexes[0].Item1;
                        result.RowEndIndex      = maxSumSubArray.SubArrayIndexes[0].Item2;
                        rectangleFound          = true;
                    }
                }
            }

            if (rectangleFound)
            {
                return(result);
            }
            else
            {
                return(null);
            }
        }