Language: C++

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Random;
import java.util.Scanner;

class BIT {
	long bit[] = new long[0];
	int N = 0;

	BIT(int n) {
		bit = new long[n + 1];
		N = n;
	}

	void add(int a, long w) {
		for (int x = a; x < N; x += (x & -x))
			bit[x] += w;
	}

	long sum(int a) {
		long ret = 0;
		for (int x = a; x > 0; x -= x & -x)
			ret += bit[x];
		return ret;
	}

	long modsum(int a, int mod) {
		long ret = 0;
		for (int x = a; x > 0; x -= x & -x) {
			ret += bit[x];
			ret %= mod;
		}
		return ret;
	}
}
class MODBIT {
	long bit[] = new long[0];
	int N = 0;
	int mod=0;
	MODBIT(int n,int m) {
		bit = new long[n + 1];
		N = n;
		mod=m;
	}

	void add(int a, long w) {
		for (int x = a; x < N; x += (x & -x)) {
			bit[x] += w;
			bit[x] %= mod;
		}
	}

	long modsum(int a, long mod2) {
		long ret = 0;
		for (int x = a; x > 0; x -= x & -x) {
			ret += bit[x];
			ret %= mod2;
		}
		return ret;
	}
}

class FastScanner {
	private final InputStream in = System.in;
	private final byte[] buffer = new byte[1024];
	private int ptr = 0;
	private int buflen = 0;

	private boolean hasNextByte() {
		if (ptr < buflen) {
			return true;
		} else {
			ptr = 0;
			try {
				buflen = in.read(buffer);
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (buflen <= 0) {
				return false;
			}
		}
		return true;
	}

	private int readByte() {
		if (hasNextByte())
			return buffer[ptr++];
		else
			return -1;
	}

	private static boolean isPrintableChar(int c) {
		return 33 <= c && c <= 126;
	}

	public boolean hasNext() {
		while (hasNextByte() && !isPrintableChar(buffer[ptr]))
			ptr++;
		return hasNextByte();
	}

	public String next() {
		if (!hasNext())
			throw new NoSuchElementException();
		StringBuilder sb = new StringBuilder();
		int b = readByte();
		while (isPrintableChar(b)) {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	public long nextLong() {
		if (!hasNext())
			throw new NoSuchElementException();
		long n = 0;
		boolean minus = false;
		int b = readByte();
		if (b == '-') {
			minus = true;
			b = readByte();
		}
		if (b < '0' || '9' < b) {
			throw new NumberFormatException();
		}
		while (true) {
			if ('0' <= b && b <= '9') {
				n *= 10;
				n += b - '0';
			} else if (b == -1 || !isPrintableChar(b)) {
				return minus ? -n : n;
			} else {
				throw new NumberFormatException();
			}
			b = readByte();
		}
	}

	public int nextInt() {
		long nl = nextLong();
		if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE)
			throw new NumberFormatException();
		return (int) nl;
	}

	public double nextDouble() {
		return Double.parseDouble(next());
	}

	public char nextchar() {
		return next().charAt(0);
	}
}

class UnionFind {
	int Parent[];

	UnionFind(int n) {// Initialize by -1
		Parent = new int[n];
		Arrays.fill(Parent, -1);
	}

	int root(int A) {// In which tree is A?
		if (Parent[A] < 0)
			return A;
		return Parent[A] = root(Parent[A]);
	}

	int size(int A) {// size of tree which is include A
		return -Parent[root(A)];
	}

	boolean connect(int A, int B) {// Connect A and B
		A = root(A);
		B = root(B);
		if (A == B)
			return false;
		if (size(A) < size(B)) {
			int C = 0;
			C = B;
			B = A;
			A = C;
		} // SWAP
		Parent[A] += Parent[B];
		Parent[B] = A;
		return true;
	}
}

class Pair<T, E> {
	public T first;
	public E second;

	void set(T x, E y) {
		first = x;
		second = y;
	}
}

class Pint {
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Pint) {
			Pint other = (Pint) obj;
			return other.first == this.first && other.second == this.second;
		}
		return false;
	}

	@Override
	public int hashCode() {
		return Objects.hash(this.first, this.second);
	}

	public int first;
	public int second;

	Pint(int x, int y) {
		first = x;
		second = y;
	}

	void set(int x, int y) {
		first = x;
		second = y;
	}
}

class Tpair {
	public int first;
	public int second;
	public long third;

