import java.util.concurrent.*;

public class ForkJoin {
    public static int findMax(int[][] matrix) {
        ForkJoinPool pool = new ForkJoinPool();
        return pool.invoke(new MaxTask(matrix, 0, matrix.length));
    }

    private static class MaxTask extends RecursiveTask<Integer> {
        private final int[][] matrix;
        private final int startRow;
        private final int endRow;

        MaxTask(int[][] matrix, int startRow, int endRow) {
            this.matrix = matrix;
            this.startRow = startRow;
            this.endRow = endRow;
        }

        @Override
        protected Integer compute() {
            if (endRow - startRow <= 100) {
                int max = Integer.MIN_VALUE;
                for (int i = startRow; i < endRow; i++) {
                    for (int j = 0; j < matrix[i].length; j++) {
                        if (matrix[i][j] > max) {
                            max = matrix[i][j];
                        }
                    }
                }
                return max;
            } 
            else {
                int mid = (startRow + endRow) / 2;
                MaxTask left = new MaxTask(matrix, startRow, mid);
                MaxTask right = new MaxTask(matrix, mid, endRow);
                left.fork();
                int rightResult = right.compute();
                int leftResult = left.join();
                return Math.max(leftResult, rightResult);
            }
        }
    }
}