static void calculateAndPrintTime(int start, int end, int step)
        {
            for (int i = start; i <= end; i += step)
            {
                // create random matrices
                int[,] leftMatrix  = new int[i, i];
                int[,] rightMatrix = new int[i, i];
                var rand = new Random();
                for (int j = 0; j < i; ++j)
                {
                    for (int k = 0; k < i; ++k)
                    {
                        leftMatrix[j, k]  = rand.Next(0, 2);
                        rightMatrix[j, k] = rand.Next(0, 2);
                    }
                }

                // start time
                var watch = System.Diagnostics.Stopwatch.StartNew();
                FourRussianMethod fourRussianMethod = new FourRussianMethod(leftMatrix, rightMatrix);
                string[,] modifiedFirst  = fourRussianMethod.compressMatrix(leftMatrix, fourRussianMethod.k, false);
                string[,] modifiedSecond = fourRussianMethod.compressMatrix(rightMatrix, fourRussianMethod.k, true);
                int[,] result            = fourRussianMethod.multiplyBitMatrixes(modifiedFirst, modifiedSecond);

                // stop time
                watch.Stop();
                // print results
                Console.WriteLine($"Matrix size: {i}, execution time: {watch.ElapsedMilliseconds} ms");
            }
        }
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            // small example on boundary values
            // create matrices
            int[,] first = new int[, ]
            {
                { 1, 0, 0, 1, 0 },
                { 0, 1, 0, 0, 0 },
                { 1, 1, 0, 1, 0 },
                { 0, 0, 0, 1, 1 },
                { 0, 1, 1, 0, 0 }
            };
            int[,] second = new int[, ]
            {
                { 1, 0, 0, 1, 0 },
                { 0, 0, 1, 0, 0 },
                { 0, 0, 0, 0, 0 },
                { 1, 0, 0, 1, 1 },
                { 0, 1, 0, 1, 0 }
            };
            // initialize new entity of class
            FourRussianMethod fourRussianMethod = new FourRussianMethod(first, second);

            // compress both matrices and print them
            string[,] modifiedFirst = fourRussianMethod.compressMatrix(first, fourRussianMethod.k, false);
            for (int i = 0; i < modifiedFirst.GetLength(0); ++i)
            {
                for (int j = 0; j < modifiedFirst.GetLength(1); ++j)
                {
                    Console.Write(modifiedFirst[i, j] + " ");
                }
                Console.WriteLine();
            }
            Console.WriteLine("*******************************************");

            string[,] modifiedSecond = fourRussianMethod.compressMatrix(second, fourRussianMethod.k, true);
            for (int i = 0; i < modifiedSecond.GetLength(0); ++i)
            {
                for (int j = 0; j < modifiedSecond.GetLength(1); ++j)
                {
                    Console.Write(modifiedSecond[i, j] + " ");
                }
                Console.WriteLine();
            }
            Console.WriteLine("*******************************************");

            // get result matrix and print it
            int[,] result = fourRussianMethod.multiplyBitMatrixes(modifiedFirst, modifiedSecond);
            for (int i = 0; i < result.GetLength(0); ++i)
            {
                for (int j = 0; j < result.GetLength(1); ++j)
                {
                    Console.Write(result[i, j] + " ");
                }
                Console.WriteLine();
            }

            // function for big tests and checking execution time
            calculateAndPrintTime(10, 1000, 10); // arguments: start matrix size, end matrix size, step
        }