// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;

#define ll long long

#define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)

#define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)

#define EREP(i,u) for(int i=start[u];i;i=e[i].next)

#define fi first

#define se second

#define mkr(a,b) make_pair(a,b)

#define SZ(A) ((int)A.size())

template<class T>inline void chkmin(T &a,T b){ if(a>b)a=b;}

template<class T>inline void chkmax(T &a,T b){ if(a<b)a=b;}

inline int read()

{

	int s=0,f=1;char ch=getchar();

	while(!isdigit(ch) && ch!='-')ch=getchar();

	if(ch=='-')ch=getchar(),f=-1;

	while(isdigit(ch))s=s*10+ch-'0',ch=getchar();

	return ~f?s:-s;

}



const int maxn=420;

const int mod=998244353;

inline int power(int a,int b)

{

	int ans=1;

	while(b)

	{

		if(b&1)ans=(ll)ans*a%mod;

		b>>=1;

		a=(ll)a*a%mod;

	}

	return ans;

}



int jc[maxn],jcn[maxn],inv[maxn];

inline void prepare()

{

	jc[0]=jc[1]=jcn[0]=jcn[1]=inv[1]=1;

	REP(i,2,400)jc[i]=(ll)i*jc[i-1]%mod,inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod,jcn[i]=(ll)jcn[i-1]*inv[i]%mod;

}



int n,a[maxn],b[maxn],sa,sainv,p[maxn];



inline void init()

{

	n=read();

	REP(i,1,n)a[i]=read(),b[i]=read(),sa+=a[i];

	sainv=power(sa,mod-2);

	REP(i,1,n)p[i]=(ll)a[i]*sainv%mod;

}



int dp[maxn][maxn];



inline void doing()

{

	dp[0][0]=1;

	REP(i,1,n)

	{

		DREP(j,400,0)DREP(k,400,0)if(dp[j][k])

		{

			int t=dp[j][k]; dp[j][k]=0;

			int xs=1;

			dp[j][k+a[i]]=(dp[j][k+a[i]]+t)%mod;

			REP(x,0,b[i]-1)

			{

				dp[j+x][k]=(dp[j+x][k]-(ll)t*xs%mod+mod)%mod;

				xs=(ll)xs*p[i]%mod*inv[x+1]%mod;

			}

		}

	}

	int ans=0;

	REP(j,0,400)REP(k,0,sa-1)if(dp[j][k])

	{

		int v=(ll)k*sainv%mod;

		int c=(mod-dp[j][k])%mod;

		ans=(ans+(ll)c*power(1-v+mod,mod-j-2)%mod*jc[j])%mod;

	}

	printf("%d\n",ans);

}



int main()

{

	prepare();

	init();

	doing();

	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.481767798890307x):
#include <bits/stdc++.h>



using namespace std;



namespace jumpmelon

{

	typedef long long big;



	const int P = 998244353;



	vector<int> operator*(const vector<int> &A, const vector<int> &B)

	{

		int n = (int)A.size(), m = (int)B.size();

		vector<int> R(n + m - 1);

		for (int i = 0; i < n; i++)

			for (int j = 0; j < m; j++)

				R[i + j] = int((R[i + j] + (big)A[i] * B[j]) % P);

		return R;

	}



	vector<int> operator+(const vector<int> &A, const vector<int> &B)

	{

		int n = (int)A.size(), m = (int)B.size();

		vector<int> R(max(n, m));

		for (int i = 0; i < n; i++)

			R[i] = A[i];

		for (int i = 0; i < m; i++)

			R[i] = (R[i] + B[i]) % P;

		return R;

	}



	int inv(int x) { return x == 1 ? 1 : int(big(P - P / x) * inv(P % x) % P); }



	const int MAXN = 400;

	int A[MAXN], B[MAXN];

	int Fac[MAXN + 1], InvFac[MAXN + 1];

	int S[MAXN + 1][MAXN + 1];

	int L[MAXN + 1];

	vector<int> G[MAXN + 1];



	int C(int n, int m) { return int((big)Fac[n] * InvFac[m] % P * InvFac[n - m] % P); }



	void work()

	{

		int n, s = 0;

		scanf("%d", &n);

		for (int i = 0; i < n; i++)

		{

			scanf("%d%d", &A[i], &B[i]);

			s += A[i];

		}

		Fac[0] = 1;

		for (int i = 1; i <= MAXN; i++)

			Fac[i] = int((big)Fac[i - 1] * i % P);

		InvFac[MAXN] = inv(Fac[MAXN]);

		for (int i = MAXN; i >= 1; i--)

			InvFac[i - 1] = int((big)InvFac[i] * i % P);

		G[0] = {1};

		int inv_s = inv(s);

		for (int i = 0, t = 0; i < n; i++)

		{

			int c = int((big)A[i] * inv_s % P);

			vector<int> V(B[i]);

			for (int j = 0, v = 1; j < B[i]; j++, v = int((big)v * c % P))

				V[j] = int(big(P - v) * InvFac[j] % P);

			t += A[i];

			for (int j = t; j >= 0; j--)

			{

				if (!G[j].empty())

					G[j] = G[j] * V;

				if (j >= A[i])

					G[j] = G[j] + G[j - A[i]];

			}

		}

		S[0][0] = 1;

		for (int i = 1; i <= MAXN; i++)

			for (int j = 1; j <= i; j++)

				S[i][j] = int((S[i - 1][j - 1] + big(i - 1) * S[i - 1][j]) % P);

		int ans = 0;

		for (int k = 0; k < (int)G[0].size(); k++)

			ans = int((ans + (big)G[0][k] * Fac[k]) % P);

		for (int d = 1; d < s; d++)

		{

			int c = int((big)d * inv_s % P), inv_c = inv(c);

			int vr = inv((1 + P - c) % P), vv = int((big)c * vr % P);

			L[0] = vr;

			for (int i = 1; i < (int)G[d].size(); i++)

			{

				L[i] = 0;

				for (int j = 0; j < i; j++)

					L[i] = int((L[i] + (big)vv * C(i, j) % P * L[j]) % P);

			}

			for (int k = 0, v = 1; k < (int)G[d].size(); k++, v = int((big)v * inv_c % P))

				for (int i = k, u = 1; i >= 0; i--, u = P - u)

					ans = int(

						(ans + (big)G[d][k] * v % P * S[k][i] % P * u % P * L[i]) % P);

		}

		printf("%d\n", (P - ans) % P);

	}

}



int main()

{

	jumpmelon::work();

	return 0;

}