	Tpair(int x, int y, long z) {
		first = x;
		second = y;
		third = z;
	}

	void set(int x, int y, long z) {
		first = x;
		second = y;
		third = z;
	}
}
class Comb{
	int N=0;
	int mod=0;
	long fact[],ifact[],inv[];
	Comb(int n,int m){
		N=n;
		mod=m;
		fact=new long[N+10];
		ifact=new long[N+10];
		inv=new long[N+10];
		inv[1] = 1;
		for (int i = 2; i < N; i++) inv[i] = 1l * (mod - mod / i) * inv[mod % i] % mod;
		fact[0] = ifact[0] = 1;
		for (int i = 1; i < N; i++) {
			fact[i] = 1l * fact[i - 1] * i % mod;
			ifact[i] = 1l * ifact[i - 1] * inv[i] % mod;
		}
	}
	public long C(int x,int y,long mod) {
		if (x < 0 || y < 0 || x < y) return 0;
		return 1l * fact[x] * ifact[y] % mod * ifact[x - y] % mod;
	}
}
public class Main {
	static FastScanner scan = new FastScanner();
	static Scanner scanner = new Scanner(System.in);
	static Random rand = new Random();
	static int mod = 1000000007;
	static double eps = 1.0E-14;
	static int big = Integer.MAX_VALUE;
	static double PI = 3.141592653589793;

	static long modlcm(long a, long b) {
		return a * b * modinv(GCD(a, b), mod);
	}

	static long GCD(long a, long b) {
		return b > 0 ? GCD(b, a % b) : a;
	}

	static long lcm(long a, long b) {
		return a * b / GCD(a, b);
	}

	static int min(int a, int b) {
		return a < b ? a : b;
	}

	static long factorial(int i) {
		return i == 1 ? 1 : i * factorial(i - 1);
	}

	static int max(int... i) {
		int x = i[0];
		for (int e : i)
			x = Math.max(x, e);
		return x;
	}

	static int min(int... i) {
		int x = i[0];
		for (int e : i)
			x = Math.min(x, e);
		return x;
	}

	static long gcd(long... i) {
		long x = i[0];
		for (long e : i)
			x = GCD(x, e);
		return x;
	}

	static long lmax(long... i) {
		long x = i[0];
		for (long e : i)
			x = Math.max(x, e);
		return x;
	}

	static long lmin(long... i) {
		long x = i[0];
		for (long e : i)
			x = Math.min(x, e);
		return x;
	}

	static long nCr(long n, long r, long m) {
		long ans = 1;
		for (long i = 0; i < r; i++) {
			ans *= (n - i);
			ans %= m;
		}
		for (long i = 0; i <= r; i++) {
			ans *= modinv(i, m);
			ans %= mod;
		}
		return ans;
	}

	static int lower_bound(long[] b, long cost) {
		int ok = b.length;
		int ng = -1;
		while (Math.abs(ok - ng) > 1) {
			int mid = (ok + ng) / 2;
			if (b[mid] >= cost)
				ok = mid;
			else
				ng = mid;
		}
		return ok;
	}

	static int upper_bound(int[] b, int cost) {
		int ok = b.length;
		int ng = -1;
		while (Math.abs(ok - ng) > 1) {
			int mid = (ok + ng) / 2;
			if (b[mid] > cost)
				ok = mid;
			else
				ng = mid;
		}
		return ok;
	}

	static boolean isPrime(long n) {
		if (n == 2)
			return true;
		if (n < 2 || n % 2 == 0)
			return false;
		double d = Math.sqrt(n);
		for (int i = 3; i <= d; i += 2)
			if (n % i == 0) {
				return false;
			}
		return true;
	}

	static int upper_division(int a, int b) {
		if (a % b == 0) {
			return a / b;
		} else {
			return a / b + 1;
		}
	}

	static long lupper_division(long a, long b) {
		if (a % b == 0) {
			return a / b;
		} else {
			return a / b + 1;
		}
	}

	static int[] setArray(int a) {
		int b[] = new int[a];
		for (int i = 0; i < a; i++) {
			b[i] = scan.nextInt();
		}
		return b;
	}

	static long[] lsetArray(int a) {
		long b[] = new long[a];
		for (int i = 0; i < a; i++) {
			b[i] = scan.nextLong();
		}
		return b;
	}

