#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <queue>
#include <set>
#include <algorithm>
#include <string>
#include <math.h>
#include <limits.h>
#include <stack>
#include <complex>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <cfloat>
#include <math.h>
#include <numeric>
#include <string.h>
#include <sys/time.h>
#include <random>


#define fs first
#define sc second

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define MAX_N 410000
int dat[2 * MAX_N - 1];


template<typename T>
class SegTree{
public:
    //セグメント木を持つグローバル変数
    int n;

    void init(int n_, T init_num){
        n = 1;
        while(n < n_) n *= 2;
        for(int i = 0; i < 2*n-1; i++){
            dat[i] = init_num;
        }
    }

    // k番目の値(0-indexed)をaに変更
    void update(int k, T a){
        k += n-1;
        dat[k] = a;
        while(k > 0){
            k = (k-1)/2;
            dat[k] = max(dat[k*2+1], dat[k*2+2]);
        }
    }

    // [a, b)の最小値を求める。
    // kは節点の番号、l, rはその節点が[l, r)に対応づいていることを表す。
    // query(a, b, 0, 0, n)で外からは呼び出す。
private: T query(int a, int b, int k, int l, int r) {
        if (r <= a || b <= l) {
            return 0;
        }

        if (a <= l && r <= b) {
            return dat[k];
        } else {
            ll vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
            ll vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
            return max(vl, vr);
        }
    }
    // [a, b)の最小値を求める。
public: T query(int a, int b){
        return query(a, b, 0, 0, this->n);
    }
};


class modInt{
    ll value;
    static const ll mod = 998244353;

public:
    modInt(ll x): value{x % mod}{}

    inline modInt& operator+=(modInt x){
        value = (value + x.value) % mod;
        return *this;
    }

    inline modInt& operator-=(modInt x){
        value = (value + mod - x.value) % mod;
        return *this;
    }

    inline modInt& operator*=(modInt x){
        value = (value * x.value) % mod;
        return *this;
    }


    inline modInt operator/=(modInt x){
        *this *= x.inv();
        return *this;
    }

    inline modInt pow(modInt x, int n){
        modInt res = modInt(1LL);
        while(n > 0){
            if(n & 1)   res *= x;
            x *= x;
            n >>= 1;
        }
        return res;
    }

    inline modInt inv(){
        modInt res = pow(value, mod-2);
        return res;
    }

    inline ll get(){
        return value;
    }
};

modInt operator+(modInt x, modInt y){
    return x += y;
}

modInt operator-(modInt x, modInt y){
    return x -= y;
}

modInt operator*(modInt x, modInt y){
    return x *= y;
}

modInt operator/(modInt x, modInt y){
    return x /= y;
}

ostream& operator<<(ostream& os, modInt x){
    return os << x.get();
}


class modIntCombinations{
    vector<modInt> factArray;

    void make_fact(ll x){
        for(auto i = factArray.size(); i <= x+1; i++){
            modInt y = factArray[i-1] * i;
            factArray.push_back(y);
        }
    }

public:
    modIntCombinations(){
        factArray.emplace_back(1);
    }

    modInt fact(ll x){
        if(factArray.size() < x+1){
            make_fact(x);
        }
        return factArray[x];
    }

    modInt comb(ll n, ll k){
        if(n < k){
            return modInt{0};
        }
        else{
            return fact(n) / fact(k) / fact(n - k);
        }
    }

    modInt perm(ll n, ll k){
        if(n < k){
            return modInt{0};
        }
        else{
            return fact(n) / fact(k);
        }
    }
};


vector<modInt> dp(210000, 0);
vector<int> next1(210000, -1);


int main(){
    int n;
    cin >> n;
    vector<P> x2;
    for(int i = 0; i < n; i++){
        ll xx, dd;  cin >> xx >> dd;
        x2.emplace_back(P(xx, dd));
    }
    sort(x2.begin(), x2.end());

    vector<ll> x(n, 0), d(n, 0);
    for(int i = 0; i < n; i++){
        x[i] = x2[i].fs;
        d[i] = x2[i].sc;
    }

    SegTree<int> st;
    st.init(n, -1);
    for(int i = 0; i < n; i++){
        st.update(i, i+1);
    }

    for(int i = n-1; i >= 0; i--){
        int next_ind = lower_bound(x.begin(), x.end(), x[i] + d[i]) - x.begin();
        if(i+1 == next_ind){
            next1[i] = i+1;
        }
        else {
            next1[i] = st.query(i + 1, next_ind);
        }
        st.update(i, next1[i]);
    }

    dp[0] = 1;

    for(int i = 0; i < n; i++){
        // 選ぶ場合
        int nex = st.query(i, i+1);
        dp[nex] = dp[nex] + dp[i];
        // 選ばない場合
        dp[i+1] = dp[i+1] + dp[i];
    }
    cout << dp[n] << endl;

    return 0;
}


Measured memory_bytes: 11884