#include <stdio.h>
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <queue>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <complex>

long long int MOD = 998244353;
long long int INF = 1e18;

int update_max_segtree(std::vector<long long int> &max_segtree, long long int N_segtree, long long int index, long long int value);


long long int get_max(std::vector<long long int> &max_segtree, long long int N_segtree, long long int a, long long int b);
long long int sub_get_max(std::vector<long long int> &max_segtree, long long int a, long long int b, long long int k, long long int l, long long int r);

int main(){
  long long int N, tmp1, tmp2;
  std::vector<std::pair<long long int, long long int> > XD;

  scanf("%lld", &N);
  for(long long int i = 0; i < N; i++){
    scanf("%lld%lld", &tmp1, &tmp2);
    XD.push_back(std::make_pair(tmp1, tmp2));
  }

  std::sort(XD.begin(), XD.end());

  std::cerr << "XD: " << std::endl;
  for(long long int i = 0; i < N; i++){
    std::cerr << XD[i].first << " " << XD[i].second << std::endl;
  }

  // solve problem
  std::vector<long long int> right_robot(N);
  right_robot[N-1] = N-1;

  // segment tree
  long long int N_segtree = (1LL<<18); // set appropriately
  std::vector<long long int> max_segtree(2*N_segtree-1, -INF);
  update_max_segtree(max_segtree, N_segtree, N-1, N-1);

  // fill right robot
  long long int l, r, mid;

  for(long long int i = N-2; i >= 0; i--){
    // no other robots are activated
    if(XD[i+1].first >= XD[i].first + XD[i].second){
      right_robot[i] = i;
      update_max_segtree(max_segtree, N_segtree, i, i);
    }
    // all other robots are activated
    else if(XD[N-1].first <  XD[i].first + XD[i].second){
      right_robot[i] = N-1;
      update_max_segtree(max_segtree, N_segtree, i, N-1);
    }
    else{
      l = i+1;
      r = N-1;
      while(r-l>1){
        mid = (r+l)/2;
        if(XD[mid].first <  XD[i].first + XD[i].second){
          l = mid;
        }
        else{
          r = mid;
        }
      }
      right_robot[i] = get_max(max_segtree, N_segtree, i+1, r);
      update_max_segtree(max_segtree, N_segtree, i, right_robot[i]);
    }
    
  }

  // calculate answer
  std::vector<long long int> count(N+1);
  count[N] = 1;
  for(long long int i = N-1; i >= 0; i--){
    count[i] = (count[i+1] + count[right_robot[i]+1]+MOD)%MOD;
  }

  // print answer
  std::cerr << "Answer: " << std::endl;
  std::cout << count[0] << std::endl;

  return 0;
}


int update_max_segtree(std::vector<long long int> &max_segtree, long long int N_segtree, long long int index, long long int value){
  // change index to that of segment tree
  index += N_segtree-1;
  while(index > 0){
    if(value > max_segtree[index]){
      max_segtree[index] = value;
      index = (index-1)/2;
    }
    else{
      break;
    }
  }

  return 0;
}

long long int get_max(std::vector<long long int> &max_segtree, long long int N_segtree, long long int a, long long int b){

  return sub_get_max(max_segtree, a, b, 0, 0, N_segtree);
}

long long int sub_get_max(std::vector<long long int> &max_segtree, long long int a, long long int b, long long int k, long long int l, long long int r){

  // if range of index k: [l, r) is included in [a, b)
  if(a<=l && r<=b){
    return max_segtree[k];
  }
  // if the range of index k: [l, r) and [a, b) have no intersection
  if(r <= a || l >= b){
    return -INF;
  }
  // other cases
  else{
    return std::max(sub_get_max(max_segtree, a, b, 2*k+1, l, (l+r)/2), sub_get_max(max_segtree, a, b, 2*k+2, (l+r)/2, r));
  }

}


Measured memory_bytes: 11372