Problem:
Score : 400 points

Problem Statement

There is a bar of chocolate with a height of H blocks and a width of W blocks.
Snuke is dividing this bar into exactly three pieces.
He can only cut the bar along borders of blocks, and the shape of each piece must be a rectangle.

Snuke is trying to divide the bar as evenly as possible.
More specifically, he is trying to minimize S_{max} - S_{min}, where S_{max} is the area (the number of blocks contained) of the largest piece, and S_{min} is the area of the smallest piece.
Find the minimum possible value of S_{max} - S_{min}.

Constraints

2 ≤ H, W ≤ 10^5

Input

Input is given from Standard Input in the following format:

H W

Output

Print the minimum possible value of S_{max} - S_{min}.

Sample Input 1

3 5

Sample Output 1

0

In the division below, S_{max} - S_{min} = 5 - 5 = 0.

Sample Input 2

4 5

Sample Output 2

2

In the division below, S_{max} - S_{min} = 8 - 6 = 2.

Sample Input 3

5 5

Sample Output 3

4

In the division below, S_{max} - S_{min} = 10 - 6 = 4.

Sample Input 4

100000 2

Sample Output 4

1

Sample Input 5

100000 100000

Sample Output 5

50000

Solution in C (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define MAX(X, Y) (((X) > (Y))? (X) : (Y))
#define MIN(X, Y) (((X) < (Y))? (X) : (Y))
int compare_int(const void *a, const void *b){
  return *(long int*)b - *(long int*)a; // 大きい順
}
// 公約数
long int gcd(long int a, long int b){
  if(b == 0){
    return a;
  }else{
    return gcd(b, a % b);
  }
}
// 最小公倍数 = a * b / 最大公約数
// 公倍数
long int lcm(long int a, long int b){
  return a * b / gcd(a, b);
}


// min
int main(void){
  long int h, w;
  long int ans = 0;
  long int a, b;
  long long int s1, s2, s3, smax, smin;

  scanf("%ld%ld", &h, &w);

  if(h % 3 == 0 || w % 3 == 0){
    ans = 0;
    printf("%ld\n", ans);
    return 0;
  }


  // wを/3する
  s1 = (w / 3 * h);
  s2 = (w - w/3) * (h / 2); 
  s3 = (w - w/3) * (h - (h / 2));
  fprintf(stderr, "s1 = %lld s2 = %lld s3 = %lld\n", s1, s2, s3);
  smax = MAX(MAX(s1, s2), s3);
  smin = MIN(MIN(s1, s2), s3);
  ans = smax - smin;
//  printf("smax - smin = %ld\n", ans);
  
  // w を/3 + 1
  s1 = (w / 3 + 1) * h;
  s2 = (w - (w/3 + 1)) * (h / 2); 
  s3 = (w - (w/3 + 1)) * (h - (h / 2));
  fprintf(stderr, "s1 = %lld s2 = %lld s3 = %lld\n", s1, s2, s3);
  smax = MAX(MAX(s1, s2), s3);
  smin = MIN(MIN(s1, s2), s3);
//  printf("smax - smin = %ld\n", ans);
  if(ans >  smax - smin){
    ans = smax - smin;
  }


  // w を三分割
  s1 = (w / 3) * h;
  s2 = (w - (w/3)/2) * h; 
  s3 = (w/3)/2 * h;
  fprintf(stderr, "s1 = %lld s2 = %lld s3 = %lld\n", s1, s2, s3);
  smax = MAX(MAX(s1, s2), s3);
  smin = MIN(MIN(s1, s2), s3);
//  printf("smax - smin = %ld\n", ans);
  if(ans >  smax - smin){
    ans = smax - smin;
  }

  // hを/3する
  s1 = (h / 3 * w);
  s2 = (h - h/3) * (w / 2); 
  s3 = (h - h/3) * (w - (w / 2));
  fprintf(stderr, "s1 = %lld s2 = %lld s3 = %lld\n", s1, s2, s3);
  smax = MAX(MAX(s1, s2), s3);
  smin = MIN(MIN(s1, s2), s3);
  ans = smax - smin;
  // printf("smax - smin = %ld\n", ans);
  if(ans >  smax - smin){
    ans = smax - smin;
  }
  
  // h を/3 + 1
  s1 = (h / 3 + 1) * w;
  s2 = (h - (h/3 + 1)) * (w / 2); 
  s3 = (h - (h/3 + 1)) * (w - (w / 2));
  fprintf(stderr, "s1 = %lld s2 = %lld s3 = %lld\n", s1, s2, s3);
  smax = MAX(MAX(s1, s2), s3);
  smin = MIN(MIN(s1, s2), s3);
  // printf("smax(%lld) - smin(%lld) = %ld\n", smax, smin, ans);
  if(ans >  smax - smin){
    ans = smax - smin;
  }

    // Hを三分割
  s1 = (h/ 3) * w;
  s2 = (h - (h/3)/2) * w; 
  s3 = (h/3)/2 * w;
  fprintf(stderr, "s1 = %lld s2 = %lld s3 = %lld\n", s1, s2, s3);
  smax = MAX(MAX(s1, s2), s3);
  smin = MIN(MIN(s1, s2), s3);
//  printf("smax - smin = %ld\n", ans);
  if(ans >  smax - smin){
    ans = smax - smin;
  }

  printf("%ld\n", ans);
  return 0;
}