#include <cstdio>
#include <cstring>

const int MAXN =1e3+20, MAXV =1e5+20, M =998244353;

/*------------------------------IO------------------------------*/

namespace IO_base{
	const int MAXB =1<<10;
	char gbuf[MAXB], *ps =gbuf, *pt =gbuf;
	
	inline char Getchar(){
		if(ps == pt){
			ps =gbuf;
			pt =gbuf+fread(gbuf, 1, MAXB, stdin);
		}
		return (ps == pt) ? EOF : *ps++;
	}
}
#define getchar IO_base::Getchar
#define putchar IO_base::Putchar

namespace IO_number{
	int read(){
		int x =0; char c =getchar(); bool f =0;
		while(c < '0' || c > '9') (c == '-') ? f =1, c =getchar() : c =getchar();
		while(c >= '0' && c <= '9') x =(x<<1)+(x<<3)+(48^c), c =getchar();
		return (f) ? -x : x;
	}
}
using namespace IO_number;

/*------------------------------Number_Theory------------------------------*/

namespace Number_Theory_base{
	// naive mod
	inline int mul(const int &x, const int &y, const int &M){
		return 1ll*x*y%M;
	}
	
	int Pow(int x, int k, const int &M){
		int ret =1;
		for(; k; k >>=1, x =mul(x, x, M))
			if(k&1)
				ret =mul(ret, x, M);
		return ret;
	}
	
	int fact[MAXV*2], fact_inv[MAXV*2];
	
	void pre_Fact(){
		fact[0] =1;
		for(int i =1; i < MAXV*2; ++i)
			fact[i] =mul(fact[i-1], i, M);
		fact_inv[MAXV*2-1] =Pow(fact[MAXV*2-1], M-2, M);
		for(int i =MAXV*2-1 -1; i >= 0; --i)
			fact_inv[i] =mul(fact_inv[i+1], i+1, M);
	}
	
	inline int Fact(const int &x){
		return fact[x];
	}
	
	inline int Fact_Inv(const int &x){
		return fact_inv[x];
	}
}
using namespace Number_Theory_base;

/*------------------------------Poly------------------------------*/

const int MAXN_Poly =1<<14;
#define MAXN MAXN_Poly

namespace Poly_base{
	struct Poly{
		int N;
		int data[MAXN];
		
		Poly():N(0){
			memset(data, 0, sizeof(data));
		}
		Poly(const int &_N)
			:N(_N){
			memset(data, 0, sizeof(data));
		}
		
		int & operator [] (const int &index){
			return data[index];
		}
		int operator [] (const int &index) const{
			return data[index];
		}
	};
}
using namespace Poly_base;

// *require `Number_Theory_base`
namespace Poly_calc{
	#define mul(x, y) mul(x, y, M_NTT)
	#define Pow(x, k) Pow(x, k, M_NTT)
	#define Inv(x) Pow(x, M_NTT-2)
	
	// helper for Poly_calc
	namespace Poly_calc_base{
		const int M_NTT =998244353, g_NTT =3;
		#define M M_NTT
		/* reference of "g": https://en.wikipedia.org/wiki/Primitive_root_modulo_n */
		
		// helper arrays/variables for NTT
		int S[MAXN];
		bool op;
		
		// helper function for NTT
		void NTT_pre(const int &N){
			int shift_of_highest_bit =0;
			while(N >= (1<<(shift_of_highest_bit+1)))
				++shift_of_highest_bit;
			--shift_of_highest_bit;
			for(int i =0; i < N; ++i)
				S[i] =(S[i>>1]>>1)|((i&1)<<shift_of_highest_bit);
			op =1;
		}
		
		// helper function for NTT
		inline void NTT_rev_op(){
			op ^=1;
		}
		
		// helper function for NTT
		inline void swap(int &x, int &y){
			x ^=y ^=x ^=y;
		}
		
		void NTT(Poly &A){
			for(int i =0; i < A.N; ++i)
				if(i < S[i])
					swap(A[i], A[S[i]]);
			for(int N =1; N < A.N; N <<=1){
				const int wn =(op) ? Pow(g_NTT, (M-1)/(N<<1)) : Inv(Pow(g_NTT, (M-1)/(N<<1)));
				for(int shift_A =0; shift_A < A.N; shift_A +=(N<<1)){
					int w =1, *f0 =&A[0]+shift_A, *f1 =&A[0]+shift_A+N;
					for(int i =0; i < N; ++i){
						const int res =mul(*f1, w);
						*f1 =(*f0-res+M)%M, *f0 =(*f0+res)%M;
						w =mul(w, wn), ++f0, ++f1;
					}
				}
			}
		}
		
		#undef M
	}
	using namespace Poly_calc_base;
	
	// helper function for conv
	int get_Result_N(const int &limit){
		int N =1;
		while(N < limit)
			N <<=1;
		return N;
	}
	
	// *tips: `MAXN_Poly =get_Result_N(MAXN*2-1);`
	void conv(Poly &A, Poly &B, Poly &Result){
		const int N =Result.N =A.N =B.N =get_Result_N(A.N+B.N-1);
		NTT_pre(N);
		NTT(A), NTT(B);
		const int Inv_N =Inv(N);
		for(int i =0; i < N; ++i)
			Result[i] =mul(mul(A[i], B[i]), Inv_N);
		NTT_rev_op();
		NTT(Result);
	}
	
	#undef mul
	#undef Pow
	#undef Inv
}
using namespace Poly_calc;

#undef MAXN

/*------------------------------Main------------------------------*/

int main(){
	pre_Fact();
	
	const int n =read();
	
	Poly A(1);
	A[0] =1;
	for(int _t =0; _t < n; ++_t){
		const int a =read(), b =read();
		const int n_A =A.N;
		
		Poly B((n_A+a)-(b-n_A+1)+1);
		for(int i =0, j =b-n_A+1; j <= n_A+a; ++i, ++j)
			if(j >= 0 && a+b-j >= 0)
				B[i] =mul(Fact_Inv(j), Fact_Inv(a+b-j), M);
		conv(A, B, B);
		A.N =n_A+a-b;
		memset(A.data, 0, sizeof(A.data));
		for(int i =0; i < A.N; ++i)
			A[i] =mul(Fact(a+b), B[n_A+i-1], M);
	}
	int ans =0;
	for(int i =0; i < A.N; ++i)
		ans =(ans+A[i])%M;
	printf("%d", ans);
}