Problem:
Score : 300 points

Problem Statement

Snuke has N dogs and M monkeys. He wants them to line up in a row.

As a Japanese saying goes, these dogs and monkeys are on bad terms. ("ken'en no naka", literally "the relationship of dogs and monkeys", means a relationship of mutual hatred.) Snuke is trying to reconsile them, by arranging the animals so that there are neither two adjacent dogs nor two adjacent monkeys.

How many such arrangements there are? Find the count modulo 10^9+7 (since animals cannot understand numbers larger than that).
Here, dogs and monkeys are both distinguishable. Also, two arrangements that result from reversing each other are distinguished.

Constraints

1 ≤ N,M ≤ 10^5

Input

Input is given from Standard Input in the following format:

N M

Output

Print the number of possible arrangements, modulo 10^9+7.

Sample Input 1

2 2

Sample Output 1

8

We will denote the dogs by A and B, and the monkeys by C and D. There are eight possible arrangements: ACBD, ADBC, BCAD, BDAC, CADB, CBDA, DACB and DBCA.

Sample Input 2

3 2

Sample Output 2

12

Sample Input 3

1 8

Sample Output 3

0

Sample Input 4

100000 100000

Sample Output 4

530123477

Solution in Rust (1.42.0) (judge verdict: Accepted)

#![allow(non_snake_case)]
#![allow(unused_imports)]
#![allow(dead_code)]

use proconio::{input, fastout};
use proconio::marker::*;
use whiteread::parse_line;
use std::collections::*;
use num::*;
use num_traits::*;
use superslice::*;
use std::ops::*;

use itertools::Itertools;
use itertools_num::ItertoolsNum;


#[derive(Debug, Clone)]
pub struct Combination {
    fac: Vec<usize>,
    fact_inv: Vec<usize>,
    inv: Vec<usize>,
    com: Option<Vec<usize>>,
    m: usize,
}
impl Combination {
    pub fn new(upper: usize, m: usize) -> Self {
        let mut fac = vec![0; upper+1];
        let mut fact_inv = vec![0; upper + 1];
        let mut inv = vec![0; upper + 1];
        fac[0] = 1;
        fac[1] = 1;
        fact_inv[0] = 1;
        fact_inv[1] = 1;
        inv[1] = 1;
        for i in 2..=upper {
            fac[i] = fac[i-1] * i % m;
            inv[i] = m - inv[m % i] * (m / i) % m;
            fact_inv[i] = fact_inv[i - 1] * inv[i] % m;
        }
        Self {
            fac: fac,
            fact_inv: fact_inv,
            inv: inv,
            com: None,
            m: m,
        }
    }
    pub fn fix_n(&mut self, n: usize) {
        let mut com = vec![0; n + 1];
        com[0] = 1;
        for i in 1..=n {
            com[i] = com[i - 1] * ((n - i + 1) * self.inv[i] % self.m) % self.m;
        }
        self.com = Some(com)
    }
    fn _calc_nck(&self, n: usize, k: usize) -> usize {
        if n < k {
            return 0;
        }
        let mut ans: usize = 1;
        let mut i = n;
        while n - k < i {
            ans *= i;
            ans %= self.m;
            i -= 1;
        }
        ans * self.fact_inv[k] % self.m
    }
    pub fn nck(&self, n: usize, k: usize) -> usize {
        match self.com.clone() {
            None => self._calc_nck(n, k),
            Some(x) => x[k],
        }
    }
    pub fn nhk(&self, n: usize, k: usize) -> usize {
        assert!(self.fact_inv.len() >= n + k - 1);
        self.nck(n + k - 1, k)
    }

