#include #include #include #include #include #include #include #include #include #include using namespace std; using i64 = int64_t; // using u64 = uint64_t; template using VV = vector>; #define REP(i, n) for(i64 i = 0; i < i64(n); i++) #define REP1(i, n) for(i64 i = 1; i <= i64(n); i++) i64 INF = 100100100100100L; i64 direct[8][2] = { {1, 0}, {0, -1}, {-1, 0}, {0, 1}, {1, -1}, {-1, -1}, {-1, 1}, {1, 1} }; template ostream &operator<<(ostream &os, pair p); template ostream &operator<<(ostream &os, const vector &v) { for(i64 i = 0; i < i64(v.size()); i++) { if (i > 0) os << ' '; os << v[i]; } return os; } template ostream &operator<<(ostream &os, const set &st) { bool first = true; for(const T &it: st) if (first) { first = false; os << it; } else{ os << ' ' << it; } return os; } template ostream &operator<<(ostream &os, map &mp) { bool first = true; for(const auto &[f, l]: mp) if (first) { first = false; os << '{' << f << "-> " << l << '}'; } else{ os << ", {" << f << "-> " << l << '}'; } return os; } template ostream &operator<<(ostream &os, pair p) { os << '{' << p.first << ", " << p.second << '}'; return os; } #include using namespace atcoder; using mint = modint998244353; vector fact; vector inv_fact; const i64 FACT_MAX = 200'010; void get_fact() { fact.resize(FACT_MAX + 1); inv_fact.resize(FACT_MAX + 1); fact[0] = 1; fact[1] = 1; for(i64 i = 2; i <= FACT_MAX; i++) fact[i] = fact[i - 1] * i; inv_fact[FACT_MAX] = mint(1) / fact[FACT_MAX]; for(i64 i = FACT_MAX; i >= 2; i--) inv_fact[i - 1] = inv_fact[i] * i; } mint nCr(i64 n, i64 r) { if (r == 0 || n == r) return 1; if (r > n || r < 0) return 0; return fact[n] * inv_fact[n - r] * inv_fact[r]; } int main() { string N; cin >> N; vector a(10, 0); for(char it: N) a[it - '0']++; get_fact(); i64 rest = N.size(); mint ans = nCr(rest - 1, a[0]); rest -= a[0]; for(i64 i = 1; i <= 9; i++) { ans *= nCr(rest, a[i]); rest -= a[i]; } cout << ans.val() << endl; return 0; }