— This is not playing but duty as allies of justice, Nii-chan!

— Not allies but justice itself, Onii-chan!

With hands joined, go everywhere at a speed faster than our thoughts! This time, the Fire Sisters — Karen and Tsukihi — is heading for somewhere they've never reached — water-surrounded islands!

There are three clusters of islands, conveniently coloured red, blue and purple. The clusters consist of a, b and c distinct islands respectively.

Bridges have been built between some (possibly all or none) of the islands. A bridge bidirectionally connects two different islands and has length 1. For any two islands of the same colour, either they shouldn't be reached from each other through bridges, or the shortest distance between them is at least 3, apparently in order to prevent oddities from spreading quickly inside a cluster.

The Fire Sisters are ready for the unknown, but they'd also like to test your courage. And you're here to figure out the number of different ways to build all bridges under the constraints, and give the answer modulo 998 244 353. Two ways are considered different if a pair of islands exist, such that there's a bridge between them in one of them, but not in the other.


-----Input-----

The first and only line of input contains three space-separated integers a, b and c (1 ≤ a, b, c ≤ 5 000) — the number of islands in the red, blue and purple clusters, respectively.


-----Output-----

Output one line containing an integer — the number of different ways to build bridges, modulo 998 244 353.


-----Examples-----
Input
1 1 1

Output
8

Input
1 2 2

Output
63

Input
1 3 5

Output
3264

Input
6 2 9

Output
813023575



-----Note-----

In the first example, there are 3 bridges that can possibly be built, and no setup of bridges violates the restrictions. Thus the answer is 2^3 = 8.

In the second example, the upper two structures in the figure below are instances of valid ones, while the lower two are invalid due to the blue and purple clusters, respectively. [Image]

Difficulty: MEDIUM_HARD
Tags: Dynamic programming

Combinatorics

Mathematics
Skill types: Dynamic programming

Starter code:

