// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;



typedef long long lint;

typedef long double louble;



template<typename T1,typename T2> inline T1 max(T1 a,T2 b){return a<b?b:a;}

template<typename T1,typename T2> inline T1 min(T1 a,T2 b){return a<b?a:b;}



namespace ae86

{

	const int bufl = 1<<15;

	

	char buf[bufl],*s=buf,*t=buf;

	

	inline int fetch()

	{

		if(s==t){t=(s=buf)+fread(buf,1,bufl,stdin);if(s==t)return EOF;}

		return *s++;

	}

	

	inline int ty()

	{

		int a=0,b=1,c=fetch();

		while(!isdigit(c))b^=c=='-',c=fetch();

		while(isdigit(c))a=a*10+c-48,c=fetch();

		return b?a:-a;

	}

}

using ae86::ty;



const int N = 400 , _ = N + 3 , mo = 998244353;



template<typename T1,typename T2> inline T1 ad(T1 &a,T2 b){return a=a+b>=mo?a+b-mo:a+b;}

template<typename T1,typename T2> inline T1 dl(T1 &a,T2 b){return a=a>=b?a-b:a-b+mo;}



inline lint powa(lint a,lint t)

{

	lint b=1;

	while(t){if(t&1)b=b*a%mo;a=a*a%mo,t>>=1;}

	return b;

}



inline lint inva(lint a)

{

	return powa(a,mo-2);

}



lint jc[_],rjc[_];



inline void fuck(int n=_-1)

{

	jc[0]=jc[1]=rjc[0]=1;

	for(int i=2;i<=n;i++)jc[i]=jc[i-1]*i%mo;

	rjc[n]=inva(jc[n]);

	for(int i=n-1;i>=1;i--)rjc[i]=rjc[i+1]*(1ll+i)%mo;

}



int n,lim[_];

lint f[_][_]={0},gai[_],sgai=0;



int main()

{

	n=ty();

	for(int i=1;i<=n;i++)gai[i]=ty(),lim[i]=ty(),sgai=(sgai+gai[i])%mo;

	

	fuck();

	f[0][0]=mo-1;

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

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

			for(int k=N;k>=0;k--)

				if(f[j][k])

					for(int a=0,x=1;a<lim[i];a++,x=1ll*x*gai[i]%mo)

						dl(f[j+gai[i]][k+a],f[j][k]*x%mo*rjc[a]%mo);

	lint ans=0;

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

		for(int j=0,perx=inva(i),x=sgai*inva(i)%mo;j<=N;j++,x=1ll*x*perx%mo)

			ad(ans,f[i][j]*jc[j]%mo*x%mo);

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



	return 0;

}


// Optimized solution to the same problem (faster):
// Written by newbiechd

#include <cstdio>

#include <cctype>

#include <cstring>

using namespace std;



const int BUF = 100003;

inline char getChar() {

  static char buf[BUF], *bufS, *bufT;

  if (bufS == bufT) {

    bufT = (bufS = buf) + fread(buf, 1, BUF, stdin);

    if (bufS == bufT) return EOF;

  }

  return *bufS++;

}

inline int read() {

  int f = 0;

  char ch;

  while (!isdigit(ch = getChar())) {}

  do f = f * 10 + (ch ^ 48);

  while (isdigit(ch = getChar()));

  return f;

}



const int maxN = 403, mod = 998244353;

int a[maxN], b[maxN], inv[maxN], fac[maxN], bin[maxN][maxN];

int p[maxN][maxN], temp[maxN][maxN];



inline int power(int x, int y) {

  int o = 1;

  while (y) {

    if (y & 1) o = 1ll * o * x % mod;

    x = 1ll * x * x % mod, y >>= 1;

  }

  return o;

}



int main() {

  int n = read(), i, j, k, t, A = 0, B = 0, ans = 0;

  for (i = 1; i <= n; ++i)

    A += a[i] = read(), b[i] = read();

  inv[1] = 1;

  for (i = 2; i < maxN; ++i)

    inv[i] = -1ll * (mod / i) * inv[mod % i] % mod;

  fac[0] = 1;

  for (i = 1; i < maxN; ++i)

    fac[i] = 1ll * fac[i - 1] * i % mod;

  k = power(A, mod - 2);

  for (i = 1; i <= n; ++i) {

    t = 1ll * k * a[i] % mod, bin[i][0] = 1;

    for (j = 1; j < b[i]; ++j)

      bin[i][j] = 1ll * bin[i][j - 1] * t % mod * inv[j] % mod;

  }

  

  p[0][0] = 1, A = 0;

  for (i = 1; i <= n; ++i) {

    for (j = 0; j <= A; ++j)

      for (k = 0; k <= B; ++k) {

        temp[j + a[i]][k] = (temp[j + a[i]][k] + p[j][k]) % mod;

        for (t = 0; t < b[i]; ++t)

          temp[j][k + t] = (-1ll * p[j][k] * bin[i][t] + temp[j][k + t]) % mod;

      }

    A += a[i], B += b[i];

    for (j = 0; j <= A; ++j) {

      memcpy(p[j], temp[j], sizeof(int) * B);

      memset(temp[j], 0, sizeof(int) * B);

    }

  }

  

  for (i = 0; i <= A; ++i)

    for (j = 0; j <= B; ++j)

      p[i][j] = -p[i][j];

  ++p[A][0];

  k = power(A, mod - 2);

  for (i = 0; i < A; ++i) {

    t = 1ll * k * i % mod;

    for (j = 0; j <= B; ++j)

      ans = (1ll * p[i][j] * fac[j] % mod * power(1 - t, mod - j - 2) + ans)

        % mod;

  }

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

  return 0;

}


// Fastest known solution for this problem: