#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define ALL(v) (v).begin(), (v).end()
using ll = long long;
using P = pair<int, int>;
const int INF = 1e9;
const long long LINF = 1e18;
const long long MOD = 998244353;

/*
    SegmentTree<int> seg(f, def) のように宣言する
    RMQ の場合 :
    auto f = [](int a, int b){return min(a, b);};
    int def = INF;
*/
template <typename Monoid>
struct SegmentTree {
    using F = function<Monoid(Monoid, Monoid)>;
    int n;
    vector<Monoid> dat;
    F f;
    Monoid def;

    SegmentTree(F f, Monoid def) : f(f), def(def) {}

    void build(const vector<Monoid> &vec) {
        int sz = vec.size();
        n = 1;
        while (n < sz) n *= 2;
        dat.assign(2 * n - 1, def);
        for (int i = 0; i < sz; i++) dat[n - 1 + i] = vec[i];
        for (int i = n - 2; i >= 0; i--)
            dat[i] = f(dat[2 * i + 1], dat[2 * i + 2]);
    }

    void update(int k, Monoid x) {
        k += (n - 1);
        dat[k] = x;
        while (k > 0) {
            k = (k - 1) / 2;
            dat[k] = f(dat[2 * k + 1], dat[2 * k + 2]);
        }
    }

    Monoid query(int a, int b) {
        return query(a, b, 0, 0, n);
    }

   private:
    Monoid query(int a, int b, int k, int l, int r) {
        if (r <= a || b <= l) return def;
        if (a <= l && r <= b) return dat[k];
        Monoid vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
        Monoid vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
        return f(vl, vr);
    }
};

template <int MOD = 1000000007>
struct Mint {
    int x;

    Mint() : x(0) {}
    Mint(long long t) {
        x = t % MOD;
        if (x < 0) x += MOD;
    }

    Mint pow(int n) {
        Mint res(1), t(x);
        while (n > 0) {
            if (n & 1) res *= t;
            t *= t;
            n >>= 1;
        }
        return res;
    }

    Mint inv() const {
        int a = x, b = MOD, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            a -= t * b;
            swap(a, b);
            u -= t * v;
            swap(u, v);
        }
        return Mint(u);
    }

    Mint &operator+=(Mint a) {
        x += a.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }

    Mint &operator-=(Mint a) {
        x += MOD - a.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }

    Mint &operator*=(Mint a) {
        x = int(1LL * x * a.x % MOD);
        return *this;
    }

    Mint &operator/=(Mint a) {
        return (*this) *= a.inv();
    }

    Mint operator+(Mint a) const {
        return Mint(x) += a;
    }
    Mint operator-(Mint a) const {
        return Mint(x) -= a;
    }
    Mint operator*(Mint a) const {
        return Mint(x) *= a;
    }
    Mint operator/(Mint a) const {
        return Mint(x) /= a;
    }

    Mint operator-() const {
        return Mint(-x);
    }

    bool operator==(const Mint a) {
        return x == a.x;
    }
    bool operator!=(const Mint a) {
        return x != a.x;
    }
    bool operator<(const Mint a) {
        return x < a.x;
    }

    friend ostream &operator<<(ostream &os, const Mint &a) {
        return os << a.x;
    }

    friend istream &operator>>(istream &is, Mint &a) {
        int t;
        is >> t;
        a = Mint<MOD>(t);
        return (is);
    }
};

signed main() {
    int n;
    cin >> n;
    vector<pair<ll, ll>> v(n);
    rep(i, n) {
        cin >> v[i].first >> v[i].second;
    }
    sort(ALL(v));
    auto f = [](int a, int b) { return max(a, b); };
    SegmentTree<int> seg(f, -INF);
    seg.build(vector<int>(n, -INF));
    vector<int> r(n);
    for (int i = n - 1; i >= 0; i--) {
        r[i] = max(
            i,
            seg.query(i, lower_bound(ALL(v), pair<ll, ll>(
                                                 v[i].first + v[i].second, 0)) -
                             v.begin()));
        seg.update(i, r[i]);
    }
    Mint<MOD> dp[n];
    dp[n] = 1;
    for (int i = n - 1; i >= 0; i--) {
        dp[i] = dp[i + 1] + dp[r[i] + 1];
    }
    cout << dp[0] << endl;
    return 0;
}

Measured memory_bytes: 7024