	static String reverse(String str) {
		char ch[] = new char[str.length()];
		char chch[] = str.toCharArray();
		int a = str.length();
		for (int i = 0; i < upper_division(a, 2); i++) {
			ch[i] = chch[ch.length - i - 1];
			ch[ch.length - 1 - i] = chch[i];
		}
		return String.valueOf(ch);
	}

	public static void printArray(int[] que) {
		for (int i = 0; i < que.length - 1; i++) {
			System.out.print(que[i] + " ");
		}
		System.out.println(que[que.length - 1]);
	}

	public static void lprintArray(long[] que) {
		for (int i = 0; i < que.length - 1; i++) {
			System.out.print(que[i] + " ");
		}
		System.out.println(que[que.length - 1]);
	}

	public static int[][] doublesort(int[][] a) {
		Arrays.sort(a, (x, y) -> Integer.compare(x[0], y[0]));
		return a;
	}

	public static long[][] ldoublesort(long[][] a) {
		Arrays.sort(a, (x, y) -> Long.compare(x[0], y[0]));
		return a;
	}

	static long modpow(long x, long n, long mo) {
		long sum = 1;
		while (n > 0) {
			if ((n & 1) == 1) {
				sum = sum * x % mo;
			}
			x = x * x % mo;
			n >>= 1;
		}
		return sum;
	}

	public static char[] revch(char ch[]) {
		char ret[] = new char[ch.length];
		for (int i = ch.length - 1, j = 0; i >= 0; i--, j++) {
			ret[j] = ch[i];
		}
		return ret;
	}

	public static int[] revint(int ch[]) {
		int ret[] = new int[ch.length];
		for (int i = ch.length - 1, j = 0; i >= 0; i--, j++) {
			ret[j] = ch[i];
		}
		return ret;
	}

	public static void warshall_floyd(long v[][]) {
		int n = v[0].length;
		for (int k = 0; k < n; k++)
			for (int i = 0; i < n; i++)
				for (int j = 0; j < n; j++)
					v[i][j] = lmin(v[i][j], v[i][k] + v[k][j]);
	}

	public static long modinv(long a, long m) {
		long b = m, u = 1, v = 0;
		while (b != 0) {
			long t = a / b;
			a -= t * b;
			long x = a;
			a = b;
			b = x;
			u -= t * v;
			x = u;
			u = v;
			v = x;
		}
		u %= m;
		if (u < 0)
			u += m;
		return u;
	}

	public static long lmod(long i, long j) {
		return (i % j) < 0 ? (i % j) + 0 + (j < 0 ? -j : j) : (i % j + 0);
	}

	public static int next_combination(int sub) {
		int x = sub & -sub, y = sub + x;
		return (((sub & ~y) / x) >> 1) | y;
	}
	public static void main(String[] $) throws IOException {
		mod=998244353;
		Comb comb=new Comb(500400,mod);
		int n=scan.nextInt();
		int m=scan.nextInt();
		long ans=0;
		for(int r=m;r>=n&&r>=m-r;r--) {
			int f=(r==(m-r))?1:0;
			ans = (ans + (comb.C(m - f, r,mod) - comb.C(m - f, 2 * r - n + 1,mod) + mod) % mod) % mod;
		}
		System.out.println(ans);
	}
}

Compiler output:
a.cc:206:9: error: stray '@' in program
  206 |         @Override
      |         ^
a.cc:215:9: error: stray '@' in program
  215 |         @Override
      |         ^
a.cc:1:1: error: 'import' does not name a type
    1 | import java.io.IOException;
      | ^~~~~~
a.cc:1:1: note: C++20 'import' only available with '-fmodules-ts'
a.cc:2:1: error: 'import' does not name a type
    2 | import java.io.InputStream;
      | ^~~~~~
a.cc:2:1: note: C++20 'import' only available with '-fmodules-ts'
a.cc:3:1: error: 'import' does not name a type
    3 | import java.util.Arrays;
      | ^~~~~~
a.cc:3:1: note: C++20 'import' only available with '-fmodules-ts'
a.cc:4:1: error: 'import' does not name a type
    4 | import java.util.NoSuchElementException;
      | ^~~~~~
a.cc:4:1: note: C++20 'import' only available with '-fmodules-ts'
a.cc:5:1: error: 'import' does not name a type
    5 | import java.util.Objects;
      | ^~~~~~
a.cc:5:1: note: C++20 'import' only available with '-fmodules-ts'
a.cc:6:1: error: 'import' does not name a type
    6 | import java.util.Random;
      | ^~~~~~