Solutions:
def f1(a, x):
	if x == 0:
		return 1
	p = f1(a, x // 2)
	p *= p
	p %= 998244353
	if x % 2:
		p *= a
		p %= 998244353
	return p % 998244353

def f(a, b):
	if a > b:
		(a, b) = (b, a)
	ans = 0
	k = 1
	for i in range(a + 1):
		ans = (ans + k) % 998244353
		k = k * (a - i) * (b - i) * f1(i + 1, 998244353 - 2) % 998244353
	return ans
(a, b, c) = map(int, input().split())
ans = f(a, b) * f(b, c) * f(a, c) % 998244353
print(ans)


mod = 998244353
maxn = 1005

def solve(n, m):
	if n > m:
		(n, m) = (m, n)
	(ans, s) = (0, 1)
	for i in range(0, n + 1):
		ans = ans + s
		s = s * (n - i) // (i + 1) * (m - i)
	return ans
while True:
	try:
		(a, b, c) = map(int, input().split())
		print(solve(a, b) * solve(a, c) * solve(b, c) % mod)
	except:
		break


mod = 998244353

def binpow(num, p):
	if p == 0:
		return 1
	if p % 2 == 0:
		return binpow(num * num % mod, p // 2)
	return num * binpow(num, p - 1) % mod

def rev(num):
	return binpow(num, mod - 2)

def solve(a, b):
	result = 1
	prev = 1
	for k in range(1, min(a, b) + 1):
		now = prev * (a - (k - 1)) * (b - (k - 1)) * rev(k) % mod
		result = (result + now) % mod
		prev = now
	return result % mod
(a, b, c) = list(map(int, input().split()))
res1 = solve(a, b)
res2 = solve(b, c)
res3 = solve(a, c)
print(res1 * res2 * res3 % mod)


(a, b, c) = list(map(int, input().split(' ')))
p = 998244353

def calc(a, b):
	if a > b:
		(a, b) = (b, a)
	ans = 0
	tmp = 1
	for i in range(a + 1):
		ans = (ans + tmp) % p
		tmp = tmp * (a - i) * (b - i) * pow(i + 1, p - 2, p) % p
	return ans
ans = calc(a, b) * calc(b, c) * calc(a, c) % p
print(ans)


def calcop(a, b):
	t = 1
	p = 1
	for i in range(0, min(a, b)):
		p *= (a - i) * (b - i)
		p //= i + 1
		t += p
	return t
(a, b, c) = map(int, input().split())
f = 998244353
ans = calcop(a, b) * calcop(b, c) * calcop(c, a) % f
print(ans)


import math
import collections
import bisect
import heapq
import time
import random
t0 = time.time()
(a, b, c) = map(int, input().split())

def ct(a, b):
	if a > b:
		(a, b) = (b, a)
	L = 998244353
	s = 1
	sx = 1
	for k in range(1, a + 1):
		s = s * (a + 1 - k) * (b + 1 - k) // k
		sx += s % L
	return sx
L = 998244353
print(ct(a, b) * ct(a, c) * ct(b, c) % L)


def gcd(a, b):
	if b == 0:
		return (a, 1, 0)
	(d, x_, y_) = gcd(b, a % b)
	return (d, y_, x_ - a // b * y_)
(a, b, c) = map(int, input().split())
r = 0
f = [1]
g = []
for i in range(1, 5005):
	f.append(f[-1] * i % 998244353)
g = [gcd(i, 998244353)[1] for i in f]
for i in range(min(a, b) + 1):
	r += f[a] * g[i] * g[a - i] * f[b] * g[b - i] % 998244353
h = 0
for i in range(min(a, c) + 1):
	h += f[a] * g[i] * g[a - i] * f[c] * g[c - i] % 998244353
v = 0
for i in range(min(c, b) + 1):
	v += f[c] * g[i] * g[c - i] * f[b] * g[b - i] % 998244353
print(r * h * v % 998244353)


import sys
import time
mod = 998244353

def calc(a, b):
	if a < b:
		(a, b) = (b, a)
	s = 0
	t = 1
	for i in range(b + 1):
		s = s + t
		t = t * (a - i) // (i + 1) * (b - i)
	return s
(a, b, c) = list(map(int, sys.stdin.readline().split()))
start = time.time()
print(calc(a, b) * calc(b, c) * calc(c, a) % mod)
end = time.time()


(a, b, c) = map(int, input().split())
MOD = 998244353
factorials = [1]
ans = 1
temp = 1
for i in range(1, 5001):
	temp = temp * i % MOD
	factorials.append(temp)
inverses = []
for i in range(5001):
	inverses.append(pow(factorials[i], MOD - 2, MOD))
tmp = 0
for n in range(0, min(a, b) + 1):
	tmp = (tmp + factorials[a] * factorials[b] * inverses[n] * inverses[b - n] * inverses[a - n]) % MOD
ans = ans * tmp % MOD
tmp = 0
for n in range(0, min(a, c) + 1):
	tmp = (tmp + factorials[a] * factorials[c] * inverses[n] * inverses[c - n] * inverses[a - n]) % MOD
ans = ans * tmp % MOD
tmp = 0
for n in range(0, min(c, b) + 1):
	tmp = (tmp + factorials[c] * factorials[b] * inverses[n] * inverses[b - n] * inverses[c - n]) % MOD
ans = ans * tmp % MOD
print(ans)


def swap(a, b):
	temp = a
	a = b
	b = temp

def cc(a, b):
	if a > b:
		swap(a, b)
	k = 1
	ans = 0
	for i in range(a + 1):
		ans = (ans + k) % m
		k = k * (a - i) * (b - i) * pow(i + 1, m - 2, m) % m
	return ans
(a, b, c) = map(int, input().split())
m = 998244353
print(cc(a, b) * cc(b, c) * cc(a, c) % m)


def schet(a, b):
	MOD = 998244353
	if a > b:
		(a, b) = (b, a)
	ans = 0
	k = 1
	for i in range(a + 1):
		ans = (ans + k) % MOD
		k = k * (a - i) * (b - i) * pow(i + 1, MOD - 2, MOD) % MOD
	return ans
(a, b, c) = map(int, input().split())
MOD = 998244353
ans = schet(a, b) * schet(b, c) * schet(a, c) % MOD
print(ans)


def invmod(x, m):
	return pow(x, m - 2, m)

def nchoose(n, m):
	nchoose = [1]
	for i in range(n):
		nchoose.append(nchoose[-1] * (n - i) * invmod(i + 1, m) % m)
	return nchoose

def fact(n, m):
	fact = [1]
	for i in range(n):
		fact.append(fact[-1] * (i + 1) % m)
	return fact
X = [int(x) for x in input().split(' ')]
ans = 1
m = 998244353
f = fact(max(X), m)
for i in range(3):
	for j in range(i + 1, 3):
		xci = nchoose(X[i], m)
		xcj = nchoose(X[j], m)
		c = 0
		for k in range(min(X[i], X[j]) + 1):
			c = (c + xci[k] * xcj[k] % m * f[k]) % m
		ans = ans * c % m
print(ans)


(a, b, c) = list(map(int, input().split(' ')))
MOD = 998244353

def d(a, b):
	s = 1
	for i in range(a, b + 1):
		s *= i
		s %= MOD
	return s

def cnk(n, k):
	s = 1
	for i in range(n - k + 1, n + 1):
		s *= i
	for i in range(1, k + 1):
		s /= i
	return s

def factorial(n):
	s = 1
	for i in range(1, n + 1):
		s *= i
	return s

def pow(a, b):
	c = 1
	while b > 0:
		if b % 2 == 0:
			b //= 2
			a *= a
			a %= MOD
		else:
			b -= 1
			c *= a
			c %= MOD
	return c

def inv(i):
	return pow(i, MOD - 2)
fi = [1, 1]

def sp(n, m):
	s = 1
	d1 = 1
	d2 = 1
	for i in range(1, n + 1):
		d1 *= n - i + 1
		d2 *= m - i + 1
		d1 %= MOD
		d2 %= MOD
		s += d1 * d2 * (fi[i] % MOD)
		s %= MOD
	return s
s = 1
for i in range(2, max(a, max(b, c)) + 1):
	s *= i
	s %= MOD
	fi.append(inv(s))
print(sp(a, b) * sp(a, c) * sp(b, c) % MOD)


(a, b, c) = list(map(int, input().split()))
md = 998244353

def solve(x, y, z):
	res1 = 0
	res2 = 0
	res3 = 0
	(a, b, c) = sorted([x, y, z])
	(tmpA, tmpB, tmpC, tmpK) = (1, 1, 1, 1)
	for k in range(a + 1):
		d = pow(tmpK, md - 2, md)
		res1 += tmpA * tmpB * d % md
		res2 += tmpA * tmpC * d % md
		tmpA *= a - k
		tmpA %= md
		tmpB *= b - k
		tmpB %= md
		tmpC *= c - k
		tmpC %= md
		tmpK *= k + 1
		tmpK %= md
		res1 = res1 % md
		res2 = res2 % md
	(tmpB, tmpC, tmpK) = (1, 1, 1)
	for k in range(b + 1):
		d = pow(tmpK, md - 2, md)
		res3 += tmpB * tmpC * d % md
		tmpB *= b - k
		tmpB %= md
		tmpC *= c - k
		tmpC %= md
		tmpK *= k + 1
		tmpK %= md
		res3 = res3 % md
	return res1 * res2 * res3 % md
res = solve(a, b, c) % 998244353
print(res)


import math
f = 998244353

def matchings(a, b):
	m = max(a, b)
	n = min(a, b)
	t = 1
	p = 1
	for i in range(0, n):
		p *= (n - i) * (m - i)
		p //= i + 1
		t += p
	t = t % f
	return t
inputs = [int(x) for x in input().split(' ')]
k = matchings(inputs[0], inputs[1]) * matchings(inputs[0], inputs[2]) * matchings(inputs[2], inputs[1]) % f
print(k)


import math
f = 998244353

def calc(a, b):
	m = max(a, b)
	n = min(a, b)
	t = 1
	p = 1
	for i in range(0, n):
		p *= (n - i) * (m - i)
		p //= i + 1
		t += p
	t = t % f
	return t
(a, b, c) = map(int, input().split())
ans = calc(a, b) * calc(b, c) * calc(c, a) % f
print(ans)


mod = 998244353

def cmb(n, r):
	if r < 0 or r > n:
		return 0
	return g1[n] * g2[r] * g2[n - r] % mod
g1 = [1, 1]
g2 = [1, 1]
inv = [0, 1]
for i in range(2, 10003):
	g1.append(g1[-1] * i % mod)
	inv.append(-inv[mod % i] * (mod // i) % mod)
	g2.append(g2[-1] * inv[-1] % mod)
(A, B, C) = map(int, input().split())
x = 0
for i in range(B + 1):
	x += cmb(A, i) * cmb(B, i) * g1[i]
z = 0
for j in range(C + 1):
	z += cmb(A, j) * cmb(C, j) * g1[j] % mod
y = 0
for k in range(B + 1):
	y += cmb(B, k) * cmb(C, k) * g1[k] % mod
print(x * y * z % mod)


mod = 998244353
f = [1]
for i in range(1, 5010):
	f += [f[i - 1] * i % mod]

def powmod(n, k):
	if k == 0:
		return 1
	res = powmod(n, k // 2)
	res *= res
	res %= mod
	if k % 2:
		res *= n
		res %= mod
	return res

def inv(n):
	return powmod(n, mod - 2)

def c(n, k):
	return f[n] * inv(f[n - k]) % mod * inv(f[k]) % mod

def match(a, b):
	res = 0
	for i in range(min(a, b) + 1):
		res += c(a, i) * c(b, i) * f[i] % mod
		res %= mod
	return res
(n, m, k) = list(map(int, input().split()))
print(match(n, m) * match(n, k) * match(m, k) % mod)


f = [1] * 50001
mod = 998244353
for i in range(1, 5001):
	f[i] = f[i - 1] * i % mod
(a, b, c) = (int(i) for i in input().split())

def pwr(b, e):
	if b == 0:
		return 0
	if e == 0:
		return 1
	if e % 2 == 0:
		z = pwr(b, e / 2) % mod
		return z * z % mod
	return b * pwr(b, e - 1) % mod

def nCr(n, r):
	den = f[r] * f[n - r] % mod
	return f[n] * pwr(den, mod - 2) % mod

def g(x, y):
	mn = min([x, y])
	sm = 0
	global mod
	for i in range(0, mn + 1):
		sm += nCr(x, i) * nCr(y, i) * f[i] % mod
		sm = sm % mod
	return sm
ans = g(a, b) * g(b, c) * g(c, a)
ans = ans % mod
print(int(ans))


(a, b, c) = map(int, input().split())
M = 998244353

def calc(a, b):
	if a > b:
		(a, b) = (b, a)
	ans = 0
	t = 1
	for i in range(a + 1):
		ans = (ans + t) % M
		t = t * (a - i) * (b - i) * pow(i + 1, M - 2, M) % M
	return ans
ans = calc(a, b) * calc(b, c) * calc(a, c) % M
print(ans)


import sys
input = sys.stdin.readline
abc = list(map(int, input().split()))
a = min(abc)
c = max(abc)
b = sum(abc) - a - c

def comb(n, r, mod):
	if r < 0 or r > n:
		return 0
	return g1[n] * g2[r] * g2[n - r] % mod
mod = 998244353
N = 10 ** 5
g1 = [1, 1]
g2 = [1, 1]
inv = [0, 1]
for i in range(2, N + 1):
	g1.append(g1[-1] * i % mod)
	inv.append(-inv[mod % i] * (mod // i) % mod)
	g2.append(g2[-1] * inv[-1] % mod)
(bc, ab, ca) = (0, 0, 0)
for k in range(b + 1):
	bc += comb(c, k, mod) * comb(b, k, mod) * g1[k] % mod
	bc %= mod
for l in range(a + 1):
	ab += comb(b, l, mod) * comb(a, l, mod) * g1[l] % mod
	ab %= mod
for m in range(a + 1):
	ca += comb(a, m, mod) * comb(c, m, mod) * g1[m] % mod
	ca %= mod
print(ab * bc * ca % mod)


m = 998244353
n = 5050
mi = [1] * n
for i in range(2, n):
	mi[i] = -(m // i) * mi[m % i] % m
f = [1] * n
g = [1] * n
for i in range(2, n):
	f[i] = f[i - 1] * i % m
	g[i] = g[i - 1] * mi[i] % m

def calc(x, y):
	s = 1
	p = f[x] * f[y]
	for i in range(1, min(x, y) + 1):
		den = g[i] * g[x - i] * g[y - i]
		s += p * den % m
	return s
(a, b, c) = map(int, input().split())
ans = calc(a, b) * calc(b, c) * calc(c, a) % m
print(ans)


MOD = 998244353

def w(a, b):
	(rt, ca, cb, fl) = (1, 1, 1, 1)
	for k in range(1, min(a, b) + 1):
		fl = fl * k % MOD
		ca = ca * (a - k + 1) // k
		cb = cb * (b - k + 1) // k
		rt = (rt + ca % MOD * (cb % MOD) % MOD * fl % MOD) % MOD
	return rt
(a, b, c) = map(int, input().split())
print(w(a, b) % MOD * w(b, c) % MOD * w(c, a) % MOD)


(a, b, c) = map(int, input().split())
d = 998244353

def f(x, y):
	(s, t) = (0, 1)
	for i in range(min(x, y) + 1):
		s = (s + t) % d
		t = t * (x - i) * (y - i) * pow(i + 1, d - 2, d) % d
	return s
print(f(a, b) * f(a, c) * f(b, c) % d)


import math

def fpow(x, y, p):
	if y < 0:
		return 1 / fpow(x, -y, p)
	elif y == 0:
		return 1
	elif y % 2 == 0:
		return fpow(x * x % p, y // 2, p)
	else:
		return x % p * fpow(x % p, y - 1, p) % p

def c(n, k):
	global fact
	return fact[n] * fpow(fact[k] * fact[n - k], mod - 2, mod) % mod
mod = 998244353
fact = [1] * 5005
for i in range(1, 5005):
	fact[i] = fact[i - 1] * i % mod
(r, g, p) = map(int, input().split())
pr = 1
su = 0
for k in range(0, min(r, g) + 1):
	su += c(r, k) * c(g, k) * fact[k]
pr *= su
su = 0
for k in range(0, min(p, g) + 1):
	su += c(p, k) * c(g, k) * fact[k]
pr *= su
su = 0
for k in range(0, min(r, p) + 1):
	su += c(r, k) * c(p, k) * fact[k]
pr *= su
print(pr % mod)


(a, b, c) = map(int, input().split())
ans = 0
mod = 998244353
fact = [1]
z = max(a, b, c)
for i in range(1, z + 1):
	fact.append(fact[-1] * i % mod)
z = min(a, b)
ans1 = 0

def power(i, a, b):
	return pow(i, a, b)
for i in range(z + 1):
	ans1 = (ans1 + fact[a] * fact[b] * power(fact[i], mod - 2, mod) * power(fact[i], mod - 2, mod) * power(fact[a - i], mod - 2, mod) * power(fact[b - i], mod - 2, mod) * fact[i] % mod) % mod
z = min(b, c)
ans2 = 0
for i in range(z + 1):
	ans2 = (ans2 + fact[c] * fact[b] * power(fact[i], mod - 2, mod) * power(fact[i], mod - 2, mod) * power(fact[c - i], mod - 2, mod) * power(fact[b - i], mod - 2, mod) * fact[i] % mod) % mod
z = min(a, c)
ans3 = 0
for i in range(z + 1):
	ans3 = (ans3 + fact[c] * fact[a] * power(fact[i], mod - 2, mod) * power(fact[i], mod - 2, mod) * power(fact[c - i], mod - 2, mod) * power(fact[a - i], mod - 2, mod) * fact[i] % mod) % mod
print(ans1 * ans2 * ans3 % mod)


(a, b, c) = map(int, input().split())
M = 998244353

def C(x, y):
	(z, t) = (0, 1)
	for i in range(min(x, y) + 1):
		z += t
		t *= (x - i) * (y - i) * pow(i + 1, M - 2, M) % M
	return z
print(C(a, b) * C(a, c) * C(b, c) % M)


def extendedEuclidean(a, b, x, y):
	if b == 0:
		return (a, 1, 0)
	(d, x1, y1) = extendedEuclidean(b, a % b, x, y)
	(x, y) = (y1, x1 - y1 * (a // b))
	return (d, x, y)
(a, b, c) = map(int, input().split())
f = [1] * (1 + max(a, b, c))
fi = [1] * (1 + max(a, b, c))
m = 998244353
for i in range(1, 1 + max(a, b, c)):
	x = f[i - 1] * i % m
	f[i] = x
	(d, x, y) = extendedEuclidean(x, m, 1, 1)
	fi[i] = x % m
ab = 0
bc = 0
ca = 0
for i in range(min(a, b) + 1):
	ab += f[a] * fi[a - i] * f[b] * fi[b - i] * fi[i] % m
for i in range(min(b, c) + 1):
	bc += f[c] * fi[c - i] * f[b] * fi[b - i] * fi[i] % m
for i in range(min(a, c) + 1):
	ca += f[a] * fi[a - i] * f[c] * fi[c - i] * fi[i] % m
print(ab * bc * ca % m)


import os
import sys
from io import BytesIO, IOBase

def make_nCr_mod(max_n=2 * 10 ** 5, mod=10 ** 9 + 7):
	max_n = min(max_n, mod - 1)
	(fact, inv_fact) = ([0] * (max_n + 1), [0] * (max_n + 1))
	fact[0] = 1
	for i in range(max_n):
		fact[i + 1] = fact[i] * (i + 1) % mod
	inv_fact[-1] = pow(fact[-1], mod - 2, mod)
	for i in reversed(range(max_n)):
		inv_fact[i] = inv_fact[i + 1] * (i + 1) % mod

	def nCr_mod(n, r):
		res = 1
		while n or r:
			(a, b) = (n % mod, r % mod)
			if a < b:
				return 0
			res = res * fact[a] % mod * inv_fact[b] % mod * inv_fact[a - b] % mod
			n //= mod
			r //= mod
		return res
	return nCr_mod
ncr = make_nCr_mod(10000, 998244353)
fact = None
mod = 998244353

def ans(a: int, b: int) -> int:
	if a > b:
		(a, b) = (b, a)
	ret = 0
	for i in range(a + 1):
		ret += ncr(a, i) * ncr(b, i) * fact[i]
	return ret

def main():
	global ncr, fact, mod
	fact = [1]
	for i in range(1, 10000):
		fact.append(i * fact[-1] % mod)
	ncr = make_nCr_mod(10000, 998244353)
	(a, b, c) = map(int, input().split())
	print(ans(a, b) * ans(b, c) * ans(a, c) % mod)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self, **kwargs):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
main()


def calc(x, y):
	(si, ans) = (1, 1)
	(n, m) = (min(x, y), max(x, y))
	for i in range(1, n + 1):
		si = si * (n - i + 1) * (m - i + 1) // i
		ans = ans + si
	return ans % MOD
MOD = 998244353
(a, b, c) = list(map(int, input().split()))
rb = calc(a, b)
rp = calc(a, c)
bp = calc(b, c)
res = rb * rp * bp % MOD
print(res)


import sys, math as mt
import heapq as hp
import collections as cc
import bisect as bi
import math as mt
import itertools as it
input = sys.stdin.readline
I = lambda : list(map(int, input().split()))
mod = 998244353

def ncr(n, r, mod=998244353):
	temp = 1
	tem = min(n - r, r)
	while r:
		temp = temp * n % mod * pow(r, mod - 2, mod) % mod
		n -= 1
		r -= 1
	return temp

def ans(a, b):
	if a < b:
		(a, b) = (b, a)
	temp = 0
	an = 1
	for i in range(b + 1):
		temp += an
		an = an * (a - i) // (i + 1) * (b - i)
	return temp
(a, b, c) = sorted(I())
print(ans(a, b) * ans(b, c) * ans(c, a) % mod)


def cal(x, n):
	ans = 1
	sum1 = x
	while n > 0:
		if n & 1:
			ans = ans * sum1 % MON
		n >>= 1
		sum1 = sum1 * sum1 % MON
MON = 998244353
N = 5000 + 20

def pecal():
	fact[0] = 1
	rfact[0] = 1
	for i in range(1, N):
		fact[i] = fact[i - 1] * i % MON
		rfact[i] = pow(fact[i], MON - 2, MON)
	return None

def cal(a, i):
	return fact[a] * rfact[a - i] % MON * rfact[i] % MON

def solve(x, y):
	ans = 0
	k = min(x, y)
	for i in range(k + 1):
		ans += cal(x, i) * cal(y, i) % MON * fact[i] % MON
	return ans
(a, b, c) = [int(x) for x in input().split(' ')]
fact = [0] * N
rfact = [0] * N
pecal()
ans = solve(a, b) * solve(a, c) % MON * solve(b, c) % MON
print(ans)


import os, sys, atexit
from io import BytesIO, StringIO
input = BytesIO(os.read(0, os.fstat(0).st_size)).readline
_OUTPUT_BUFFER = StringIO()
sys.stdout = _OUTPUT_BUFFER

@atexit.register
def write():
	sys.__stdout__.write(_OUTPUT_BUFFER.getvalue())
f = [1] * 5003
M = 998244353
for i in range(1, 5003):
	f[i] = i % M * f[i - 1] % M % M

def ncr(n, r):
	t1 = f[n]
	t2 = f[r] % M * f[n - r] % M % M
	return t1 * pow(t2, M - 2, M)
(a, b, c) = map(int, input().split())
ans = 1

def func(a, b):
	global ans
	M = 998244353
	if a > b:
		(a, b) = (b, a)
	count = 0
	for i in range(a + 1):
		t1 = ncr(a, i) % M
		t2 = f[b] * pow(f[b - i], M - 2, M) % M
		count += t1 * t2 % M
	ans = ans % M * (count % M) % M
func(a, b)
func(b, c)
func(c, a)
print(int(ans))


(a, b, c) = map(int, input().split())
N = max(a, b, c)
mod = 998244353

def mul(a, b):
	return a * b % mod
from itertools import accumulate
fact = [1] + list(accumulate(range(1, N + 1), mul))
rfact = [0] * (N + 1)
rfact[-1] = pow(fact[-1], mod - 2, mod)
for i in range(N - 1, -1, -1):
	rfact[i] = mul(rfact[i + 1], i + 1)

def C(n, k):
	return mul(mul(fact[n], rfact[k]), rfact[n - k])

def get(x, y):
	ans = 0
	for n in range(min(x, y) + 1):
		ans += mul(mul(C(x, n), C(y, n)), fact[n])
	return ans
print(mul(mul(get(a, b), get(a, c)), get(b, c)))


def ncr(n, r):
	return fact[n] * pow(fact[n - r] * fact[r] % mod, mod - 2, mod) % mod

def calc(a, b):
	count = 1
	count += a * b
	for i in range(2, min(a, b) + 1):
		count = (count + ncr(a, i) * ncr(b, i) * fact[i]) % mod
	return count
mod = 998244353
fact = [1, 1]
for i in range(2, 5001):
	fact.append(fact[-1] * i % mod)
(a, b, c) = map(int, input().split())
x1 = calc(a, b)
x2 = calc(b, c)
x3 = calc(a, c)
print(x1 * x2 * x3 % mod)


import os
import sys
import math
from io import BytesIO, IOBase
from fractions import Fraction
import collections
from itertools import permutations
from collections import defaultdict
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
mod = 998244353
f = [1]
for i in range(1, 5010):
	f += [f[i - 1] * i % mod]

def powmod(n, k):
	if k == 0:
		return 1
	res = powmod(n, k // 2)
	res *= res
	res %= mod
	if k % 2:
		res *= n
		res %= mod
	return res

def inv(n):
	return powmod(n, mod - 2)

def c(n, k):
	return f[n] * inv(f[n - k]) % mod * inv(f[k]) % mod

def match(a, b):
	res = 0
	for i in range(min(a, b) + 1):
		res += c(a, i) * c(b, i) * f[i] % mod
		res %= mod
	return res
(n, m, k) = list(map(int, input().split()))
print(match(n, m) * match(n, k) * match(m, k) % mod)


MOD = 998244353

def getAns(a, b):
	if a < b:
		(a, b) = (b, a)
	s = 0
	total = 1
	for i in range(b + 1):
		s = s + total
		total = total * (a - i) // (i + 1) * (b - i)
	return s
x = [int(i) for i in input().split()]
x.sort()
print(getAns(x[2], x[1]) * getAns(x[1], x[0]) * getAns(x[2], x[0]) % MOD)


def comb(n, r):
	if r > n or r < 0:
		return 0
	return fact[n] * inv_fact[r] * inv_fact[n - r] % mod
mod = 998244353
fact = [1, 1]
inv_fact = [1, 1]
inv = [0, 1]
for i in range(2, 10003):
	fact.append(fact[-1] * i % mod)
	inv.append(-inv[mod % i] * (mod // i) % mod)
	inv_fact.append(inv_fact[-1] * inv[-1] % mod)
(r, b, p) = map(int, input().split())
(ans1, ans2, ans3) = (0, 0, 0)
for i in range(r + 1):
	ans1 += comb(r, i) * comb(b, i) * fact[i] % mod
for i in range(r + 1):
	ans2 += comb(r, i) * comb(p, i) * fact[i] % mod
for i in range(b + 1):
	ans3 += comb(b, i) * comb(p, i) * fact[i] % mod
print(ans1 * ans2 * ans3 % mod)


def pwm(a, pw, mod):
	ans = 1
	while pw:
		if pw & 1:
			ans *= a
			ans %= mod
		a *= a
		pw >>= 1
		a %= mod
	return ans

def precalc(mod):
	rfact[0] = 1
	for i in range(1, 5432):
		fact[i] = fact[i - 1] * i % mod
		rfact[i] = pwm(fact[i], mod - 2, mod)

def cnk(n, k, mod):
	return fact[n] * rfact[k] * rfact[n - k] % mod

def calc(a, b, mod):
	ans = 0
	for k in range(min(a, b) + 1):
		ans += cnk(a, k, mod) * cnk(b, k, mod) * fact[k]
		ans %= mod
	return ans
fact = [1] * 5432
rfact = [0] * 5432
mod = 998244353
precalc(mod)
(a, b, c) = (int(z) for z in input().split())
res = calc(a, b, mod) * calc(a, c, mod) * calc(b, c, mod)
res %= mod
print(res)


(a, b, c) = [int(i) for i in input().split()]
n = max(a, b, c) + 1
mod = 998244353
f = [0] * (n + 1)
f[0] = 1
for i in range(1, n + 1):
	f[i] = f[i - 1] * i % mod

def f_pow(a, k):
	if k == 0:
		return 1
	if k % 2 == 1:
		return f_pow(a, k - 1) * a % mod
	else:
		return f_pow(a * a % mod, k // 2) % mod

def C(n, k):
	d = f[k] * f[n - k] % mod
	return f[n] * f_pow(d, mod - 2) % mod
(ans, cur) = (1, 0)
for i in range(min(a, b) + 1):
	cur += C(a, i) * C(b, i) * f[i]
	cur %= mod
(ans, cur) = (ans * cur % mod, 0)
for i in range(min(b, c) + 1):
	cur += C(b, i) * C(c, i) * f[i]
	cur %= mod
(ans, cur) = (ans * cur % mod, 0)
for i in range(min(a, c) + 1):
	cur += C(a, i) * C(c, i) * f[i]
	cur %= mod
print(ans * cur % mod)


from sys import stdin
M = 998244353

def bridges(x, y):
	(bridges_number, current_term) = (0, 1)
	for bn in range(min(x, y) + 1):
		bridges_number += current_term
		current_term *= (x - bn) * (y - bn) * pow(bn + 1, M - 2, M) % M
	return bridges_number
(a, b, c) = map(int, stdin.readline().split())
print(bridges(a, b) * bridges(b, c) * bridges(c, a) % M)


(a, b, c) = map(int, input().split())
mod = 998244353

def cal(x, y):
	(ans, tmp) = (1, 1)
	for k in range(1, min(x, y) + 1):
		tmp = tmp * (x - k + 1) * (y - k + 1) // k
		ans = ans + tmp
	return ans % mod
print(cal(a, b) * cal(b, c) * cal(c, a) % mod)


import math
mod = 998244353
factmod = [0] * 5001
factmod[0] = 1
for i in range(1, 5001):
	factmod[i] = factmod[i - 1] * i % mod

def nCk(n, k):
	if n == a:
		return aCks[k]
	if n == b:
		return bCks[k]
	if n == c:
		return cCks[k]
	xxx

def calc(x, y):
	global mod
	(x, y) = (min(x, y), max(x, y))
	sm = 0
	for i in range(x + 1):
		sm += nCk(x, i) % mod * (nCk(y, i) % mod) * (factmod[i] % mod)
		sm = sm % mod
	return sm
(a, b, c) = list(map(int, input().split()))
aCks = [1] * (a + 1)
for i in range(1, a):
	aCks[i] = aCks[i - 1] * (a - i + 1) // i
aCks = [aCks[i] % mod for i in range(len(aCks))]
bCks = [1] * (b + 1)
for i in range(1, b):
	bCks[i] = bCks[i - 1] * (b - i + 1) // i
bCks = [bCks[i] % mod for i in range(len(bCks))]
cCks = [1] * (c + 1)
for i in range(1, c):
	cCks[i] = cCks[i - 1] * (c - i + 1) // i
cCks = [cCks[i] % mod for i in range(len(cCks))]
print(calc(a, b) * calc(b, c) * calc(a, c) % mod)


(a, b, c) = map(int, input().split())
mod = 998244353
ab = 0
fac = [1] * 5001

def modinv(a):
	global mod
	return pow(a, mod - 2, mod)
modiv = [0] * 5001
for i in range(2, 5001):
	fac[i] = fac[i - 1] * i % mod
for i in range(5001):
	modiv[i] = modinv(fac[i])

def ncr(n, r):
	global modiv, fac
	ans = 1
	ans = fac[n]
	ans *= modiv[n - r]
	ans *= modiv[r]
	return ans % mod
for i in range(min(a, b) + 1):
	ab += ncr(a, i) * ncr(b, i) * fac[i]
bc = 0
for i in range(min(c, b) + 1):
	bc += ncr(c, i) * ncr(b, i) * fac[i]
ac = 0
for i in range(min(a, c) + 1):
	ac += ncr(a, i) * ncr(c, i) * fac[i]
print(ab * bc * ac % mod)