#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define endl '\n'
#define fcin ios::sync_with_stdio(false); cin.tie(nullptr);
#define INF 0x3f3f3f3f
#define all(x) x.begin(), x.end()
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

typedef long long ll;
typedef pair<int, int> pii;

template <typename A, typename B>
string to_string(pair<A, B> p){
    return "(" + to_string(p.fi) + ", " + to_string(p.se) + ")";
}

template <typename T>
string to_string(T v){
    string s = "{";
    bool first = true;
    for(const auto & x : v){
        if(!first) s += ", ";
        first = false;
        s += to_string(x);
    }
    return s + "}";
}

void debug_out(){ cerr << endl;}
template <typename First, typename... Next>
void debug_out(First F, Next... N){
    cerr << " " << to_string(F);
    debug_out(N...);
}

#ifdef LOCAL
    #define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
    #define debug(...) 1
#endif

const int N = 2e5 + 5;
const ll MOD = ll(998244353);
vector<pii> v;
ll dp[N];
int nxt[N];

ll add(ll x, ll y){
    x += y;
    if(x >= MOD) x -= MOD;
    return x;
}

ll sub(ll x, ll y){
    x -= y;
    x += MOD;
    if(x >= MOD) x -= MOD;
    return x;
}

ll mul(ll x, ll y){
    return (x % MOD * y % MOD) % MOD;
}

ll pwr(ll x, ll p){
    if(p == 0) return 1;
    if(p == 1) return x;
    if(p&1) return mul(x, pwr(x, p-1));
    ll t = pwr(x, p/2);
    return mul(t, t);
}

ll inv(ll x){
    return pwr(x, MOD-2);
}

template<typename T>
struct SegTree{
    T a[N], seg[4*N], lazy[4*N];

    SegTree(int m){
        for(int i = 0; i <= 4 * m + 4; i++) seg[i] = 0;
        for(int i = 0; i <= 4 * m + 4; i++) lazy[i] = 0;
        for(int i = 0; i <= m; i++) a[i] = 0;
    }

    inline T merge(T a, T b){
        return max(a, b);
    }

    inline T out(){
        return 0;
    }

    void build(int p, int l, int r){
        if(l == r) seg[p] = a[l];
        else {
            int mid = (l + r)/2;
            build(p+p, l, mid);
            build(p+p+1, mid + 1, r);
            seg[p] = merge(seg[p+p], seg[p+p+1]);
        }
    }

    void prop(int p, int l, int r){
        if(lazy[p]){
            seg[p] = lazy[p];
            if(l != r){
                lazy[p+p] = lazy[p];
                lazy[p+p+1] = lazy[p];
            }
            lazy[p] = 0;
        }
    }

    void upd(int p, int l, int r, int a, int b, T x){
        prop(p, l, r);
        if(l > b or r < a) return;
        if(l >= a and r <= b){
            lazy[p] = x;
            prop(p, l, r);
        } else {
            int mid = (l + r)/2;
            upd(p+p, l, mid, a, b, x);
            upd(p+p+1, mid + 1, r, a, b, x);
            seg[p] = merge(seg[p+p], seg[p+p+1]);
        }
    }

    T query(int p, int l, int r, int a, int b){
        prop(p, l, r);
        if(l > b or r < a) return out();
        if(l >= a and r <= b){
            return seg[p];
        } else {
            int mid = (l+r)/2;
            T lc = query(p+p, l, mid, a, b);
            T rc = query(p+p+1, mid+1, r, a, b);
            return merge(lc, rc);
        }
    }
};

int main(){
    fcin;
    int n;
    cin >> n;
    
    v.resize(n, {0, 0});
    for(int i = 0; i < n; i++){
        cin >> v[i].fi >> v[i].se;
    }

    sort(v.begin(), v.end());
    
    SegTree<int> st(n + 1);

    dp[n] = 1;
    nxt[n-1] = n;

    for(int i = n - 1; i >= 0; i--){
        auto it = lower_bound(v.begin(), v.end(), make_pair(v[i].fi + v[i].se, -INF));
        if(it == v.end()){
            dp[i] = add(dp[i+1], 1);
            nxt[i] = n;
        }
        else {
            int r = it - v.begin();
            nxt[i] = max(st.query(1, 1, n, i+2, r), r);
            dp[i] = add(dp[i+1], dp[nxt[i]]);
        }
        st.upd(1, 1, n, i+1, i+1, nxt[i]);
    }

    debug(v);
    cout << dp[0] % MOD << endl;
    return 0;
}



Measured memory_bytes: 11264