a.cc:6:1: note: C++20 'import' only available with '-fmodules-ts'
a.cc:7:1: error: 'import' does not name a type
    7 | import java.util.Scanner;
      | ^~~~~~
a.cc:7:1: note: C++20 'import' only available with '-fmodules-ts'
a.cc:10:14: error: flexible array member 'BIT::bit' not at end of 'class BIT'
   10 |         long bit[] = new long[0];
      |              ^~~
a.cc:38:2: error: expected ';' after class definition
   38 | }
      |  ^
      |  ;
a.cc:10:14: error: initializer for flexible array member 'long int BIT::bit []'
   10 |         long bit[] = new long[0];
      |              ^~~
a.cc: In constructor 'BIT::BIT(int)':
a.cc:14:17: error: invalid use of array with unspecified bounds
   14 |                 bit = new long[n + 1];
      |                 ^~~
a.cc: At global scope:
a.cc:40:14: error: flexible array member 'MODBIT::bit' not at end of 'class MODBIT'
   40 |         long bit[] = new long[0];
      |              ^~~
a.cc:64:2: error: expected ';' after class definition
   64 | }
      |  ^
      |  ;
a.cc:40:14: error: initializer for flexible array member 'long int MODBIT::bit []'
   40 |         long bit[] = new long[0];
      |              ^~~
a.cc: In constructor 'MODBIT::MODBIT(int, int)':
a.cc:44:17: error: invalid use of array with unspecified bounds
   44 |                 bit = new long[n + 1];
      |                 ^~~
a.cc: At global scope:
a.cc:67:16: error: expected ':' before 'final'
   67 |         private final InputStream in = System.in;
      |                ^~~~~~
      |                :
a.cc:67:17: error: 'final' does not name a type
   67 |         private final InputStream in = System.in;
      |                 ^~~~~
a.cc:68:16: error: expected ':' before 'final'
   68 |         private final byte[] buffer = new byte[1024];
      |                ^~~~~~
      |                :
a.cc:68:17: error: 'final' does not name a type
   68 |         private final byte[] buffer = new byte[1024];
      |                 ^~~~~
a.cc:69:16: error: expected ':' before 'int'
   69 |         private int ptr = 0;
      |                ^~~~
      |                :
a.cc:70:16: error: expected ':' before 'int'
   70 |         private int buflen = 0;
      |                ^~~~
      |                :
