//ヘッダー
#include<bits/stdc++.h>
using namespace std;

//型定義
typedef long long ll;

//定数
const int MOD=998244353;

//REPマクロ
#define REP(i,n) for(ll i=0;i<(ll)(n);i++)
#define REPD(i,n) for(ll i=n-1;i>=0;i--)
#define REP2(i,a,b) for(ll i=a;i<(ll)(b);i++)
#define REPD2(i,a,b) for(ll i=a;i>(ll)(b);i--)

// 多次元 vector 生成
template<class T>
vector<T> make_vec(size_t a){
    return vector<T>(a);
}
template<class T, class... Ts>
auto make_vec(size_t a, Ts... ts){
  return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}

//vectorの扱い
#define ALL(x) (x).begin(),(x).end() //sortなどの引数省略
#define SIZE(x) ((ll)(x).size()) //size
#define MAX(x) *max_element(ALL(x)) //最大値
#define MIN(x) *min_element(ALL(x)) //最小値

//省略
using vi  = vector<int>;
using vii = vector<vector<int>>;
using vl  = vector<ll>;
using vll = vector<vector<ll>>;
using pii = pair<int,int>;
using pll = pair<ll,ll>;

//区間加算・区間最大値（最小値）評価セグメント木
//クエリlog(N)
//代入する値を負にすれば最小値も可能
//starry_sky_tree seg(N);で初期化
//seg.getmax(a,b);でインデックスa～b-1までの区間和を計算
//seg.add(a,b,x);でインデックスa～b-1までの値にxを加算
struct starry_sky_tree {
    int size;
    vector<int> data;
    vector<int> lazy;
    vector<int> width;

    starry_sky_tree(int n) {
        size = 1;
        while (size < n) size <<= 1;
        data.resize(size*2, 0);
        lazy.resize(size*2, 0);
        width.resize(size*2, 1);
        for (int i = size-2; i >= 0; i--) {
            width[i] = width[i*2+1] + width[i*2+2];
        }
    }

    void lazy_propagate(int p) {
        data[p] += lazy[p];
        if (p < size-1) {
            lazy[p*2+1] += lazy[p];
            lazy[p*2+2] += lazy[p];
        }
        lazy[p] = 0;
    }

    void add(int wishl, int wishr, int x) {
        add(wishl, wishr, 0, size, 0, x);
    }
    void add(int wishl, int wishr, int watchl, int watchr, int k, int x) {
        if (wishr <= watchl || watchr <= wishl) {
            lazy_propagate(k);
            return;
        }
        if (wishl <= watchl && watchr <= wishr) {
            lazy[k] += x;
            lazy_propagate(k);
            return;
        }

        int mid = (watchl + watchr) / 2;
        lazy_propagate(k);
        add(wishl, wishr, watchl, mid, k*2+1, x);
        add(wishl, wishr, mid, watchr, k*2+2, x);
        data[k] = max(data[k*2+1], data[k*2+2]);
    }

    int getmax(int wishl, int wishr) {
        return getmax(wishl, wishr, 0, size, 0);
    }
    int getmax(int wishl, int wishr, int watchl, int watchr, int k) {
        if (wishr <= watchl || watchr <= wishl) return -1000000000;
        if (wishl <= watchl && watchr <= wishr) {
            lazy_propagate(k);
            return data[k];
        }

        int mid = (watchl + watchr) / 2;
        int L = getmax(wishl, wishr, watchl, mid, k*2+1);
        int R = getmax(wishl, wishr, mid, watchr, k*2+2);
        return max(L, R);
    }
};

int main(){
    ll N;
    cin>>N;
    vector<pair<ll,ll>> XD(N);
    REP(i,N) cin>>XD[i].first>>XD[i].second;
    sort(ALL(XD));
    vl X(N),D(N);
    REP(i,N){
        X[i]=XD[i].first;
        D[i]=XD[i].second;
    }

    starry_sky_tree seg(N+10);
    REPD2(i,N-1,-1){
        ll idx =lower_bound(ALL(X),X[i]+D[i])-X.begin();
        ll l=i+1;
        ll r=idx;
        ll num=seg.getmax(l,r);
        num=max(num,idx);
        seg.add(i,i+1,num);
    }

    vl dp(N+1,0);
    dp[N]=1;
    REPD2(i,N-1,-1){
        dp[i]=dp[i+1];
        dp[i]+=dp[seg.getmax(i,i+1)];
        dp[i]%=MOD;

    }
    cout<<dp[0]<<endl;

}

Measured memory_bytes: 17244