public static int[][] multiply(int[][] f, int[][] s) {
        int f_rows = f.length;
        int s_rows = s.length;
        if(f_rows == 0) {
            return s;
        }
        if(s_rows == 0) {
            return f;
        }
        
        int f_cols = f[0].length;
        if (f_cols != s_rows) {
            String errMsg = String.format(ERRMSG_FORMAT, f_cols, s_rows);
            throw new IllegalArgumentException(errMsg);
        }
        
        int s_cols = s[0].length;
        if (f_rows == 1 && f_cols == 1 && s_rows == 1 && s_cols == 1) {
            return new int[][] { new int[] { f[0][0] * s[0][0] } };
        }
        
        //looks like there is an issue in forming the sub matrix
        int[][] f_quad_1 = subMatrix(f, 0, f_rows / 2, 0, f_cols / 2); // A
        int[][] f_quad_2 = subMatrix(f, 0, f_rows / 2, f_cols / 2, f_cols); // B
        int[][] f_quad_3 = subMatrix(f, f_rows / 2, f_rows, 0, f_cols / 2); // C
        int[][] f_quad_4 = subMatrix(f, f_rows / 2, f_rows, f_cols / 2, f_cols); // D
        int[][] s_quad_1 = subMatrix(s, 0, s_rows / 2, 0, s_cols / 2); // E
        int[][] s_quad_2 = subMatrix(s, 0, s_rows / 2, s_cols / 2, s_cols); // F
        int[][] s_quad_3 = subMatrix(s, s_rows / 2, s_rows, 0, s_cols / 2); // G
        int[][] s_quad_4 = subMatrix(s, s_rows / 2, s_rows, s_cols / 2, s_cols); // H

        int[][] r_quad_1 = add(multiply(f_quad_1, s_quad_1), multiply(f_quad_2, s_quad_3));
        int[][] r_quad_2 = add(multiply(f_quad_1, s_quad_2), multiply(f_quad_2, s_quad_4));
        int[][] r_quad_3 = add(multiply(f_quad_3, s_quad_1), multiply(f_quad_4, s_quad_3));
        int[][] r_quad_4 = add(multiply(f_quad_3, s_quad_2), multiply(f_quad_4, s_quad_4));

        return merge(r_quad_1, r_quad_2, r_quad_3, r_quad_4);
    }