    pub fn npk(&self, n: usize, k: usize) -> usize {
        return self.fac[n] * self.fact_inv[n-k] % self.m
    }
}
#[derive(Debug)]
pub struct ModInt<T> {
    v: T,
    m: T,
}
impl<T> ModInt<T>
where
    T: Copy,
{
    pub fn value(&self) -> T {
        self.v
    }
    pub fn modulo(&self) -> T {
        self.m
    }
}
impl<T> ModInt<T> {
    fn new_unchecked(v: T, modulo: T) -> Self {
        Self { v, m: modulo }
    }
}
impl<T> ModInt<T>
where
    T: Copy + RemAssign + PartialOrd,
{
    pub fn new(mut v: T, modulo: T) -> Self {
        if v >= modulo {
            v %= modulo;
        }
        Self::new_unchecked(v, modulo)
    }
}
impl<T> ModInt<T>
where
    T: Copy
        + Sub<Output = T>
        + ShrAssign
        + BitAnd<Output = T>
        + PartialEq
        + PartialOrd
        + Div<Output = T>
        + RemAssign,
    ModInt<T>: MulAssign,
{
    pub fn pow(self, e: T) -> Self {
        let zero = self.modulo() - self.modulo();
        let one = self.modulo() / self.modulo();
        let mut e = e;
        let mut result = Self::new_unchecked(one, self.modulo());
        let mut cur = self;
        while e > zero {
            if e & one == one {
                result *= cur;
            }
            e >>= one;
            cur *= cur;
        }
        result
    }
}
impl<T> Copy for ModInt<T> where T: Copy {}
impl<T> Clone for ModInt<T>
where
    T: Copy,
{
    fn clone(&self) -> Self {
        Self::new_unchecked(self.value(), self.modulo())
    }
}
impl<T> Add<T> for ModInt<T>
where
    T: AddAssign + SubAssign + RemAssign + Copy + PartialOrd,
{
    type Output = Self;
    fn add(self, mut rhs: T) -> Self::Output {
        if rhs >= self.modulo() {
            rhs %= self.modulo();
        }
        rhs += self.value();
        if rhs >= self.modulo() {
            rhs -= self.modulo();
        }
        Self::new_unchecked(rhs, self.modulo())
    }
}
impl<T> Sub<T> for ModInt<T>
where
    T: AddAssign + SubAssign + RemAssign + Copy + PartialOrd,
{
    type Output = Self;
    fn sub(self, mut rhs: T) -> Self::Output {
        if rhs >= self.modulo() {
            rhs %= self.modulo();
        }
        let mut result = self.value();
        result += self.modulo();
        result -= rhs;
        if result >= self.modulo() {
            result -= self.modulo();
        }
        Self::new_unchecked(result, self.modulo())
    }
}
impl<T> Mul<T> for ModInt<T>
where
    T: MulAssign + RemAssign + Copy + PartialOrd,
{
    type Output = Self;
    fn mul(self, mut rhs: T) -> Self::Output {
        if rhs >= self.modulo() {
            rhs %= self.modulo();
        }
        rhs *= self.value();
        rhs %= self.modulo();
        Self::new_unchecked(rhs, self.modulo())
    }
}
impl<T> Add<ModInt<T>> for ModInt<T>
where
    T: Copy,
    ModInt<T>: Add<T, Output = ModInt<T>>,
{
    type Output = Self;
    fn add(self, rhs: ModInt<T>) -> Self::Output {
        self + rhs.value()
    }
}
impl<T> Sub<ModInt<T>> for ModInt<T>
where
    T: Copy,
    ModInt<T>: Sub<T, Output = ModInt<T>>,
{
    type Output = Self;
    fn sub(self, rhs: ModInt<T>) -> Self::Output {
        self - rhs.value()
    }
}
impl<T> Mul<ModInt<T>> for ModInt<T>
where
    T: Copy,
    ModInt<T>: Mul<T, Output = ModInt<T>>,
{
    type Output = Self;
    fn mul(self, rhs: ModInt<T>) -> Self::Output {
        self * rhs.value()
    }
}
impl<T> Div<ModInt<T>> for ModInt<T>
where
    T: Copy,
    ModInt<T>: Div<T, Output = ModInt<T>>,
{
    type Output = Self;
    fn div(self, rhs: ModInt<T>) -> Self::Output {
        self / rhs.value()
    }
}
impl<T> AddAssign<T> for ModInt<T>
where
    T: Copy,
    ModInt<T>: Add<T, Output = ModInt<T>>,
{
    fn add_assign(&mut self, other: T) {
        *self = *self + other;
    }
}
impl<T> AddAssign<ModInt<T>> for ModInt<T>
where
    T: Copy,
    ModInt<T>: Add<ModInt<T>, Output = ModInt<T>>,
{
    fn add_assign(&mut self, other: ModInt<T>) {
        *self = *self + other;
    }
}
impl<T> SubAssign<T> for ModInt<T>
where
    T: Copy,
    ModInt<T>: Sub<T, Output = ModInt<T>>,
{
    fn sub_assign(&mut self, other: T) {
        *self = *self - other;
    }
}
impl<T> SubAssign<ModInt<T>> for ModInt<T>
where
    T: Copy,
    ModInt<T>: Sub<ModInt<T>, Output = ModInt<T>>,
{
    fn sub_assign(&mut self, other: ModInt<T>) {
        *self = *self - other;
    }
}
impl<T> DivAssign<T> for ModInt<T>
where
    T: Copy,
    ModInt<T>: Div<T, Output = ModInt<T>>,
{
    fn div_assign(&mut self, rhs: T) {
        *self = *self / rhs
    }
}
impl<T> DivAssign<ModInt<T>> for ModInt<T>
where
    T: Copy,
    ModInt<T>: Div<ModInt<T>, Output = ModInt<T>>,
{
    fn div_assign(&mut self, rhs: ModInt<T>) {
        *self = *self / rhs
    }
}
impl<T> MulAssign<T> for ModInt<T>
where
    T: Copy,
    ModInt<T>: Mul<T, Output = ModInt<T>>,
{
    fn mul_assign(&mut self, rhs: T) {
        *self = *self * rhs;
    }
}
impl<T> MulAssign<ModInt<T>> for ModInt<T>
where
    T: Copy,
    ModInt<T>: Mul<ModInt<T>, Output = ModInt<T>>,
{
    fn mul_assign(&mut self, rhs: ModInt<T>) {
        *self = *self * rhs;
    }
}
impl<T> Div<T> for ModInt<T>
where
    T: Copy
        + Add<Output = T>
        + Sub<Output = T>
        + Div<Output = T>
        + BitAnd<Output = T>
        + PartialEq
        + PartialOrd
        + SubAssign
        + ShrAssign
        + RemAssign
        + MulAssign,
{
    type Output = Self;
    fn div(self, mut rhs: T) -> Self::Output {
        if rhs >= self.modulo() {
            rhs %= self.modulo();
        }
        let one = self.modulo() / self.modulo();
        let two = one + one;
        self * Self::new_unchecked(rhs, self.modulo()).pow(self.modulo() - two)
    }
}


#[fastout]
fn solve() {
    const MOD: usize = 1_000_000_007;
    const INF: usize = std::usize::MAX;
    
    input!{
        n: usize, m: usize
    }

    let comb = Combination::new(2*std::cmp::max(n, m), MOD);
    if n == m {
        let ans: ModInt<usize> = ModInt::new(2, MOD) * ModInt::new(comb.npk(m, m), MOD) * ModInt::new(comb.npk(n, n), MOD);
        println!("{}", ans.value());
    } else if n == m - 1 || m == n - 1 {
        let ans: ModInt<usize> = ModInt::new(comb.npk(n, n), MOD) * ModInt::new(comb.npk(m, m), MOD);
        println!("{}", ans.value())
    } else {
        println!("0")
    }
}

fn main() {
    solve()
}

#[cfg(test)]
mod test {
    use super::solve;
}