#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using Graph = vector<vector<int>>;
using WGraph = vector<vector<pair<int, ll>>>;

template<class T>inline bool chmax(T &a, const T &b) { if (b > a) { a = b; return true; } return false; }
template<class T>inline bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

constexpr int dx[4] = {-1, 0, 0, 1}, dy[4] = {0, -1, 1, 0};
constexpr int INF = 1e9;
constexpr int MOD = 1e9 + 7;
constexpr long long LINF = 1e18;
constexpr double EPS = 1e-10;
constexpr double PI = M_PI;

template<int mod>
class ModInt {
    private:
        long long val;
    public:
        constexpr ModInt(const long long v = 0) : val(v%mod) { if (val < 0) val += mod; }
        constexpr ModInt(const ModInt &v) : val(v.val) {}
        constexpr ModInt &operator=(const long long v) { val = v; return *this; }
        constexpr ModInt &operator=(const ModInt &v) { if (this != &v) val = v.val; return *this; }
        constexpr ModInt operator+() const { return ModInt(val); }
        constexpr ModInt operator-() const { return ModInt(-val); }
        constexpr ModInt operator+(const ModInt &v) const { return ModInt(*this) += v; }
        constexpr ModInt operator-(const ModInt &v) const { return ModInt(*this) -= v; }
        constexpr ModInt operator*(const ModInt &v) const { return ModInt(*this) *= v; }
        constexpr ModInt operator/(const ModInt &v) const { return ModInt(*this) /= v; }
        constexpr ModInt &operator+=(const ModInt &v) { val += v.val; if (val >= mod) val -= mod; return *this; }
        constexpr ModInt &operator-=(const ModInt &v) { val -= v.val; if (val < 0) val += mod; return *this; }
        constexpr ModInt &operator*=(const ModInt &v) { val *= v.val; if (val >= mod) val %= mod; return *this; }
        constexpr ModInt &operator/=(const ModInt &v) { val *= v.inverse().val; if (val >= mod) val %= mod; return *this; }
        constexpr ModInt &operator++() { ++val; if (val >= mod) val -= mod; return *this; }
        constexpr ModInt &operator--() { --val; if (val < 0) val += mod; return *this; }
        constexpr ModInt operator++(int) { ModInt tmp(*this); operator++(); return tmp; }
        constexpr ModInt operator--(int) { ModInt tmp(*this); operator--(); return tmp; }
        constexpr bool operator==(const ModInt &v) const { return val == v.val; }
        constexpr bool operator!=(const ModInt &v) const { return !(*this == v); }
        friend std::istream &operator>>(std::istream &s, ModInt &v) { long long tmp; s >> tmp; v = ModInt(tmp); return s; }
        friend std::ostream &operator<<(std::ostream &s, const ModInt &v) { return s << v.val; }
        constexpr ModInt inverse() const {
            long long n = val, res = 1;
            while (n > 1) {
                res *= (mod - mod / n);
                res %= mod;
                n = mod % n;
            }
            return ModInt(res);
        }
        static constexpr ModInt modpow(ModInt v, long long n) {
            ModInt res(1);
            for ( ; n>0; n>>=1) {
                if (n & 1) res *= v;
                v *= v;
            }
            return res;
        }
};

using MInt = ModInt<998244353>;

template<class T>
class SegmentTree {
    using Func = std::function<T(T, T)>;
    private:
        const Func F;
        const T DEF;
        int N;
        std::vector<T> dat;
    public:
        SegmentTree(int n, const Func f, const T def) : F(f), DEF(def) {
            N = 1;
            while (N < n) N *= 2;
            dat.assign(2*N, DEF);
        }
        // a is 0-indexed
        void set(int a, const T v) { dat[a+N] = v; }
        void build() { for (int i=N-1; i>0; --i) dat[i] = F(dat[2*i], dat[2*i+1]); }
        // a is 0-indexed
        void update(int a, const T v) {
            int cur = a + N;
            dat[cur] = v;
            while ((cur /= 2) > 0) dat[cur] = F(dat[2*cur], dat[2*cur+1]);
        }
        // return value of [a, b)
        // a and b are 0-indexed
        T get(int a, int b) const { return get(a, b, 1, 0, N); }
        T get(int a, int b, int k, int l, int r) const {
            if (b <= l || r <= a) return DEF;
            if (a <= l && r <= b) return dat[k];
            T vleft = get(a, b, 2*k, l, (l+r)/2);
            T vright = get(a, b, 2*k+1, (l+r)/2, r);
            return F(vleft, vright);
        }
        // a is 0-indexed
        T at(int a) const { return dat.at(a+N); }
};

void solve() {
    int N;
    cin >> N;
    vector<pair<int, int>> robots(N);
    for (int i=0; i<N; ++i) cin >> robots[i].first >> robots[i].second;

    sort(robots.begin(), robots.end());
    SegmentTree<int> st(N, [](int a, int b){return max(a, b);}, 0);
    for (int i=0; i<N; ++i) st.set(i, i+1);
    st.build();
    for (int i=N-2; i>=0; --i) {
        int p = lower_bound(robots.begin(), robots.end(), make_pair(robots[i].first+robots[i].second, 0)) - robots.begin();
        st.update(i, st.get(i, p));
    }
    vector<MInt> dp(N+1);
    dp[N] = 1;
    for (int i=N-1; i>=0; --i) dp[i] = dp[i+1] + dp[st.at(i)];
    cout << dp[0] << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(20);

    solve();

    return 0;
}


Measured memory_bytes: 8476