a.cc:72:16: error: expected ':' before 'boolean'
   72 |         private boolean hasNextByte() {
      |                ^~~~~~~~
      |                :
a.cc:72:17: error: 'boolean' does not name a type; did you mean 'bool'?
   72 |         private boolean hasNextByte() {
      |                 ^~~~~~~
      |                 bool
a.cc:89:16: error: expected ':' before 'int'
   89 |         private int readByte() {
      |                ^~~~
      |                :
a.cc:96:16: error: expected ':' before 'static'
   96 |         private static boolean isPrintableChar(int c) {
      |                ^~~~~~~
      |                :
a.cc:96:24: error: 'boolean' does not name a type; did you mean 'bool'?
   96 |         private static boolean isPrintableChar(int c) {
      |                        ^~~~~~~
      |                        bool
a.cc:100:15: error: expected ':' before 'boolean'
  100 |         public boolean hasNext() {
      |               ^~~~~~~~
      |               :
a.cc:100:16: error: 'boolean' does not name a type; did you mean 'bool'?
  100 |         public boolean hasNext() {
      |                ^~~~~~~
      |                bool
a.cc:106:15: error: expected ':' before 'String'
  106 |         public String next() {
      |               ^~~~~~~
      |               :
a.cc:106:16: error: 'String' does not name a type
  106 |         public String next() {
      |                ^~~~~~
a.cc:118:15: error: expected ':' before 'long'
  118 |         public long nextLong() {
      |               ^~~~~
      |               :
a.cc:144:15: error: expected ':' before 'int'
  144 |         public int nextInt() {
      |               ^~~~
      |               :
a.cc:151:15: error: expected ':' before 'double'
  151 |         public double nextDouble() {
      |               ^~~~~~~
      |               :
a.cc:155:15: error: expected ':' before 'char'
  155 |         public char nextchar() {
      |               ^~~~~
      |               :
a.cc:158:2: error: expected ';' after class definition
  158 | }
      |  ^
      |  ;
a.cc: In member function 'int FastScanner::readByte()':
a.cc:90:21: error: 'hasNextByte' was not declared in this scope
   90 |                 if (hasNextByte())
      |                     ^~~~~~~~~~~
a.cc:91:32: error: 'buffer' was not declared in this scope; did you mean 'buflen'?
   91 |                         return buffer[ptr++];
      |                                ^~~~~~
      |                                buflen
a.cc: In member function 'long int FastScanner::nextLong()':
a.cc:119:22: error: 'hasNext' was not declared in this scope
  119 |                 if (!hasNext())
      |                      ^~~~~~~
a.cc:120:35: error: expected type-specifier before 'NoSuchElementException'
  120 |                         throw new NoSuchElementException();
      |                                   ^~~~~~~~~~~~~~~~~~~~~~
a.cc:122:17: error: 'boolean' was not declared in this scope; did you mean 'bool'?
  122 |                 boolean minus = false;
      |                 ^~~~~~~
      |                 bool
a.cc:125:25: error: 'minus' was not declared in this scope
  125 |                         minus = true;
      |                         ^~~~~
a.cc:129:35: error: expected type-specifier before 'NumberFormatException'
  129 |                         throw new NumberFormatException();
      |                                   ^~~~~~~~~~~~~~~~~~~~~
a.cc:135:48: error: 'isPrintableChar' was not declared in this scope
  135 |                         } else if (b == -1 || !isPrintableChar(b)) {
      |                                                ^~~~~~~~~~~~~~~
a.cc:136:40: error: 'minus' was not declared in this scope
  136 |                                 return minus ? -n : n;
      |                                        ^~~~~
a.cc:138:43: error: expected type-specifier before 'NumberFormatException'
  138 |                                 throw new NumberFormatException();
      |                                           ^~~~~~~~~~~~~~~~~~~~~
a.cc: In member function 'int FastScanner::nextInt()':
a.cc:146:26: error: 'Integer' was not declared in this scope
  146 |                 if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE)
      |                          ^~~~~~~
a.cc:147:35: error: expected type-specifier before 'NumberFormatException'
  147 |                         throw new NumberFormatException();
      |                                   ^~~~~~~~~~~~~~~~~~~~~
a.cc: In member function 'double FastScanner::nextDouble()':
a.cc:152:24: error: 'Double' was not declared in this scope; did you mean 'double'?
  152 |                 return Double.parseDouble(next());
      |                        ^~~~~~
      |                        double
a.cc:152:43: error: 'next' was not declared in this scope; did you mean 'nextInt'?
  152 |                 return Double.parseDouble(next());
      |                                           ^~~~
      |                                           nextInt
a.cc: In member function 'char FastScanner::nextchar()':
a.cc:156:24: error: 'next' was not declared in this scope; did you mean 'nextInt'?
  156 |                 return next().charAt(0);
      |                        ^~~~
      |                        nextInt
a.cc: At global scope:
a.cc:178:9: error: 'boolean' does not name a type; did you mean 'bool'?
  178 |         boolean connect(int A, int B) {// Connect A and B
      |         ^~~~~~~
      |         bool
a.cc:161:13: error: flexible array member 'UnionFind::Parent' in an otherwise empty 'class UnionFind'
  161 |         int Parent[];
      |             ^~~~~~
a.cc:193:2: error: expected ';' after class definition
  193 | }
      |  ^
      |  ;
a.cc: In constructor 'UnionFind::UnionFind(int)':
a.cc:164:17: error: invalid use of array with unspecified bounds
  164 |                 Parent = new int[n];
      |                 ^~~~~~
a.cc:165:17: error: 'Arrays' was not declared in this scope
  165 |                 Arrays.fill(Parent, -1);
      |                 ^~~~~~
a.cc: At global scope:
a.cc:195:7: error: 'Pair' is not a class template
  195 | class Pair<T, E> {
      |       ^~~~
a.cc:195:12: error: 'T' was not declared in this scope
  195 | class Pair<T, E> {
      |            ^
a.cc:195:15: error: 'E' was not declared in this scope
  195 | class Pair<T, E> {
      |               ^
a.cc:196:15: error: expected ':' before 'T'
  196 |         public T first;
      |               ^~
      |               :
a.cc:196:16: error: 'T' does not name a type
  196 |         public T first;
      |                ^
a.cc:197:15: error: expected ':' before 'E'
  197 |         public E second;
      |               ^~
      |               :
a.cc:197:16: error: 'E' does not name a type
  197 |         public E second;
      |