#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <cstring>
#include <iomanip>

using namespace std;

int mod=998244353;
class Box{
  public:
  double a,b;
  Box(double a_, double b_):a(a_),b(b_){};
  const Box operator+(const Box& B) const{
   return Box(a*B.a, b*B.a+B.b);
  }
  void print(){
   cout << a<<", "<< b<<endl;
  }
};
template <typename T> class SegTree{
 /* Segmentﾂ姪・                                                                             */
 /* [0,n)ﾂづ個計nﾂ古つづ個要ﾂ素ﾂづｰﾂ格ﾂ納ﾂつｵﾂ、ﾂつﾂづｩﾂ凝ｦﾂ甘納l,r)ﾂづ個値ﾂづｰﾂ偲ｦﾂ督ｾﾂつｷﾂづｩﾂつｽﾂづ淞づ個構ﾂ堕｢ﾂ。                    */
 /* ﾂ更ﾂ新ﾂ渉按猟敖、ﾂ値ﾂづ個偲ｦﾂ督ｾﾂ仰､ﾂづ瑛og(n)                                                           */
 /* ﾂつｱﾂづｪﾂつｪﾂ使ﾂつｦﾂづｩﾂつｽﾂづ淞づ個湘ｰﾂ個渉づ債、ﾂ凝ｦﾂ甘尿,Bﾂづ個値ﾂづｰﾂ用ﾂつ｢ﾂづ・凝ｦﾂ甘尿+Bﾂづ個値ﾂつｪcombineﾂづ可づｦﾂづｨﾂ計ﾂ算ﾂづ・つｫﾂづｩﾂつｱﾂづ・。*/
 /* ﾂ陛鳴宜ﾂ的ﾂづ頴perator+ﾂづｰﾂ偲ﾂ堕閉つｵﾂつｽﾂつｭﾂづｧﾂつｷﾂづ按づｧﾂづ篠格ﾂ納ﾂ嘉つ能ﾂづ・つｵﾂづ・つ｢ﾂづｩﾂ。ﾂ療｡ﾂづ坑oxﾂづｰﾂ参ﾂ湘・づ個つｱﾂづ・。       */
 private:
  vector<T> data;
  long long size; // ﾂ禿ｼﾂ療債づ・つｵﾂづ・与ﾂつｦﾂづｧﾂづｪﾂづｩﾂ要ﾂ素ﾂ青板づ・づ按つｭﾂつｻﾂづｪﾂ暗按湘｣ﾂづ個催・妥･ﾂづ・ﾂづ個療敖湘ｦﾂづｰﾂ偲ﾂ催崢づ個サﾂイﾂズﾂ催篠づ・陛崢篠敖つｷﾂづｩ
 public:
  T combine(T a, T b){
   //cout << "combine: "; a.print();
   //cout << "combine: "; b.print();
   return max(a,b);
  }
  SegTree(long long n, T def){
     size = 1;
     while(size < n) size*=2;
     data=vector<T>(size*2-1, def);
     for(int i=0; i<n; i++) setValue(i, def);
  }

  T getValue(int l){
    return getValue(l, l+1);
  }
  T getValue(int l, int r){
    // return sum in [l,r-1] or [l,r)
    return getValue_(0, l, r, 0, size);
  }
  T getValue_(int ind, int l, int r, int lb, int rb){
    //cout << ind << ", "<< l << ", " << r <<", "<<lb <<", "<< rb<<endl;
    if(l<=lb && rb<=r) return data[ind];
    int mid = (lb+rb)/2;
    if(r <= mid) return getValue_(ind*2+1, l, r, lb, mid);
    if(mid <= l) return getValue_(ind*2+2, l, r, mid, rb);
    return combine(getValue_(ind*2+1, l, r, lb, mid),
                   getValue_(ind*2+2, l, r, mid, rb));
  }
  void setValue(int i, T value){
    // add x to i
    int internal_index = size-1+i;
    data[internal_index]=value;
    while( internal_index != 0 ){
      internal_index=(internal_index-1)/2;
      data[internal_index]=combine(data[internal_index*2+1], data[internal_index*2+2]);
      //cout << "set: "<< internal_index << endl;
      //data[internal_index].print();
    }
    return;
  }
};
int main(){
   int N;
   cin >> N;
   vector<pair<long long,long long>>vec;
   for(int i=0;i<N;i++){
      long long x,d;
      cin >> x >> d;
      vec.push_back(make_pair(x,d));
   }
   sort(vec.begin(),vec.end());
   long long dp[300000];
   for(int i = 0;i<300000; i++)dp[i]=0;
   dp[N]=1;
   SegTree<int> ST(300000,0);
   for(int i = 0 ; i <300000; i++){
      ST.setValue(i,i+1);
   }
   for(int i = N-1; i>=0; i--){
      long long cur = vec[i].first;
      long long dist = vec[i].second;
      auto it = lower_bound(vec.begin(),vec.end(),make_pair(cur+dist,0LL));
      int index = it - vec.begin();
      long long v = ST.getValue(i, index);
      ST.setValue(i,v);
      dp[i]= dp[i+1]+dp[v];
      dp[i]%=mod;
   }
   cout << dp[0] << endl;
   return 0;
}


Measured memory_bytes: 10604