#include #include using namespace std; #define For(i, a, b) for(int i = (a); i < (b); i++) #define rep(i, n) For(i, 0, n) #define rFor(i, a, b) for(int i = (a); i >= (b); i--) #define ALL(v) (v).begin(), (v).end() #define rALL(v) (v).rbegin(), (v).rend() using lint = long long; using ld = long double; int INF = 2000000000; lint LINF = 1000000000000000000; using mint = atcoder::modint998244353; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int k; cin >> k; vector l(k), m(k); int n = 0; rep(i, k) { cin >> l[i] >> m[i]; n += l[i] * m[i]; } vector num; int sum = n; rep(i, k) { num.emplace_back(sum); num.emplace_back(l[i] * m[i]); num.emplace_back(sum - l[i] * m[i]); sum -= l[i] * m[i]; } rep(i, k) { int rest = l[i] * m[i]; rep(_, m[i]) { num.emplace_back(rest); num.emplace_back(l[i]); num.emplace_back(rest - l[i]); rest -= l[i]; } num.emplace_back(m[i]); } sort(ALL(num)); num.erase(unique(ALL(num)), num.end()); map Fac, Finv; Fac[0] = Fac[1] = 1; Finv[0] = Finv[1] = 1; mint now = 1; int mx = num.back(); int cur = 0; while (num[cur] < 2) { cur++; } for (int i = 2; i <= mx; i++) { now *= mint(i); if (cur < (int)num.size() && num[cur] == i) { Fac[i] = now; Finv[i] = now.inv(); cur++; } } auto comb = [&](int n, int k) -> mint { return Fac[n] * Finv[k] * Finv[n - k]; }; mint ans = 1; sum = n; rep(i, k) { ans *= comb(sum, l[i] * m[i]); sum -= l[i] * m[i]; } rep(i, k) { int rest = l[i] * m[i]; rep(_, m[i]) { ans *= comb(rest, l[i]); rest -= l[i]; } ans /= Fac[m[i]]; } cout << ans.val() << "\n"; }