from __future__ import division, print_function
import os
import sys
from io import BytesIO, IOBase
def powmin2(x, r):
return pow(x, r - 2, r)
def comb(m, n, k):
res = 1
for i in range(n):
res = (res * (m - i)) % k
pro_mod = 1
for i in range(2, n + 1):
pro_mod = (pro_mod * i) % k
return (res * powmin2(pro_mod, k)) % k
def main():
n, m = map(int, input().split())
if n == 2:
print(0)
else:
print(
(comb(m, n - 1, 998244353) * (n - 2) * pow(2, n - 3, 998244353)) % 998244353
)
BUFSIZE = 8192
class FastIO(IOBase):
newlines = 0
def __init__(self, file):
self._file = 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")
def print(*args, **kwargs):
sep, file = kwargs.pop("sep", " "), kwargs.pop("file", sys.stdout)
at_start = True
for x in args:
if not at_start:
file.write(sep)
file.write(str(x))
at_start = False
file.write(kwargs.pop("end", "\n"))
if kwargs.pop("flush", False):
file.flush()
sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")
if __name__ == "__main__":
main()
// C++ program to find the nCr%p based on optimal Dynamic Programming implementation
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lli long long int
// Returns (val1 * val2) % mod
ll moduloMultiplication(ll val1, ll val2,ll mod)
{
// Initialize the result
ll ans = 0;
// Update val1 if it is greater than or equal to mod
val1 %= mod;
while (val2) {
// If val2 is odd, add a with result
if (val2 & 1)
ans = (ans + val1) % mod;
// Here we assume that doing 2*val1 doesn't cause overflow
val1 = (2 * val1) % mod;
val2 = val2/2;
}
return ans;
}
// C++ function for extended Euclidean Algorithm
lli gcdExtended(lli val1, lli val2,lli* xx,lli* yy);
// Function to find modulo inverse of val2 if inverse does not exist it returns -1
lli modInverse(lli val2, lli mod)
{
// used in extended GCD algorithm
lli xx, yy;
lli g = gcdExtended(val2, mod, &xx, &yy);
// Return -1 if val2 and mod are not co-prime
if (g != 1)return -1;
// mod is added to handle negative xx
return (xx % mod + mod) % mod;
}
// Function for extended Euclidean Algorithm to find modular inverse.
lli gcdExtended(lli val1, lli val2,lli* xx,lli* yy)
{
// Base Case
if (val1 == 0) {
*xx = 0, *yy = 1;
return val2;
}
// To store results of recursive call
lli x1, y1;
lli gcd = gcdExtended(val2 % val1, val1, &x1, &y1);
// Update xx and yy using results of recursive call
*xx = y1 - (val2 / val1) * x1;
*yy = x1;
return gcd;
}
// Function to compute val1/val2 under modlo mod
lli modDivide(lli val1, lli val2,lli mod)
{
val1 = val1 % mod;
lli inv = modInverse(val2, mod);
if (inv == -1)
// Divison not defined
return 0;
else
return (inv * val1) % mod;
}
// Function to calculate nCr % p
int computencr(int n, int r, int x)
{
// Base case this case is not possible
if (r > n)
return 0;
// For larger r optimization need to be done
if (r > n - r)
r = n - r;
// ans stores the current result
lli ans = 1;
for (int i = 1; i <= r; i++) {
/*
Derived formula for calculating the result is
C(n,r-1)*(n-r+1)/r
this Function calculates ans*(n-i+1) % x.
*/
ans = moduloMultiplication(ans, (n + 1 - i), x);
// Function calculates ans/i % x
ans = modDivide(ans, i, x);
}
return ans;
}
int main()
{
lli n,m,x=998244353;
cin>>n>>m;
// Compute nCr % x
lli ans= computencr(m, n-1, x);
ans=(ans*(n-2))%x;
for(int i=1;i<=n-3;i++) ans=(ans*2)%x;
cout<<ans<<endl;
return 0;
}
1351. Count Negative Numbers in a Sorted Matrix | 617. Merge Two Binary Trees |
1450. Number of Students Doing Homework at a Given Time | 700. Search in a Binary Search Tree |
590. N-ary Tree Postorder Traversal | 589. N-ary Tree Preorder Traversal |
1299. Replace Elements with Greatest Element on Right Side | 1768. Merge Strings Alternately |
561. Array Partition I | 1374. Generate a String With Characters That Have Odd Counts |
1822. Sign of the Product of an Array | 1464. Maximum Product of Two Elements in an Array |
1323. Maximum 69 Number | 832. Flipping an Image |
1295. Find Numbers with Even Number of Digits | 1704. Determine if String Halves Are Alike |
1732. Find the Highest Altitude | 709. To Lower Case |
1688. Count of Matches in Tournament | 1684. Count the Number of Consistent Strings |
1588. Sum of All Odd Length Subarrays | 1662. Check If Two String Arrays are Equivalent |
1832. Check if the Sentence Is Pangram | 1678. Goal Parser Interpretation |
1389. Create Target Array in the Given Order | 1313. Decompress Run-Length Encoded List |
1281. Subtract the Product and Sum of Digits of an Integer | 1342. Number of Steps to Reduce a Number to Zero |
1528. Shuffle String | 1365. How Many Numbers Are Smaller Than the Current Number |