#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
typedef long long LL;

using std::vector;
constexpr int LOGN=15, M=998244353, G=3;
vector<int> rev[LOGN];
vector<LL> g[LOGN];

LL Pow(LL a, int k)
{
    LL ans=1;
    while(k)
    {
        if(k&1) ans=(ans*a)%M; 
        a=(a*a)%M, k>>=1;
    }
    return ans;
}
inline LL Inv(const LL& a)
{
    return Pow(a, M-2);
}

void PreNTT()
{
    for(int mid=0, len; mid<LOGN-1; mid++)
    {
        len=1<<mid;
        g[mid].assign(len, 1);
        LL Gn=Pow(G, (M-1)/(len<<1)), tmp=1;
        for(LL i=0; i<len; i++)
        {
            g[mid][i]=tmp;
            tmp=tmp*Gn%M;
        }
    }
    rev[0].push_back(0);
    for(int bit_length=1, bit_depth; bit_length<LOGN; bit_length++)
    {
        bit_depth=1<<bit_length;
        vector<int> &rev_now=rev[bit_length];
        rev_now.assign(bit_depth, 0);
        for(int i=0; i<bit_depth; i++)
            rev_now[i]=(rev_now[i>>1]>>1) | (i&1)<<(bit_length-1);
    }
}
void NTT(vector<LL> &X, bool reverse=false)
{
    int bit_depth=X.size(), bit_length=__builtin_ctz(bit_depth);
    for(int i=0, ri; i<bit_depth; i++)
    {
        ri=rev[bit_length][i];
        if(i<ri) std::swap(X[i], X[ri]);
    }
    for(int mid=0, len; mid<bit_length; mid++)
    {
        len=1<<mid;
        for(int i=0; i<bit_depth; i+=(len<<1))
            for(int j=0; j<len; j++)
            {
                LL x=X[i+j], y=X[i+j+len]*g[mid][j]%M;
                X[i+j]=(x+y)%M;
                X[i+j+len]=(x-y+M)%M;
            }
    }
    if(reverse)
    {
        LL inv_n=Inv(bit_depth);
        for(int i=0; i<bit_depth; i++)
            X[i]=X[i]*inv_n%M;
        std::reverse(X.begin()+1, X.end());
    }
}

vector<LL> Mul(vector<LL> a, vector<LL> b)
{
    int len=1<<(32-__builtin_clz(a.size()+b.size()-1));
    a.resize(len), b.resize(len);
    NTT(a), NTT(b);
    vector<LL> ans(len);
    for(int i=0; i<len; i++) 
        ans[i]=a[i]*b[i];
    NTT(ans, true);
    return ans;
}

LL Combine(int n, int k)
{
    static vector<LL> fac(1, 1), inv_fac(1, 1);
    if(k<0 || k>n) return 0;
    while((int)fac.size()<=n)
    {
        fac.push_back(fac.back()*fac.size()%M);
        inv_fac.push_back(Inv(fac.back()));
    }
    return fac[n]*inv_fac[k]%M*inv_fac[n-k]%M;
}

void Test()
{
    freopen("temp\\in.txt", "r", stdin);
}
int main()
{
    // Test();
    PreNTT();

    int n, a, b;
    scanf("%d", &n);
    vector<LL> ans(1, 1);
    for(int i=0, w, new_w; i<n; i++)
    {
        scanf("%d%d", &a, &b);
        w=ans.size(), new_w=w+a-b;
        vector<LL> tmp;
        for(int j=b-w+1; j<w+a; j++)
            tmp.push_back(Combine(a+b, j));
        auto new_ans=Mul(ans, tmp);
        ans.resize(new_w);
        for(int j=0; j<new_w; j++)
            ans[j]=new_ans[w+j-1];
    }

    LL sum=0, w=ans.size();
    for(int i=0; i<w; i++)
        sum=(sum+ans[i])%M;
    std::cout<<sum;
    return 0;
}
	 	 		 		  			 	 	 		   		   		