#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;

template<long long mod>
class modint{
private:
  long long a;
public:
  constexpr modint(const long long x = 0) noexcept : a(x%mod) {}
  constexpr long long& value() noexcept { return a; }
  constexpr const long long& value() const noexcept { return a; }
  constexpr modint operator+(const modint rhs) const noexcept {
    return modint(*this) += rhs;
  }
  constexpr modint operator-(const modint rhs) const noexcept {
    return modint(*this) -= rhs;
  }
  constexpr modint operator*(const modint rhs) const noexcept {
    return modint(*this) *= rhs;
  }
  constexpr modint operator/(const modint rhs) const noexcept {
    return modint(*this) /= rhs;
  }
  constexpr modint& operator+=(const modint rhs) noexcept {
    a += rhs.a;
    if(a >= mod) a -= mod;
    return *this;
  }
  constexpr modint &operator-=(const modint rhs) noexcept {
    if(a < rhs.a) a += mod;
    a -= rhs.a;
    return *this;
  }
  constexpr modint& operator*=(const modint rhs) noexcept {
    a = a*rhs.a%mod;
    return *this;
  }
  constexpr modint& operator/=(modint rhs) noexcept {
    long long k = mod-2;
    while(k > 0){
      if(k&1){
        *this *= rhs;
      }
      rhs *= rhs;
      k /= 2;
    }
    return *this;
  }
  friend ostream& operator<<(ostream &os, const modint &X){
    return os << X.a;
  }
  friend istream& operator>>(istream &is, modint &X){
    is >> X.a;
    X.a %= mod;
    if(X.a < 0) X.a += mod;
    return is;
  }
};

const long long INF = 1e18;

struct RMaxQ{
private:
  int n;
  vector<long long> data;
public:
  RMaxQ(int N){
    vector<long long> V(N,-INF);
    int sz = V.size();
    n = 1;
    while(n < sz) n *= 2;
    data.resize(2*n-1,-INF);
    for(int i = 0; i < sz; ++i) data[n-1+i] = V[i];
    for(int i = n-2; i >= 0; --i) data[i] = max(data[2*i+1],data[2*i+2]);
  }
  RMaxQ(vector<long long> V){
    int sz = V.size();
    n = 1;
    while(n < sz) n *= 2;
    data.resize(2*n-1,-INF);
    for(int i = 0; i < sz; ++i) data[n-1+i] = V[i];
    for(int i = n-2; i >= 0; --i) data[i] = max(data[2*i+1],data[2*i+2]);
  }
  void update(int idx, long long val){//0-indexed
    idx += n-1;
    data[idx] = val;
    while(idx > 0){
      idx = (idx-1)/2;
      data[idx] = max(data[2*idx+1],data[2*idx+2]);
    }
  }
  long long get_max(int l, int r){//[l,r)の区間の最大値
    long long ret = -INF;
    l += n-1, r += n-1;
    while(l < r){
      if((l&1) == 0){
        ret = max(ret,data[l]);
      }
      if((r&1) == 0){
        ret = max(ret,data[r-1]);
      }
      l /= 2;
      r = (r-1)/2;
    }
    return ret;
  }
};

using mint = modint<998244353>;

int main(){
  int N;
  cin >> N;
  vector<pair<long long,long long>> R;
  for(int i = 0; i < N; ++i){
    int x, d;
    cin >> x >> d;
    R.emplace_back(x,d);
  }
  sort(R.begin(), R.end());
  RMaxQ rmq(N);
  for(int i = N-1; i >= 0; --i){
    long long r = upper_bound(R.begin(), R.end(), make_pair(R[i].first+R[i].second,0LL)) - R.begin();
    // cerr << i << " " << r << endl;
    long long nex = rmq.get_max(i,r);
    nex = max<long long>(nex,i);
    // cerr << i << " " << nex << endl;
    rmq.update(i,nex);
  }
  vector<mint> dp(N+1);
  dp[0] = 1;
  for(int i = 0; i < N; ++i){
    // cerr << i << " " << rmq.get_max(i,i+1)+1 << endl;
    dp[i+1] += dp[i];
    dp[rmq.get_max(i,i+1)+1] += dp[i];
  }
  cout << dp.back() << endl;
}


Measured memory_bytes: 9580