Problem:
Score : 300 points

Problem Statement

There is a grid with infinitely many rows and columns. In this grid, there is a rectangular region with consecutive N rows and M columns, and a card is placed in each square in this region.
The front and back sides of these cards can be distinguished, and initially every card faces up.

We will perform the following operation once for each square contains a card:

For each of the following nine squares, flip the card in it if it exists: the target square itself and the eight squares that shares a corner or a side with the target square.

It can be proved that, whether each card faces up or down after all the operations does not depend on the order the operations are performed.
Find the number of cards that face down after all the operations.

Constraints

1 \leq N,M \leq 10^9

All input values are integers.

Input

Input is given from Standard Input in the following format:

N M

Output

Print the number of cards that face down after all the operations.

Sample Input 1

2 2

Sample Output 1

0

We will flip every card in any of the four operations. Thus, after all the operations, all cards face up.

Sample Input 2

1 7

Sample Output 2

5

After all the operations, all cards except at both ends face down.

Sample Input 3

314 1592

Sample Output 3

496080

Solution in Java (OpenJDK 11.0.6) (judge verdict: Accepted)

import java.util.Scanner;


public class Main {

    public static String Y = "Yes";
    public static String N = "No";
    public static long MOD = (long) (Math.pow(10, 9) + 7);
    public static Scanner sc = new Scanner(System.in);
    static int h;
    static int w;
    static boolean[][] checked;
    static int[][] depth;

    public static void main(String[] args) {

        long n = nl();
        long m = nl();
        if (n == 2l || m == 2l) {
            out(0);
            return;
        }
        if (n == 1l && m == 1l) {
            out(1);
            return;
        }
        if (n == 1l || m == 1l) {
            out(max(n, m) - 2);
            return;
        }

        out(n * m - 2 * n - 2 * m + 4);

    }

    /*
     * 以下メソッド集
     */

    public static void permutation(String q, String ans) {

        // Base Case
        if (q.length() <= 1) {
            System.out.println(ans + q);
        }
        // General Case
        else {
            for (int i = 0; i < q.length(); i++) {
                permutation(q.substring(0, i) + q.substring(i + 1), ans + q.charAt(i));
            }
        }
    }

    static char[][] same(char[][] c, int h, int w) {

        char[][] a = new char[h][w];
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                a[i][j] = c[i][j];
            }
        }
        return a;

    }

    static int countkuro(char[][] c) {

        int count = 0;
        for (char[] cc : c) {
            for (char ccc : cc) {
                if ('#' == ccc) {
                    count++;
                }
            }
        }
        return count;
    }

    static void debug() {

        out("---");
    }

    static void debug(Object a) {

        out("-------");
        out(a);
        out("-------");
    }

    static int ketasuu(int n) {

        String str = "" + n;
        return str.length();
    }

    static int account(String str) {

        String target = "AC";
        int count = 0;
        int len = str.length();
        for (int i = 0; i < len - 1; i++) {
            if (target.equals(str.substring(i, i + target.length()))) {
                count++;
            }
        }
        return count;
    }

    static int ni() {

        return sc.nextInt();
    }

    static long nl() {

        return sc.nextLong();
    }

    static double nd() {

        return sc.nextDouble();
    }

    static String n() {

        return sc.next();
    }

    static char[] nc() {

        return sc.next().toCharArray();
    }

    static int kaijo(int n) {

        if (n == 0 || n == 1) {
            return 1;
        } else {
            return n * kaijo(n - 1);
        }
    }

    static int fib(int n) {

        return (n == 1 || n == 0) ? n : fib(n - 2) + fib(n - 1);
    }

    static long lcm(long m, long n) {

        return m * n / gcd(m, n);
    }

    static int lcm(int m, int n) {

        return m * n / gcd(m, n);
    }

    static long gcd(long a, long b) {

        return (b == 0) ? a : gcd(b, a % b);
    }

    static int gcd(int a, int b) {

        return (b == 0) ? a : gcd(b, a % b);
    }

    static void out(Object obj) {

        System.out.println(obj);
    }

    static void outn(Object obj) {

        System.out.print(obj);
    }

    static double max(double d, double e) {

        return Math.max(d, e);
    }

    static long max(long a, long b) {

        return Math.max(a, b);
    }

    static long min(long d, long e) {

        return Math.min(d, e);
    }

    static int min(int a, int b) {

        return Math.min(a, b);
    }
}


class XY {

    int h;
    int w;
    int d;

    XY(int h, int w, int d) {
        this.h = h;
        this.w = w;
        this.d = d;
    }
}