#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#include <random>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define sz(x) ((int)(x).size())
typedef vector<int> vi;
typedef long long ll;
typedef pair<int, int> pii;
typedef double db;
mt19937 mrand(random_device{}());
const ll mod = 998244353;
int rnd(int x) { return mrand() % x; }
ll powmod(ll a, ll b) { ll res = 1; a %= mod; assert(b >= 0); for (; b; b >>= 1) { if (b & 1)res = res * a % mod; a = a * a % mod; }return res; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
// head

const int MAXN = 200000 + 5;
int n;
ll x[MAXN], d[MAXN];
int idx[MAXN];

int to[MAXN];
ll dp[MAXN];

bool cmp(const int a, const int b)
{
	return x[a] < x[b];
}

int lower_bound(ll num) {
	int le = 0, ri = n;
	while (le < ri) {
		int mid = (le + ri) / 2;
		int ii = idx[mid];
		if (x[ii] < num) {
			le = mid + 1;
		}
		else {
			ri = mid;
		}
	}
	return le;
}

namespace SegmentTree {
	int n;

	struct Node {
		int maxn;
	};

	Node nodes[4 * MAXN];

	void init(int n_) {
		//为了简单起见，将元素扩大到2的幂
		n = 1;
		while (n < n_) n *= 2;

		memset(nodes, 0, sizeof(nodes));
	}

	//将第k个值更新为a
	void update(int k, int a) {
		//叶子节点
		k += n - 1;
		nodes[k].maxn = a;
		//向上更新
		while (k > 0) {
			k = (k - 1) / 2;
			nodes[k].maxn = max(nodes[k * 2 + 1].maxn, nodes[k * 2 + 2].maxn);
		}
	}

	//求[a,b)的最大prefix_max
	//后面的参数是为了计算方便传入的
	//k是节点的编号，l,r表示这个节点代表区间[l,r)
	//外部调用时，使用query(a,b,0,0,n);
	int query(int a, int b, int k, int l, int r) {
		//如果[a,b)和[l,r)不相交，返回0
		if (r <= a || b <= l) return 0;
		//如果[a,b)完全包含[l,r)，返回当前节点值
		if (a <= l && r <= b) return nodes[k].maxn;
		else {
			int v1 = query(a, b, k * 2 + 1, l, (l + r) / 2);
			int v2 = query(a, b, k * 2 + 2, (l + r) / 2, r);
			return max(v1, v2);
		}
	}
}


int main()
{
	ios::sync_with_stdio(false);
#ifdef RG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	cin >> n;
	rep(i, 0, n) cin >> x[i] >> d[i];

	iota(idx, idx + n, 0);
	sort(idx, idx + n, cmp);

	SegmentTree::init(n);

	to[n - 1] = n;
	SegmentTree::update(n - 1, n);
	per(i, 0, n) {
		int ii = idx[i];
		ll le = x[ii];
		ll ri = x[ii] + d[ii];

		int j = lower_bound(ri) - 1;
		//cout << i+1<<","<<j+1 << endl;
		int jj = idx[j];
		if (x[jj] <= x[ii]) {
			to[i] = i + 1;
		}
		else {
			to[i] = SegmentTree::query(i + 1, j + 1, 0, 0, SegmentTree::n);
		}
		SegmentTree::update(i, to[i]);
		/*else if (ri > x[jj] + d[jj]) {
			to[i] = max(j+1, to[i+1]);
		}
		else {
			to[i] = max(to[j], to[i+1]);
		}*/
	}

	/*cout << "st:";
	rep(i, 0, n) cout << SegmentTree::nodes[SegmentTree::n+i-1].maxn << ",\t";
	cout << endl;
	cout << "i:";
	rep(i, 0, n) cout << i << ",\t";
	cout << endl;
	cout << "x:";
	rep(i, 0, n) cout << x[index[i]] << ",\t";
	cout << endl;
	cout << "d:";
	rep(i, 0, n) cout << d[index[i]] << ",\t";
	cout << endl;
	cout << "to:";
	rep(i, 0, n) cout << to[i] << ",\t";
	cout << endl;*/

	dp[n] = 1;
	per(i, 0, n) {
		dp[i] = (dp[i + 1] + dp[to[i]]) % mod;
		//cout << dp[i] << endl;
	}

	cout << dp[0] << endl;

	return 0;
}

Measured memory_bytes: 9600