#include <bits/stdc++.h>

using namespace std;

#define all(x) begin(x), end(x)

using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using vi = vector<int>;

struct modint {
    static const int MOD = 998244353;

    int v;
    modint(const int _v = 0): v(_v % MOD) {
        if (v < 0) v += MOD;
    }

    bool operator==(const modint& other) const {
        return v == other.v;
    }

    modint& operator+=(const modint& other) {
        v += other.v;
        if (v >= MOD)
            v -= MOD;
        return *this;
    }

    modint& operator-=(const modint& other) {
        v -= other.v;
        if (v < 0)
            v += MOD;
        return *this;
    }

    modint& operator*=(const modint& other) {
        v = 1LL * v * other.v % MOD;
        return *this;
    }

    modint& operator/=(const modint& other) {
        *this *= other.inv();
        return *this;
    }

    modint operator+(const modint& other) const {
        return modint(v) += other;
    }

    modint operator-(const modint& other) const {
        return modint(v) -= other;
    }

    modint operator*(const modint& other) const {
        return modint(v) *= other;
    }

    modint operator/(const modint& other) const {
        return modint(v) /= other;
    }

    static modint pow(const modint& b, ll e) {
        if (e == 0) return 1;
        modint x = pow(b * b, e / 2);
        return (e % 2) ? b * x : x;
    }

    modint pow(ll e) const {
        return pow(*this, e);
    }

    modint inv() const {
        return pow(MOD - 2);
    }

    friend ostream& operator<<(ostream& os, modint m) {
        return os << m.v;
    }
};

struct seg_tree {
    using T = int;
    T combine(T a, T b) const {
        return max(a, b);
    }

    int n;
    vector<T> data;
    seg_tree(int n): n(n) {
        data.assign(n << 1, 0);
    }

    void update(int i, T v) {
        i += n;
        data[i] = v;
        for (i >>= 1; i; i >>= 1) {
            data[i] = combine(data[i << 1], data[i << 1 | 1]);
        }
    }

    T query(int l, int r) {
        T res_left(0), res_right(0);
        for (l += n, r += n; l <= r; l >>= 1, r >>= 1) {
            if (l & 1)    res_left  = combine(res_left, data[l++]);
            if (!(r & 1)) res_right = combine(data[r--], res_right);
        }

        return combine(res_left, res_right);
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n;
    cin >> n;
    vector<pii> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i].first >> a[i].second;
    }
    sort(all(a));

    vi dp(n, 0);
    seg_tree st(n);
    // for each point, figure out what range it would cover if it launched:
    for (int i = n - 1; i >= 0; --i) {
        // find the smallest j where a[j].first >= x + d
        int g = a[i].first + a[i].second;
        int lo = i;
        int hi = n;
        while (lo + 1 < hi) {
            int mid = (lo + hi) / 2;
            if (a[mid].first >= g)
                hi = mid;
            else
                lo = mid;
        }

        if (i == lo) {
            dp[i] = lo;
        } else {
            dp[i] = st.query(i + 1, lo);
        }

        st.update(i, dp[i]);
    }

    vector<modint> dp2(n + 1, modint(0));
    dp2[n] = 1;
    for (int i = n - 1; i >= 0; --i) {
        int j = dp[i];
        dp2[i] = dp2[i + 1] + dp2[j + 1];
    }

    cout << dp2[0];

    return 0;
}


Measured memory_bytes: 4992