#pragma region Include/Defines
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <limits.h>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <memory.h>
#include <string.h>
#include <math.h>
#include <string>
#include <algorithm>
#include <functional>
#include <cassert>
#include <map>
#include <set>
#include <iostream>
#include <queue>
#include <time.h>

using namespace std;
typedef long long lli;
typedef vector<int> vi;
typedef vector<lli> vli;
typedef pair<int, int> pii;
typedef pair<lli, lli> pll;
typedef vector<pii> vpii;
typedef vector <pll> vpll;
typedef long double ld;
#define all(a) std::begin(a), std::end(a)

const int INF = 0x3f3f3f3f;
const lli LINF = 0x3f3f3f3f3f3f3f3f;

template<typename T, typename T2> inline void _max(T &a, T2 b) { a = max((T)a, (T)b); }
template<typename T, typename T2> inline void _min(T &a, T2 b) { a = min((T)a, (T)b); }

#ifdef _DEBUG
#define epr(...) fprintf(stderr,__VA_ARGS__)
#else
#define epr(...) 
#endif
#pragma endregion

#pragma region Modular Arithmetic
int MOD = int(1e9) + 7;
inline int add(const int a, const int b, const int mod = MOD) { return (a + b >= mod) ? (a + b - mod) : (a + b); }
inline void _add(int &a, const int b, const int mod = MOD) { a = add(a, b, mod); }
inline int sub(const int a, const int b, const int mod = MOD) { return (a - b < 0) ? (a - b + mod) : (a - b); }
inline void _sub(int &a, const int b, const int mod = MOD) { a = sub(a, b, mod); }
inline int negate(const int a, const int mod = MOD) { return mod - a; }
inline int mul(const int a, const int b, const int mod = MOD) { return (a * 1ll * b) % mod; }
inline void _mul(int &a, const int b, const int mod = MOD) { a = mul(a, b, mod); }
int binPow(int b, lli p, const int mod = MOD) {
	int r = 1;
	while (p) {
		if (p & 1) r = mul(r, b, mod);
		b = mul(b, b, mod);
		p >>= 1;
	}
	return r;
}
int gcdex(int a, int b, int &x, int &y) {
	if (!b) return x = 1, y = 0, a;
	int px, py, res = gcdex(b, a % b, px, py);
	return x = py, y = px - a / b * py, res;
}
int inv(const int a, const int mod = MOD) { // a and mod must be coprime
	int x, y;
	int g = gcdex(a, mod, x, y);
	assert(g == 1);
	x = (x % mod + mod) % mod;
	return x;
}
inline int dvd(const int a, const int b, const int mod = MOD) { // b and mod must be coprime
	int rev = inv(b, mod);
	return mul(a, inv(b, mod), mod);
} // b != 0
inline void _dvd(int &a, const int b, const int mod = MOD) { a = dvd(a, b, mod); } // b and mod must be coprime
inline int convert(int x, const int mod = MOD) {
	int tx = x % mod + mod;
	return tx >= mod ? tx - mod : tx;
};
struct mNum {
	int x, m;
	mNum(int _x, int m = MOD) : x(convert(_x, m)), m(m) {}
	mNum(lli _x, int m = MOD) : x(convert(_x, m)), m(m) {}
};
mNum operator +(mNum a, mNum b) { return mNum(add(a.x, b.x, a.m), a.m); }
mNum operator -(mNum a, mNum b) { return mNum(sub(a.x, b.x, a.m), a.m); }
mNum operator *(mNum a, mNum b) { return mNum(mul(a.x, b.x, a.m), a.m); }
mNum operator /(mNum a, mNum b) { return mNum(dvd(a.x, b.x, a.m), a.m); }
mNum operator ^(mNum a, lli x) { return mNum(binPow(a.x, x, a.m), a.m); }
mNum operator +=(mNum &a, mNum b) { return a = a + b; }
mNum operator -=(mNum &a, mNum b) { return a = a - b; }
mNum operator *=(mNum &a, mNum b) { return a = a * b; }
mNum operator /=(mNum &a, mNum b) { return a = a / b; }
mNum operator ^=(mNum &a, lli x) { return a = a ^ x; }
#pragma endregion

const int MAX = 1e5 + 10;
int n, m;

void clear() {
}

void read() {
}

void solve() {
	int d = abs(n - m);
	if (d > 1) return void(printf("0\n"));
	int mu = d == 1 ? 1 : 2;
	int f[MAX] = { 0 };
	f[0] = 1;
	for (int i = 1; i <= max(n, m); i++) f[i] = mul(f[i - 1], i);
	int res = mul(mu, mul(f[n], f[m]));
	printf("%d\n", res);
}

int main() {
#ifdef _LOCAL_VAN
	freopen("in.txt", "r", stdin);
#endif
	while (scanf("%d%d", &n, &m) == 2) {
		clear();
		read();
		solve();
#ifndef _LOCAL_VAN
		return 0;
#endif
	}
	return 0;
}

Measured memory_bytes: 640