#include <bits/stdc++.h>
#pragma GCC optimize(3, "Ofast", "inline")
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
bool Finish_read;
template <class T>
inline void read(T& x) {
  Finish_read = 0;
  x = 0;
  int f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    if (ch == EOF) return;
    ch = getchar();
  }
  while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
  x *= f;
  Finish_read = 1;
}
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6 + 11;
int N, A, B;
const int P = 998244353;
int get(int s) { return s > 1 ? 32 - __builtin_clz(s - 1) : 0; }
namespace NTT {
const long long G = 3;
long long qpow(long long b, long long p) {
  return !p ? 1 : qpow(b * b % P, p / 2) * (p & 1 ? b : 1) % P;
}
long long inv(long long b) { return qpow(b, P - 2); }
vector<long long> ntt(vector<long long>& a) {
  int n = a.size(), x = get(n);
  vector<long long> res, RES(n), roots(n);
  roots[0] = 1, roots[1] = qpow(G, (P - 1) / n);
  for (int i = (2); i < (n); i++) roots[i] = roots[i - 1] * roots[1] % P;
  res = a;
  for (int i = (1); i < (x + 1); i++) {
    int inc = n >> i;
    for (int j = 0; j < (inc); j++)
      for (int k = 0; k < n; k += inc) {
        int t = 2 * k % n + j;
        RES[k + j] = (res[t] + roots[k] * res[t + inc]) % P;
      }
    swap(res, RES);
  }
  return res;
}
vector<long long> ntt_rev(vector<long long>& a) {
  vector<long long> res = ntt(a);
  long long r = inv(a.size());
  for (int i = 0; i < (res.size()); i++) res[i] = res[i] * r % P;
  reverse(res.begin() + 1, res.end());
  return res;
}
vector<long long> brute(vector<long long>& a, vector<long long>& b) {
  vector<long long> c(a.size() + b.size() - 1);
  for (int i = 0; i < (a.size()); i++)
    for (int j = 0; j < (b.size()); j++)
      c[i + j] = (c[i + j] + a[i] * b[j]) % P;
  return c;
}
vector<long long> conv(vector<long long> a, vector<long long> b) {
  int s = a.size() + b.size() - 1, L = get(s), n = 1 << L;
  if (s <= 0) return {};
  a.resize(n);
  a = ntt(a);
  b.resize(n);
  b = ntt(b);
  for (int i = 0; i < (n); i++) a[i] = a[i] * b[i] % P;
  a = ntt_rev(a);
  a.resize(s);
  return a;
}
}  // namespace NTT
queue<vector<long long> > Q;
long long inv[maxn], fac[maxn], invf[maxn];
inline long long C(long long x, long long y) {
  return ((fac[x] * invf[y]) % P * invf[x - y]) % P;
}
void init() {
  invf[0] = inv[0] = inv[1] = fac[0] = fac[1] = 1;
  for (long long i = 1; i < maxn; i++) fac[i] = fac[i - 1] * i % P;
  for (int i = 2; i < maxn; i++) inv[i] = 1LL * (P - P / i) * inv[P % i] % P;
  for (int i = 1; i < maxn; i++) invf[i] = invf[i - 1] * inv[i] % P;
}
vector<long long> a = {1};
int main() {
  init();
  scanf("%d%d%d", &N, &A, &B);
  if (A + B - 2 > N - 1 || A == 0 || B == 0) {
    puts("0");
    return 0;
  }
  Q.push(a);
  a[0] = 0;
  a.push_back(1);
  for (int i = 0; i < N - 1; i++) a[0] = i, Q.push(a);
  while (Q.size() > 1) {
    vector<long long> p = Q.front();
    Q.pop();
    vector<long long> q = Q.front();
    Q.pop();
    Q.push(NTT::conv(p, q));
  }
  vector<long long> ans = Q.front();
  printf("%lld\n", ans[A + B - 2] * C(A + B - 2, A - 1) % P);
  return 0;
}
