There are N robots numbered 1 to N placed on a number line. Robot i is placed at coordinate X_i. When activated, it will travel the distance of D_i in the positive direction, and then it will be removed from the number line. All the robots move at the same speed, and their sizes are ignorable.
Takahashi, who is a mischievous boy, can do the following operation any number of times (possibly zero) as long as there is a robot remaining on the number line.
 - Choose a robot and activate it. This operation cannot be done when there is a robot moving.
While Robot i is moving, if it touches another robot j that is remaining in the range [X_i, X_i + D_i) on the number line, Robot j also gets activated and starts moving. This process is repeated recursively.
How many possible sets of robots remaining on the number line are there after Takahashi does the operation some number of times? Compute this count modulo 998244353, since it can be enormous.

-----Constraints-----
 - 1 \leq N \leq 2 \times 10^5
 - -10^9 \leq X_i \leq 10^9
 - 1 \leq D_i \leq 10^9
 - X_i \neq X_j (i \neq j)
 - All values in input are integers.

-----Input-----
Input is given from Standard Input in the following format:
N
X_1 D_1
:
X_N D_N

-----Output-----
Print the number of possible sets of robots remaining on the number line, modulo 998244353.

-----Sample Input-----
2
1 5
3 3

-----Sample Output-----
3

There are three possible sets of robots remaining on the number line: \{1, 2\}, \{1\}, and \{\}.
These can be achieved as follows:
 - If Takahashi activates nothing, the robots \{1, 2\} will remain.
 - If Takahashi activates Robot 1, it will activate Robot 2 while moving, after which there will be no robots on the number line. This state can also be reached by activating Robot 2 and then Robot 1.
 - If Takahashi activates Robot 2 and finishes doing the operation, the robot \{1\} will remain.

Difficulty: MEDIUM_HARD

Solutions:
class SegTree:

	def __init__(self, init_val, ide_ele, segfunc):
		self.n = len(init_val)
		self.num = 2 ** (self.n - 1).bit_length()
		self.ide_ele = ide_ele
		self.seg = [self.ide_ele] * 2 * self.num
		self.segfunc = segfunc
		for i in range(self.n):
			self.seg[i + self.num - 1] = init_val[i]
		for i in range(self.num - 2, -1, -1):
			self.seg[i] = segfunc(self.seg[2 * i + 1], self.seg[2 * i + 2])

	def update(self, k, x):
		k += self.num - 1
		self.seg[k] = x
		while k + 1:
			k = (k - 1) // 2
			self.seg[k] = self.segfunc(self.seg[k * 2 + 1], self.seg[k * 2 + 2])

	def query(self, p, q):
		if q <= p:
			return self.ide_ele
		p += self.num - 1
		q += self.num - 2
		res = self.ide_ele
		while q - p > 1:
			if p & 1 == 0:
				res = self.segfunc(res, self.seg[p])
			if q & 1 == 1:
				res = self.segfunc(res, self.seg[q])
				q -= 1
			p = p // 2
			q = (q - 1) // 2
		if p == q:
			res = self.segfunc(res, self.seg[p])
		else:
			res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q])
		return res
N = int(input())
GOTO = [i for i in range(1, N + 1)]
INF = 10 ** 15
ide_ele = -1
SEG = SegTree(GOTO, ide_ele, max)
LIST = []
XX = []
mod = 998244353
for i in range(N):
	(X, D) = map(int, input().split())
	LIST.append([X, D])
LIST.sort(key=lambda x: x[0])
for i in range(N):
	XX.append(LIST[i][0])
import bisect
for i in range(N - 1):
	j = N - 2 - i
	Xj = LIST[j][0]
	Dj = LIST[j][1]
	Nj = bisect.bisect_right(XX, Xj + Dj - 1)
	NEXT = SEG.query(j + 1, Nj)
	if NEXT != -1:
		GOTO[j] = NEXT
		SEG.update(j, NEXT)
S = [-1] * (N + 1)
S[N] = 1
for i in range(N):
	j = N - 1 - i
	S[j] = S[j + 1] + S[GOTO[j]]
	S[j] %= mod
print(S[0])


import sys
import bisect
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)
inf = 10 ** 18
mod = 998244353

class SegmentTree:

	def __init__(self, N, arr=None, op=None, unit=None):
		self.N = N
		self.unit = unit
		self.op = op
		self.tree = [unit] * (2 * N + 1)
		if arr is not None:
			self._build(arr)

	def _build(self, arr):
		op = self.op
		N = self.N
		for (i, a) in enumerate(arr, N):
			self.tree[i] = a
		for i in reversed(range(1, N)):
			self.tree[i] = op(self.tree[i << 1], self.tree[i << 1 | 1])

	def update(self, i, x):
		i += self.N
		op = self.op
		self.tree[i] = x
		while i > 1:
			i >>= 1
			self.tree[i] = op(self.tree[i << 1], self.tree[i << 1 | 1])

	def val(self, i):
		return self.tree[i + self.N]

	def query(self, L, R):
		op = self.op
		res = self.unit
		L += self.N
		R += self.N
		while L < R:
			if L & 1:
				res = op(res, self.tree[L])
				L += 1
			if R & 1:
				R -= 1
				res = op(res, self.tree[R])
			L >>= 1
			R >>= 1
		return res
N = int(input())
XD = list((tuple(map(int, input().split())) for _ in range(N)))
XD.sort()
(X, D) = zip(*XD)
X += (inf,)
seg = SegmentTree(N + 1, None, max, 0)
for L in reversed(range(N)):
	R = bisect.bisect_left(X, X[L] + D[L])
	p = seg.query(L, R)
	seg.update(L, max(L, p))
dp = [0] * (N + 1)
dp[-1] = 1
for i in reversed(range(N)):
	p = seg.val(i)
	dp[i] = (dp[i + 1] + dp[p + 1]) % mod
print(dp[0])


from collections import deque
n = int(input())
info = [list(map(int, input().split())) for i in range(n)]
info = sorted(info, reverse=True)
MOD = 998244353
dp = [0] * (n + 1)
dp[0] = 1
q = deque([])
for i in range(n):
	dp[i + 1] += dp[i]
	(x, d) = info[i]
	(l, r) = (x, x + d)
	num = 1
	while True:
		if not q:
			q.append((l, num))
			break
		(tmp_l, tmp_num) = q.pop()
		if r > tmp_l:
			num = tmp_num + num
		else:
			q.append((tmp_l, tmp_num))
			q.append((l, num))
			break
	num = q[-1][1]
	dp[i + 1] += dp[i + 1 - num]
	dp[i + 1] %= MOD
print(dp[-1])


import sys
sys.setrecursionlimit(2147483647)
INF = 1 << 60
MOD = 998244353
input = lambda : sys.stdin.readline().rstrip()

class SegmentTree(object):

	def __init__(self, A, dot, unit):
		n = 1 << (len(A) - 1).bit_length()
		tree = [unit] * (2 * n)
		for (i, v) in enumerate(A):
			tree[i + n] = v
		for i in range(n - 1, 0, -1):
			tree[i] = dot(tree[i << 1], tree[i << 1 | 1])
		self._n = n
		self._tree = tree
		self._dot = dot
		self._unit = unit

	def __getitem__(self, i):
		return self._tree[i + self._n]

	def update(self, i, v):
		i += self._n
		self._tree[i] = v
		while i != 1:
			i >>= 1
			self._tree[i] = self._dot(self._tree[i << 1], self._tree[i << 1 | 1])

	def add(self, i, v):
		self.update(i, self[i] + v)

	def sum(self, l, r):
		l += self._n
		r += self._n
		l_val = r_val = self._unit
		while l < r:
			if l & 1:
				l_val = self._dot(l_val, self._tree[l])
				l += 1
			if r & 1:
				r -= 1
				r_val = self._dot(self._tree[r], r_val)
			l >>= 1
			r >>= 1
		return self._dot(l_val, r_val)
from bisect import bisect_left

def resolve():
	n = int(input())
	XD = [tuple(map(int, input().split())) for _ in range(n)]
	XD.sort()
	X = [xd[0] for xd in XD]
	tree = SegmentTree([-INF] * n, max, -INF)
	for i in range(n - 1, -1, -1):
		(x, d) = XD[i]
		j = bisect_left(X, x + d)
		tree.update(i, max(j, tree.sum(i + 1, j)))
	dp = [0] * (n + 1)
	dp[n] = 1
	for i in range(n - 1, -1, -1):
		dp[i] += dp[i + 1]
		dp[i] += dp[tree[i]]
		dp[i] %= MOD
	print(dp[0])
resolve()


def examA():
	S = SI()
	if S == 'AAA' or S == 'BBB':
		print('No')
	else:
		print('Yes')
	return

def examB():
	(N, A, B) = LI()
	loop = N // (A + B)
	ans = loop * A + min(A, N % (A + B))
	print(ans)
	return

def examC():
	(A, B) = LI()
	ans = -1
	for i in range(1, 20000):
		if i * 8 // 100 == A:
			if i * 10 // 100 == B:
				ans = i
				break
	print(ans)
	return

def examD():
	S = SI()
	Q = I()
	rev = 0
	L = ''
	R = ''
	for _ in range(Q):
		q = LSI()
		if q[0] == '1':
			rev += 1
		else:
			c = int(q[1])
			if (c + rev) % 2 == 1:
				L += q[2]
			else:
				R += q[2]
	ans = ''
	if rev % 2 == 0:
		ans = L[::-1] + S + R
	else:
		ans = R[::-1] + S[::-1] + L
	print(ans)
	return

def examE():
	(N, P) = LI()
	S = SI()
	A = [0] * (N + 1)
	cur = 0
	if P == 5:
		ans = 0
		for i in range(N):
			if int(S[N - 1 - i]) % 5 == 0:
				ans += N - i
		print(ans)
		return
	elif P == 2:
		ans = 0
		for i in range(N):
			if int(S[N - 1 - i]) % 2 == 0:
				ans += N - i
		print(ans)
		return
	for i in range(N):
		s = int(S[N - 1 - i])
		cur += s * pow(10, i, P)
		A[i + 1] = cur % P
	D = [0] * P
	for a in A:
		D[a] += 1
	ans = 0
	for d in D:
		ans += d * (d - 1) // 2
	print(ans)
	return

def examF():

	def dfs(n, s):
		cur = 1
		can = sum(X[s])
		for i in range(s, n):
			if X[i][0] >= can:
				V[s] = cur
				return (cur, i)
			if i == n - 1:
				return (cur, i)
			(now, visited) = dfs(n, i + 1)
			cur += now
		V[s] = cur
		return (cur, n)
	N = I()
	X = [LI() for _ in range(N)]
	X.sort()
	V = [[] for _ in range(N)]
	neg = 0
	ans = dfs(N, 0)
	print(V)
	print(ans)
	return

def examF2():
	N = I()
	X = [LI() for _ in range(N)]
	N += 1
	X.sort()
	parent = [-1] * N
	stack = [(inf, -1)]
	for (i, (x, d)) in enumerate(X):
		d += x
		while stack[-1][0] <= x:
			stack.pop()
		parent[i] = stack[-1][1]
		stack.append((d, i))
	dp = [1] * N
	ans = 1
	for i in range(N - 1)[::-1]:
		p = parent[i]
		if p == -1:
			ans *= dp[i] + 1
			ans %= mod2
			continue
		dp[p] *= dp[i] + 1
		dp[p] %= mod2
	print(ans)
	return
import sys, copy, bisect, itertools, heapq, math, random
from heapq import heappop, heappush, heapify
from collections import Counter, defaultdict, deque

def I():
	return int(sys.stdin.readline())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LSI():
	return list(map(str, sys.stdin.readline().split()))

def LS():
	return sys.stdin.readline().split()

def SI():
	return sys.stdin.readline().strip()
global mod, mod2, inf, alphabet, _ep
mod = 10 ** 9 + 7
mod2 = 998244353
inf = 10 ** 18
_ep = 10 ** (-12)
alphabet = [chr(ord('a') + i) for i in range(26)]
sys.setrecursionlimit(10 ** 6)
examF2()


import sys
sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline
from bisect import bisect_left
N = int(input())
XD = [[int(i) for i in input().split()] for _ in range(N)]
XD.sort()
MOD = 998244353

def make():
	edge = [[] for _ in range(N)]
	parent = [-1] * N
	MAXIDX = N
	sorted_X = [X for (X, _) in XD]
	for i in range(N - 1, -1, -1):
		idx = bisect_left(sorted_X, XD[i][0] + XD[i][1])
		for j in range(i + 1, min(idx, MAXIDX)):
			if parent[j] < 0:
				parent[j] = i
		if idx >= MAXIDX:
			MAXIDX = i + 1
	for (i, par) in enumerate(parent):
		if par < 0:
			continue
		edge[par].append(i)
	return (parent, edge)
(parent, edge) = make()

def cnt(node):
	if not edge[node]:
		return 2
	res = 1
	for v in edge[node]:
		res = res * cnt(v) % MOD
	res += 1
	return res % MOD

def main():
	ans = 1
	for (i, par) in enumerate(parent):
		if par < 0:
			ans = ans * cnt(i) % MOD
	print(ans)

def __starting_point():
	main()
__starting_point()


import bisect

class SegTree:

	def __init__(self, n):
		self.n = n
		self.s = 1
		while self.s < self.n:
			self.s <<= 1
		self.mins = [1 << 30] * (self.s * 2)

	def update(self, i, val):
		i += self.s
		self.mins[i] = val
		i >>= 1
		while i:
			self.mins[i] = min(self.mins[i * 2], self.mins[i * 2 + 1])
			i >>= 1

	def min(self, l, r):
		l += self.s
		r += self.s
		res = self.mins[0]
		while l <= r:
			if l & 1:
				res = min(res, self.mins[l])
				l += 1
			if not r & 1:
				res = min(res, self.mins[r])
				r -= 1
			l >>= 1
			r >>= 1
		return res
MOD = 998244353
N = int(input())
robots = []
for _ in range(N):
	(x, d) = map(int, input().split())
	robots.append((-x, -d))
robots.sort()
dp = [0] * (N + 1)
dp[0] = 1
st = SegTree(N)
for (i, (x, d)) in enumerate(robots):
	lo = bisect.bisect_right(robots, (x + d, 0), hi=i)
	lo = min(lo, st.min(lo, i))
	st.update(i, lo)
	dp[i + 1] += (dp[i] + dp[lo]) % MOD
print(dp[-1])


import sys
sys.setrecursionlimit(10 ** 9)
MOD = 998244353
N = int(input())
robo = list((list(map(int, input().split())) for i in range(N)))
robo.sort()
child = [[] for i in range(N + 1)]
stack = []
for i in range(N):
	(x, d) = robo[i]
	while stack and stack[-1][0] <= x:
		stack.pop()
	if stack:
		child[stack[-1][1]].append(i + 1)
	else:
		child[0].append(i + 1)
	stack.append([x + d, i + 1])

def func(x):
	hoge = 1
	for i in child[x]:
		hoge *= func(i)
		hoge %= MOD
	return (hoge + 1) % MOD
print(func(0) - 1)


n = int(input())
x = [list(map(int, input().split())) for i in range(n)] + [[10 ** 10]]
x.sort(key=lambda x: x[0])
a = [0] * (n - 1)
y = a + [n]
a += [2, 1]
for i in range(n - 2, -1, -1):
	y[i] = i + 1
	while x[y[i]][0] < sum(x[i]):
		y[i] = y[y[i]]
	a[i] = (a[i + 1] + a[y[i]]) % 998244353
print(a[0])


def main():
	import sys
	sys.setrecursionlimit(10 ** 9)
	input = sys.stdin.readline
	mod = 998244353
	N = int(input())
	robot = [tuple(map(int, input().split())) for _ in range(N)]
	robot.sort()
	stack = []
	dp = [1] * (N + 1)
	for i in reversed(range(N)):
		(x, d) = robot[i]
		while stack and robot[stack[-1]][0] < x + d:
			stack.pop()
		if stack:
			dp[i] = dp[i + 1] + dp[stack[-1]]
		else:
			dp[i] = dp[i + 1] + 1
		dp[i] %= mod
		stack.append(i)
	print(dp[0])
main()


from bisect import bisect
from itertools import accumulate
from functools import reduce
from sys import setrecursionlimit
setrecursionlimit(10000000)
MOD = 998244353

def solve(robots):
	N = len(robots) + 1
	robots.sort()
	parent = [None] * N
	stack = [(float('inf'), 0)]
	for (i, (x, d)) in enumerate(robots, start=1):
		d += x
		while stack[-1][0] <= x:
			stack.pop()
		parent[i] = stack[-1][1]
		while stack[-1][0] <= d:
			stack.pop()
		stack.append((d, i))
	dp = [1] * N
	for i in reversed(range(1, N)):
		p = parent[i]
		dp[p] *= dp[i] + 1
		dp[p] %= MOD
	return dp[0]
N = int(input())
robots = [tuple(map(int, input().split())) for _ in range(N)]
print(solve(robots))


import sys
input = sys.stdin.readline
import bisect
MOD = 998244353
n = int(input())
xd = []
places = [(10 ** 12, 0)]
for _ in range(n):
	(x, d) = [int(item) for item in input().split()]
	xd.append((x, d))
xd.sort(reverse=True)
affect = [0] * (n + 1)
dp = [0] * (n + 1)
dp[0] = 1
for (i, (x, d)) in enumerate(xd):
	frm = x
	too = x + d
	too_idx = i
	while too > places[-1][0]:
		(_, too_idx) = places.pop()
	places.append((frm, too_idx))
	dp[i + 1] = dp[i] + dp[too_idx]
	dp[i + 1] %= MOD
print(dp[-1])


M = 998244353
n = int(input())
r = []
for i in range(n):
	(x, d) = map(int, input().split())
	r.append((x, x + d))
r.sort()
cls = []
dp = [0 for i in range(n + 1)]
dp[n] = 1
for i in range(n - 1, -1, -1):
	ne = i + 1
	while cls:
		(ci, cne) = cls[-1]
		if r[ci][0] < r[i][1]:
			cls.pop()
			ne = cne
		else:
			break
	cls.append((i, ne))
	dp[i] = (dp[i + 1] + dp[ne]) % M
print(dp[0])


from heapq import heappush, heappop
import sys
input = sys.stdin.readline
mod = 998244353
N = int(input())
XD = [tuple(map(int, input().split())) for _ in range(N)]
XD.sort(key=lambda x: x[0])
children = [[] for _ in range(N)]
pq = []
for (i, (x, d)) in list(enumerate(XD))[::-1]:
	while pq and pq[0][0] < x + d:
		(y, j) = heappop(pq)
		children[i].append(j)
	heappush(pq, (x, i))
val = [0] * N
for i in range(N)[::-1]:
	res = 1
	for j in children[i]:
		res = res * val[j] % mod
	val[i] = res + 1
ans = 1
while pq:
	(x, i) = heappop(pq)
	ans = ans * val[i] % mod
print(ans)


def main():
	from collections import deque
	import sys
	sys.setrecursionlimit(10 ** 7)
	input = sys.stdin.readline
	n = int(input())
	X = sorted([list(map(int, input().split())) for i in range(n)])
	mod = 998244353
	e = [[] for i in range(n)]

	def dfs(x):
		count = 1
		for i in e[x]:
			count *= dfs(i)
			count %= mod
		return count + 1
	q = deque([])
	for i in range(n - 1, -1, -1):
		(a, b) = X[i]
		while q and q[0][0] < a + b:
			e[i].append(q[0][1])
			q.popleft()
		q.appendleft([a, i])
	ans = 1
	for (i, j) in q:
		ans *= dfs(j)
		ans %= mod
	print(ans)
main()


import sys
input = sys.stdin.readline

def solve():
	MOD = 998244353
	N = int(input())
	XDs = [tuple(map(int, input().split())) for _ in range(N)] + [(10 ** 12, 0)]
	XDs.sort()
	Xs = [X for (X, D) in XDs]
	stack = [N]
	dp = [0] * (N + 1)
	dp[-1] = 1
	for i in reversed(list(range(N))):
		(X, D) = XDs[i]
		while Xs[stack[-1]] < X + D:
			stack.pop()
		dp[i] = dp[stack[-1]] + dp[i + 1]
		dp[i] %= MOD
		stack.append(i)
	print(dp[0])
solve()


from bisect import bisect_left
import sys
input = sys.stdin.readline
N = int(input())
XD = [[int(i) for i in input().split()] for _ in range(N)]
mod = 998244353
XD.sort()

class SegTree:

	def __init__(self, n, v, f):
		i = 1
		while i < n:
			i <<= 1
		self.n = i
		self.v = v
		self.f = f
		self.tree = [v] * (i << 1)

	def update(self, i, x):
		i += self.n - 1
		self.tree[i] = x
		while i > 0:
			i = (i - 1) // 2
			self.tree[i] = self.f(self.tree[i * 2 + 1], self.tree[i * 2 + 2])

	def query(self, l, r):
		l = l + self.n
		r = r + self.n
		s = self.v
		while l < r:
			if r & 1:
				r -= 1
				s = self.f(s, self.tree[r - 1])
			if l & 1:
				s = self.f(s, self.tree[l - 1])
				l += 1
			l >>= 1
			r >>= 1
		return s
INF = 1 << 60
ST = SegTree(N, -INF, max)
xs = [x for (x, _) in XD]
for i in range(N - 1, -1, -1):
	(x, d) = XD[i]
	j = bisect_left(xs, x + d)
	ST.update(i, max(i, ST.query(i, j)))
dp = [0] * (N + 1)
dp[N] = 1
for i in range(N):
	dp[i] += dp[i - 1]
	dp[i] %= mod
	j = ST.query(i, i + 1)
	dp[j] += dp[i - 1]
	dp[j] %= mod
print(dp[N - 1])


MOD = 998244353
N = int(input())
robots = []
for _ in range(N):
	(x, d) = map(int, input().split())
	robots.append((x, d))
robots.sort(reverse=True)
dp = [0] * (N + 1)
los = [N] * (N + 1)
dp[0] = 1
los[0] = 0
for (i, (x, d)) in enumerate(robots):
	lo = i
	while lo > 0 and robots[lo - 1][0] < x + d:
		lo = los[lo]
	los[i + 1] = lo
	dp[i + 1] += (dp[i] + dp[lo]) % MOD
print(dp[-1])


N = int(input())
(R, d, f, s, x) = (sorted((list(map(int, input().split())) for i in range(N))) + [(2000000000.0, 0)], [0] * N + [1], [0] * N, 1, N)
for i in range(N - 1, -1, -1):
	while R[x][0] < sum(R[i]):
		x = f[x]
	d[i] = s = (s + d[x]) % 998244353
	(f[i], x) = (x, i)
print(d[0])


import sys
from bisect import bisect_left as bl
input = sys.stdin.readline
N = int(input())
mod = 998244353
a = []
xs = [0] * N
for _ in range(N):
	(x, d) = map(int, input().split())
	a.append((x, d))
a.sort()
for i in range(N):
	xs[i] = a[i][0]

class SegTree:

	def segfunc(self, x, y):
		return max(x, y)

	def __init__(self, n, ide_ele, init_val):
		self.ide_ele = ide_ele
		self.num = 2 ** (n - 1).bit_length()
		self.seg = [self.ide_ele] * 2 * self.num
		for i in range(n):
			self.seg[i + self.num - 1] = init_val[i]
		for i in range(self.num - 2, -1, -1):
			self.seg[i] = self.segfunc(self.seg[2 * i + 1], self.seg[2 * i + 2])

	def update(self, k, x):
		k += self.num - 1
		self.seg[k] = x
		while k + 1:
			k = (k - 1) // 2
			self.seg[k] = self.segfunc(self.seg[k * 2 + 1], self.seg[k * 2 + 2])

	def query(self, p, q):
		if q <= p:
			return self.ide_ele
		p += self.num - 1
		q += self.num - 2
		res = self.ide_ele
		while q - p > 1:
			if p & 1 == 0:
				res = self.segfunc(res, self.seg[p])
			if q & 1 == 1:
				res = self.segfunc(res, self.seg[q])
				q -= 1
			p = p // 2
			q = (q - 1) // 2
		if p == q:
			res = self.segfunc(res, self.seg[p])
		else:
			res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q])
		return res
seg = SegTree(N, 0, [0] * N)
for l in range(N - 1, -1, -1):
	r = bl(xs, a[l][0] + a[l][1])
	mx = max(l, seg.query(l, r))
	seg.update(l, mx)
dp = [0] * (N + 1)
dp[0] = 1
for i in range(N):
	dp[i + 1] += dp[i]
	dp[i + 1] %= mod
	dp[seg.query(i, i + 1) + 1] += dp[i]
	dp[i + 1] %= mod
print(dp[-1])


from sys import setrecursionlimit
setrecursionlimit(10000000)
n = int(input())
xds = [tuple(map(int, input().split())) for _ in range(n)]
xds.sort()
xds.insert(0, (-1000000001, 2000000004))
n += 1

def make_blocks(i):
	(x, d) = xds[i]
	right = x + d
	res = []
	nexti = i + 1
	while nexti < n:
		(xn, dn) = xds[nexti]
		if xn < right:
			(l, lasti) = make_blocks(nexti)
			res.append(l)
			nexti = lasti + 1
		else:
			return (res, nexti - 1)
	return (res, n - 1)
(l, _) = make_blocks(0)

def count(l):
	ans = 1
	for ll in l:
		ans = ans * (1 + count(ll)) % 998244353
	return ans
print(count(l))


n = int(input())
a = sorted((tuple(map(int, input().split())) for i in range(n)))
a.append((10 ** 18, 1))
mo = 998244353
dp = [0] * (n + 1)
dp[n] = 1
f = list(range(n))
fr = list(range(n))
bd = [x + d for (x, d) in a]

def getF(u):
	if f[f[u]] != f[u]:
		f[u] = getF(f[u])
		return f[u]
	return f[u]

def uniF(u, v):
	u = getF(u)
	v = getF(v)
	if u == v:
		return
	f[u] = v
	fr[v] = max(fr[v], fr[u])
	bd[v] = max(bd[v], bd[u])
for i in range(n - 1, -1, -1):
	cur = i
	while fr[getF(cur)] + 1 < n and a[fr[getF(cur)] + 1][0] < bd[getF(cur)]:
		uniF(cur, fr[getF(cur)] + 1)
	dp[i] = (dp[i + 1] + dp[fr[getF(cur)] + 1]) % mo
print(dp[0])


import sys
INF = 1 << 60
MOD = 998244353
sys.setrecursionlimit(2147483647)
input = lambda : sys.stdin.buffer.readline().rstrip()
from bisect import bisect_left

class LazySegmentTree(object):

	def __init__(self, A, dot, unit, compose, identity, act):
		logn = (len(A) - 1).bit_length()
		n = 1 << logn
		tree = [unit] * (2 * n)
		for (i, v) in enumerate(A):
			tree[i + n] = v
		for i in range(n - 1, 0, -1):
			tree[i] = dot(tree[i << 1], tree[i << 1 | 1])
		(self._n, self._logn, self._tree, self._lazy) = (n, logn, tree, [identity] * (2 * n))
		(self._dot, self._unit, self._compose, self._identity, self._act) = (dot, unit, compose, identity, act)

	def _ascend(self, i):
		(tree, lazy, dot, act) = (self._tree, self._lazy, self._dot, self._act)
		while i > 1:
			i >>= 1
			tree[i] = act(lazy[i], dot(tree[i << 1], tree[i << 1 | 1]))

	def _descend(self, i):
		(tree, lazy, identity, compose, act) = (self._tree, self._lazy, self._identity, self._compose, self._act)
		for k in range(self._logn, 0, -1):
			p = i >> k
			f = lazy[p]
			(tree[p << 1], lazy[p << 1]) = (act(f, tree[p << 1]), compose(f, lazy[p << 1]))
			(tree[p << 1 | 1], lazy[p << 1 | 1]) = (act(f, tree[p << 1 | 1]), compose(f, lazy[p << 1 | 1]))
			lazy[p] = identity

	def range_act(self, l, r, f):
		l += self._n
		r += self._n
		(l0, r0) = (l, r)
		(tree, lazy, act, compose) = (self._tree, self._lazy, self._act, self._compose)
		while l < r:
			if l & 1:
				(tree[l], lazy[l]) = (act(f, tree[l]), compose(f, lazy[l]))
				l += 1
			if r & 1:
				r -= 1
				(tree[r], lazy[r]) = (act(f, tree[r]), compose(f, lazy[r]))
			l >>= 1
			r >>= 1
		self._ascend(l0)
		self._ascend(r0 - 1)

	def sum(self, l, r):
		l += self._n
		r += self._n
		l_val = r_val = self._unit
		(tree, dot) = (self._tree, self._dot)
		while l < r:
			if l & 1:
				l_val = dot(l_val, tree[l])
				l += 1
			if r & 1:
				r -= 1
				r_val = dot(tree[r], r_val)
			l >>= 1
			r >>= 1
		return dot(l_val, r_val)
from operator import add

def resolve():
	n = int(input())
	XD = [tuple(map(int, input().split())) for _ in range(n)]
	XD.sort()
	X = [a[0] for a in XD]
	A = [0] * n
	A[-1] = 1

	def compose(f, g):
		return f if f != INF else g

	def act(f, x):
		return f if f != INF else x
	tree = LazySegmentTree(A, add, 0, compose, INF, act)
	for i in range(n - 2, -1, -1):
		x = tree.sum(i + 1, n)
		tree.range_act(i, i + 1, (x + 1) % MOD)
		(x, d) = XD[i]
		j = bisect_left(X, x + d)
		tree.range_act(i + 1, j, 0)
	print((tree.sum(0, n) + 1) % MOD)
resolve()


mod = 998244353
(N, *XD) = map(int, open(0).read().split())
XD = sorted(zip(*[iter(XD)] * 2), reverse=True)
S = [(10000000000.0, 0)]
dp = [1] + [0] * N
for (i, (x, d)) in enumerate(XD):
	j = i
	while S[-1][0] < x + d:
		(_, j) = S.pop()
	S.append((x, j))
	dp[i + 1] = (dp[i] + dp[j]) % mod
print(dp[-1])


from heapq import *
N = int(input())
X = [list(map(int, input().split())) for i in range(N)]
X.sort(reverse=True)
Q = []
heapify(Q)
Y = 0
mod = 998244353
for i in range(N):
	Y = 1
	while len(Q):
		if Q[0][0] < X[i][0] + X[i][1]:
			Y = Y * Q[0][1] % mod
			heappop(Q)
		else:
			break
	heappush(Q, (X[i][0], Y + 1))
P = 1
while len(Q):
	P = P * heappop(Q)[1] % mod
print(P)


def main():
	mod = 998244353
	n = int(input())
	ab = sorted([tuple(map(int, input().split())) for _ in [0] * n])
	next_idx = [-1] * n
	for i in range(n - 1, -1, -1):
		dist = sum(ab[i])
		now = i
		while now < n - 1:
			(a1, b1) = ab[now + 1]
			if a1 < dist:
				now = next_idx[now + 1]
			else:
				break
		next_idx[i] = now
	dp = [0] * (n + 1)
	dp[n] = 1
	for i in range(n - 1, -1, -1):
		dp[i] = (dp[i + 1] + dp[next_idx[i] + 1]) % mod
	print(dp[0])
main()


from collections import deque
n = int(input())
info = [list(map(int, input().split())) for i in range(n)]
MOD = 998244353
info = [(10 ** 10, 10 ** 10)] + sorted(info, reverse=True)
dp = [0] * (n + 1)
dp[0] = 1
q = deque([])
for i in range(n):
	if sum(info[i + 1]) <= info[i][0]:
		dp[i + 1] = 2 * dp[i]
		dp[i + 1] %= MOD
		q.append((i, info[i]))
	elif sum(info[i + 1]) <= q[-1][1][0]:
		dp[i + 1] = dp[i] + dp[q[-1][0]]
		dp[i + 1] %= MOD
	else:
		while q:
			q.pop()
			if sum(info[i + 1]) <= q[-1][1][0]:
				dp[i + 1] = dp[i] + dp[q[-1][0]]
				dp[i + 1] %= MOD
				break
print(dp[-1] % MOD)


import sys, math, itertools, collections, bisect
input = lambda : sys.stdin.buffer.readline().rstrip().decode('utf-8')
inf = float('inf')
mod = 998244353
mans = 998244353
ans = 0
count = 0
pro = 1
sys.setrecursionlimit(10 ** 6)
n = int(input())
XD = [tuple(map(int, input().split())) for i in range(n)]
XD.append((-10 ** 10, inf))
XD.sort()
now = 0
visited1 = []

def dfs(node):
	visited1.append(node)
	global now
	pro = 1
	while now < n:
		if XD[now + 1][0] < XD[node][0] + XD[node][1]:
			now += 1
			pro *= dfs(now)
			pro %= mod
		else:
			break
	return pro + 1
ans = dfs(0)
print((ans - 1) % mod)


def i1():
	return int(input())

def i2():
	return [int(i) for i in input().split()]
import bisect
mod = 998244353
n = int(input())
d = []
N = 1 << n.bit_length()
t = [-1 for i in range(2 * N - 1)]

def ud(i, x):
	i += N - 1
	t[i] = x
	while i:
		i = i - 1 >> 1
		if t[i * 2 + 1] > t[i * 2 + 2]:
			t[i] = t[i * 2 + 1]
		else:
			t[i] = t[i * 2 + 2]

def qr(a, b):
	a += N - 1
	b += N - 1
	L = -1
	R = -1
	while a < b:
		if a & 1 == 0:
			if L < t[a]:
				L = t[a]
		if b & 1 == 0:
			b -= 1
			if R < t[b]:
				R = t[b]
		a >>= 1
		b >>= 1
	return max(L, R)
for i in range(n):
	d.append([int(i) for i in input().split()])
d.sort()
dx = []
dd = []
for (i, j) in d:
	dx.append(i)
	dd.append(j)
for i in range(n)[::-1]:
	tx = dx[i] + dd[i]
	j = bisect.bisect_left(dx, tx)
	tt = qr(i, j)
	if j - 1 > tt:
		ud(i, j - 1)
	else:
		ud(i, tt)
dp = [0 for i in range(n + 1)]
dp[-1] = 1
for i in range(n)[::-1]:
	dp[i] += dp[i + 1]
	dp[i] %= mod
	dp[i] += dp[t[i + N - 1] + 1]
	dp[i] %= mod
print(dp[0])


mod = 998244353
n = 0
x = []
d = []

def search(s):
	lo = 0
	hi = n - 1
	while lo <= hi:
		mid = (lo + hi) // 2
		if s > x[mid]:
			lo = mid + 1
		elif s < x[mid]:
			hi = mid - 1
		else:
			return mid
	return max(lo, hi)

def __starting_point():
	xd = []
	n = int(input())
	for i in range(n):
		(xi, di) = map(int, input().split())
		xd.append((xi, di))
	xd.sort()
	x = list(map(lambda x: x[0], xd))
	d = list(map(lambda x: x[1], xd))
	dp = [0] * (n + 1)
	dp[-1] = 1
	next = [0] * n
	st = []
	st.append((n, 2000000000.0))
	for i in range(n - 1, -1, -1):
		while st[-1][1] < x[i] + d[i]:
			st.pop()
		next[i] = st[-1][0]
		st.append((i, x[i]))
	for i in range(n - 1, -1, -1):
		dp[i] = (dp[next[i]] + dp[i + 1]) % mod
	print(dp[0])
__starting_point()


from heapq import *
import sys
sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.readline())

def MI():
	return map(int, sys.stdin.readline().split())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def SI():
	return sys.stdin.readline()[:-1]

def main():

	def dfs(i):
		res = 1
		for j in to[i]:
			res = res * dfs(j) % md
		return res + 1
	md = 998244353
	n = II()
	xd = LLI(n)
	xd.sort(reverse=True)
	to = [[] for _ in range(n)]
	hp = []
	for (i, (x, d)) in enumerate(xd):
		while hp and hp[0][0] < x + d:
			(px, pi) = heappop(hp)
			to[i].append(pi)
		heappush(hp, (x, i))
	ans = 1
	while hp:
		(_, i) = heappop(hp)
		ans = ans * dfs(i) % md
	print(ans)
main()


import sys
sys.setrecursionlimit(10 ** 7)
MOD = 998244353

def init(G, robots, fs, p):
	q = p
	while q < len(robots) and robots[q][0] < robots[p][0] + robots[p][1]:
		if fs[q]:
			G[p].append(q)
			fs[q] = False
			q = init(G, robots, fs, q) - 1
		q += 1
	return q

def calc(G, p, fs):
	fs[p] = False
	if len(G[p]) == 0:
		return 2
	tmp = 1
	for v in G[p]:
		tmp *= calc(G, v, fs)
		tmp %= MOD
	tmp += 1
	return tmp

def main():
	n = int(input())
	robots = [list(map(int, input().split())) for _ in range(n)]
	G = [[] for _ in range(n)]
	robots.sort(key=lambda x: x[0])
	fs = [True] * n
	q = 0
	while q < n:
		if fs[q]:
			fs[q] = False
			init(G, robots, fs, q)
		else:
			q += 1
	fs = [True] * n
	ans = 1
	for i in range(n):
		if fs[i]:
			ans *= calc(G, i, fs)
			ans %= MOD
	print(ans % MOD)
main()


import numpy as np
import collections
Robot = collections.namedtuple('Robot', ['l', 'r'])
N = int(input())
MOD = 998244353
robots = []
for _ in range(N):
	(x, d) = map(int, input().split())
	robots.append(Robot(x, x + d))
robots.sort()
robots.append(Robot(10 ** 10, 10 ** 10 + 1))
stack = [N]
dp = np.zeros(N + 1, dtype=int)
dp[N] = 1
for i in range(N - 1, -1, -1):
	while robots[stack[-1]].l < robots[i].r:
		stack.pop()
	j = stack[-1]
	dp[i] = (dp[i + 1] + dp[j]) % MOD
	stack.append(i)
print(dp[0])


N = int(input())
XD = []
for _ in range(N):
	(x, d) = map(int, input().split())
	XD.append((x, x + d))
MOD = 998244353
XD.sort(reverse=True)
sei = [(10 ** 9, 0)]
pattern = [0] * (N + 1)
pattern[0] = 1
for (i, (s, e)) in enumerate(XD):
	ei = i
	while e > sei[-1][0]:
		(_, ei) = sei.pop()
	sei.append((s, ei))
	pattern[i + 1] = (pattern[i] + pattern[ei]) % MOD
print(pattern[-1])


import sys
import bisect
from collections import deque
sys.setrecursionlimit(10 ** 7)
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
N = int(readline())
MOD = 998244353
XD = [[int(x) for x in readline().split()] for _ in range(N)]
XD.sort()
NXT = deque()
E = [[] for _ in range(N)]
for i in range(N - 1, -1, -1):
	(x, d) = XD[i]
	while NXT:
		(j, nx) = NXT.pop()
		if nx < x + d:
			E[i].append(j)
		else:
			NXT.append((j, nx))
			break
	NXT.append((i, x))

def dfs(i):
	rtn = 1
	for v in E[i]:
		rtn *= dfs(v)
		rtn %= MOD
	return rtn + 1
ans = 1
for (i, x) in NXT:
	ans *= dfs(i)
	ans %= MOD
print(ans % MOD)


import sys
sys.setrecursionlimit(10 ** 9)
mod = 998244353

def init_max(init_max_val, n):
	for i in range(n):
		seg_max[i + num_max - 1] = init_max_val[i]
	for i in range(num_max - 2, -1, -1):
		seg_max[i] = max(seg_max[2 * i + 1], seg_max[2 * i + 2])

def update_max(k, x):
	k += num_max - 1
	seg_max[k] = x
	while k:
		k = (k - 1) // 2
		seg_max[k] = max(seg_max[k * 2 + 1], seg_max[k * 2 + 2])

def query_max(p, q):
	if q <= p:
		return ide_ele_max
	p += num_max - 1
	q += num_max - 2
	res = ide_ele_max
	while q - p > 1:
		if p & 1 == 0:
			res = max(res, seg_max[p])
		if q & 1 == 1:
			res = max(res, seg_max[q])
			q -= 1
		p = p // 2
		q = (q - 1) // 2
	if p == q:
		res = max(res, seg_max[p])
	else:
		res = max(max(res, seg_max[p]), seg_max[q])
	return res
ide_ele_max = -1
num_max = 1 << 18
seg_max = [ide_ele_max] * 2 * num_max
N = int(input())
tmpX = []
for i in range(N):
	(x, d) = list(map(int, input().split()))
	tmpX.append((x, d))
tmpX.sort()
(X, D) = ([0] * N, [0] * N)
for i in range(N):
	X[i] = tmpX[i][0]
	D[i] = tmpX[i][1]
to = [0] * N
for i in range(N):
	to[i] = i
init_max(to, N)
for i in range(N - 1, -1, -1):
	ok = i
	ng = N
	while ng - ok > 1:
		mid = (ng + ok) // 2
		if X[i] + D[i] > X[mid]:
			ok = mid
		else:
			ng = mid
	to[i] = query_max(i, ok + 1)
	update_max(i, to[i])
dp = [0] * (N + 1)
dp[0] = 1
for i in range(N):
	dp[i + 1] += dp[i]
	dp[i + 1] %= mod
	dp[to[i] + 1] += dp[i]
	dp[to[i] + 1] %= mod
print(dp[N])


n = int(input())
x = [list(map(int, input().split())) for i in range(n)]
x.sort(key=lambda x: x[0])
x.append([2 * 10 ** 9 + 1, 0])
y = [0] * (n - 1) + [n - 1]
a = [0] * (n - 1) + [2]
for i in range(n - 2, -1, -1):
	j = i + 1
	while x[j][0] < sum(x[i]):
		j = y[j] + 1
	y[i] = j - 1
for i in range(n - 2, -1, -1):
	a[i] = a[y[i] + 1] if y[i] + 1 < n else 1
	a[i] = (a[i] + a[i + 1]) % 998244353
print(a[0])


mod = 998244353
N = int(input())
X = []
for _ in range(N):
	(x, d) = map(int, input().split())
	X.append((x, x + d))
X = sorted(X, key=lambda x: x[0])
L = [(0, -(10 ** 9 + 1), 10 ** 9 + 1)]
P = [-1] * (N + 1)
for (i, (x, y)) in enumerate(X):
	while L[-1][2] <= y:
		if L[-1][2] > x and P[i + 1] < 0:
			P[i + 1] = L[-1][0]
		L.pop()
	if P[i + 1] < 0:
		P[i + 1] = L[-1][0]
	L.append((i + 1, x, y))
C = [[] for _ in range(N + 1)]
for (i, p) in enumerate(P):
	if p >= 0:
		C[p].append(i)
Y = [1] * (N + 1)
for i in range(N + 1)[::-1]:
	s = 1
	for j in C[i]:
		s = s * (Y[j] + 1) % mod
	Y[i] = s
print(Y[0])


INF = 10 ** 18
MOD = 998244353
N = int(input())
robots = [(-INF, INF)]
for _ in range(N):
	(x, d) = map(int, input().split())
	robots.append((x, x + d))
robots.sort()
stack = list()
tree = [[] for _ in range(N + 1)]
for i in range(N + 1)[::-1]:
	(x, r) = robots[i]
	while stack and stack[-1][0] < r:
		(y, j) = stack.pop()
		tree[i].append(j)
	stack.append((x, i))
stack = list()
stack.append(0)
visited = [0 for _ in range(N + 1)]
visited[0] = 1
order = [None for _ in range(N + 1)]
order[0] = 0
od = 0
while stack:
	node = stack.pop()
	for adj in tree[node]:
		if not visited[adj]:
			visited[adj] = 1
			od += 1
			order[od] = adj
			stack.append(adj)
dp = [1 for _ in range(N + 1)]
for node in order[::-1]:
	for adj in tree[node]:
		dp[node] *= dp[adj]
	dp[node] += 1
	dp[node] %= MOD
print(dp[0] - 1)


import heapq
mod = 998244353
n = int(input())
robot = [tuple(map(int, input().split())) for _ in range(n)]
robot.sort(reverse=True)
parent = list(range(n))
root = []
for i in range(n):
	(x, d) = robot[i]
	while root:
		r = heapq.heappop(root)
		if r[0] < x + d:
			parent[r[1]] = i
		else:
			heapq.heappush(root, r)
			break
	heapq.heappush(root, (x, i))
count = 1
dp = [1] * n
for i in range(n):
	p = parent[i]
	if p == i:
		count = count * (dp[i] + 1) % mod
	else:
		dp[p] = dp[p] * (dp[i] + 1) % mod
print(count)


import sys
input = sys.stdin.readline
N = int(input())
XD = [tuple(map(int, input().split())) for i in range(N)]
XD.sort()
MOD = 998244353
ns = [-1] * N
for (i, (x, d)) in reversed(list(enumerate(XD))):
	tmp = i
	while tmp < N - 1:
		(nx, _) = XD[tmp + 1]
		if nx < x + d:
			tmp = ns[tmp + 1]
		else:
			break
	ns[i] = tmp
dp = [0] * (N + 1)
dp[N] = 1
for i in range(N - 1, -1, -1):
	dp[i] = (dp[i + 1] + dp[ns[i] + 1]) % MOD
print(dp[0])


def main():
	mod = 998244353
	n = int(input())
	ab = [tuple(map(int, input().split())) for _ in [0] * n]
	ab.sort()
	next_a = [-1] * n
	dp = [0] * (n + 1)
	dp[n] = 1
	for i in range(n - 1, -1, -1):
		(a0, b0) = ab[i]
		dist = a0 + b0
		now = i
		while now < n - 1:
			(a1, b1) = ab[now + 1]
			if a1 < dist:
				now = next_a[now + 1]
			else:
				break
		next_a[i] = now
	for i in range(n - 1, -1, -1):
		dp[i] = (dp[i + 1] + dp[next_a[i] + 1]) % mod
	print(dp[0] % mod)
main()


import sys
from bisect import bisect_left, bisect_right
input = sys.stdin.readline
ide = 0

def func(a, b):
	return max(a, b)

class SegmentTree:

	def __init__(self, ls, commutative=True):
		if commutative == True:
			self.n = len(ls)
			self.tree = [ide for i in range(self.n)] + ls
		else:
			self.n = 2 ** (len(ls) - 1).bit_length()
			self.tree = [ide for i in range(self.n)] + ls + [ide for i in range(self.n - len(ls))]
		for i in range(1, self.n)[::-1]:
			self.tree[i] = func(self.tree[i << 1 | 0], self.tree[i << 1 | 1])

	def getall(self):
		return self.tree[1]

	def get(self, l, r):
		lret = ide
		rret = ide
		l += self.n
		r += self.n
		while l < r:
			if l & 1:
				lret = func(lret, self.tree[l])
				l += 1
			if r & 1:
				rret = func(self.tree[r - 1], rret)
			l >>= 1
			r >>= 1
		ret = func(lret, rret)
		return ret

	def update(self, i, x):
		i += self.n
		self.tree[i] = x
		while i > 1:
			i >>= 1
			self.tree[i] = func(self.tree[i << 1 | 0], self.tree[i << 1 | 1])
n = int(input())
xd = [list(map(int, input().split())) for i in range(n)]
mod = 998244353
xd.sort()
xls = list(zip(*xd))[0]
rls = [0] * n
st = SegmentTree(rls)
for i in range(n)[::-1]:
	idx = bisect_left(xls, xd[i][0] + xd[i][1]) - 1
	x = st.get(i, idx + 1)
	st.update(i, max(i, x))
dp = [0] * n
dp[-1] = 2
for i in range(n - 1)[::-1]:
	x = st.get(i, i + 1)
	if x == n - 1:
		dp[i] = dp[i + 1] + 1
	else:
		dp[i] = dp[i + 1] + dp[x + 1]
	dp[i] %= mod
print(dp[0])


import sys
from bisect import bisect_left

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
sys.setrecursionlimit(10 ** 9)
INF = 10 ** 18
MOD = 998244353

class SegTree:

	def __init__(self, n, func, intv, A=[]):
		self.n = n
		self.func = func
		self.intv = intv
		n2 = 1
		while n2 < n:
			n2 <<= 1
		self.n2 = n2
		self.tree = [self.intv] * (n2 << 1)
		if A:
			for i in range(n):
				self.tree[n2 + i] = A[i]
			for i in range(n2 - 1, -1, -1):
				self.tree[i] = self.func(self.tree[i * 2], self.tree[i * 2 + 1])

	def update(self, i, x):
		i += self.n2
		self.tree[i] = x
		while i > 0:
			i >>= 1
			self.tree[i] = self.func(self.tree[i * 2], self.tree[i * 2 + 1])

	def query(self, a, b):
		l = a + self.n2
		r = b + self.n2
		s = self.intv
		while l < r:
			if r & 1:
				r -= 1
				s = self.func(s, self.tree[r])
			if l & 1:
				s = self.func(s, self.tree[l])
				l += 1
			l >>= 1
			r >>= 1
		return s

	def get(self, i):
		return self.tree[i + self.n2]

	def all(self):
		return self.tree[1]

	def print(self):
		for i in range(self.n):
			print(self.get(i), end=' ')
		print()
N = INT()
XD = []
for _ in range(N):
	(x, d) = MAP()
	XD.append((x, d))
XD.sort()
(X, _) = zip(*XD)
X = list(X)
X += [INF]
st = SegTree(N + 1, max, -INF)
st.update(N, N)
for i in range(N - 1, -1, -1):
	(x, d) = XD[i]
	j = bisect_left(X, x + d)
	mx = st.query(i, j)
	st.update(i, max(i, mx))
dp = [0] * (N + 1)
dp[N] = 1
for i in range(N - 1, -1, -1):
	dp[i] += dp[i + 1]
	dp[i] += dp[st.get(i) + 1]
	dp[i] %= MOD
ans = dp[0]
print(ans)


import bisect
import sys
sys.setrecursionlimit(10 ** 6)
INF = 10 ** 6

class SegTree:

	def __init__(self, N):
		self.N = N
		self.data = [-INF] * (2 * N - 1)

	def update(self, i, x):
		n = self.N + i - 1
		self.data[n] = x
		while n > 0:
			n = (n - 1) // 2
			self.data[n] = max(self.data[2 * n + 1], self.data[2 * n + 2])

	def elem(self, i):
		return self.data[self.N + i - 1]

	def _query(self, a, b, k, l, r):
		if r <= a or b <= l:
			return -INF
		if a <= l and r <= b:
			return self.data[k]
		val_left = self._query(a, b, 2 * k + 1, l, (l + r) // 2)
		val_right = self._query(a, b, 2 * k + 2, (l + r) // 2, r)
		return max(val_left, val_right)

	def query(self, a, b):
		return self._query(a, b, 0, 0, self.N)

def main():
	MOD = 998244353
	N = int(input())
	robot_list = [list(map(int, input().split())) for _ in range(N)]
	robot_list.sort()
	X = [robot[0] for robot in robot_list]
	D = [robot[1] for robot in robot_list]
	PW_N = 1
	while PW_N < N:
		PW_N *= 2
	next_robot_tree = SegTree(PW_N)
	next_robot_tree.update(N - 1, N)
	for n in range(N - 2, -1, -1):
		if X[n] + D[n] <= X[n + 1]:
			next_robot_tree.update(n, n + 1)
		else:
			next_robot = bisect.bisect_left(X, X[n] + D[n])
			next_robot = next_robot_tree.query(n, next_robot)
			next_robot_tree.update(n, next_robot)
	cnt = [0] * (N + 1)
	cnt[0] = 1
	for n in range(N):
		cnt[n + 1] += cnt[n]
		cnt[n + 1] %= MOD
		next_robot = next_robot_tree.elem(n)
		cnt[next_robot] += cnt[n]
		cnt[next_robot] %= MOD
	print(cnt[N])
main()


import bisect
import sys
input = sys.stdin.readline

class SegmentTreeRMQ(object):

	def __init__(self, size, value):
		self.len = 1 << size.bit_length()
		self.array = [value] * (2 * self.len)

	def update(self, i, x):
		i += self.len
		while i > 0:
			self.array[i] = max(self.array[i], x)
			i >>= 1

	def get(self, i):
		return self.array[i + self.len]

	def get_maximum(self, l, r):
		L = l + self.len
		R = r + self.len
		ANS = -1 << 30
		while L < R:
			if L & 1:
				ANS = max(ANS, self.array[L])
				L += 1
			if R & 1:
				R -= 1
				ANS = max(ANS, self.array[R])
			L >>= 1
			R >>= 1
		return ANS
N = int(input())
xd_array = [list(map(int, input().split())) for _ in range(N)]
xd_array = sorted(xd_array, key=lambda x: x[0])
x_array = [i[0] for i in xd_array]
d_array = [i[1] for i in xd_array]
mod = 998244353
tree = SegmentTreeRMQ(N, -1)
ans_array = [0] * (N + 1)
ans_array[-1] = 1
for i in range(N - 1, -1, -1):
	move = x_array[i] + d_array[i] - 0.1
	max_index = bisect.bisect_left(x_array, move)
	max_move = max(i, tree.get_maximum(i, max_index))
	tree.update(i, max_move)
	ans_array[i] = (ans_array[i + 1] + ans_array[max_move + 1]) % mod
print(ans_array[0])


import sys
input = sys.stdin.readline
mod = 998244353
N = int(input())
XD = [tuple(map(int, input().split())) for _ in range(N)]
XD.sort(key=lambda x: x[0])
children = [[] for _ in range(N)]
stack = []
for (i, (x, d)) in list(enumerate(XD))[::-1]:
	while stack and stack[-1][0] < x + d:
		(y, j) = stack.pop()
		children[i].append(j)
	stack.append((x, i))
val = [0] * N
for i in range(N)[::-1]:
	res = 1
	for j in children[i]:
		res = res * val[j] % mod
	val[i] = res + 1
ans = 1
for (x, i) in stack:
	ans = ans * val[i] % mod
print(ans)


import sys
input = lambda : sys.stdin.readline().rstrip()
M = 998244353
n = int(input())
xs = [0] * n
ds = [0] * n
for i in range(n):
	(x, d) = (int(c) for c in input().split())
	ds[i] = d
	xs[i] = (x, i)
import sys
sys.setrecursionlimit(max(1000, n))
xs.sort()
index = [x[1] for x in xs]
xs = [x[0] for x in xs]
ds = [ds[ind] for ind in index]

def _sub(i):
	if i == n - 1:
		return (2, n)
	res = 1
	ind = i + 1
	while True:
		if xs[i] + ds[i] <= xs[ind]:
			break
		(o, ind) = _sub(ind)
		res *= o
		res %= M
		if ind >= n:
			break
	return (res + 1, ind)
out = []
done = 0
while True:
	(o, done) = _sub(done)
	out.append(o)
	if done >= n:
		break
result = 1
for o in out:
	result *= o
	result %= M
print(result)


import sys
from operator import itemgetter
(n, *xd) = map(int, sys.stdin.buffer.read().split())
MOD = 998244353
xd = sorted(zip(xd[0::2], xd[1::2]))
xxx = list(map(itemgetter(0), xd)) + [10 ** 10]
ans = [0] * n + [1]
stack = [n]
for i in range(n - 1, -1, -1):
	(x, d) = xd[i]
	r = x + d
	while r > xxx[stack[-1]]:
		stack.pop()
	ans[i] = (ans[i + 1] + ans[stack[-1]]) % MOD
	stack.append(i)
print(ans[0])


n = int(input())
l = [tuple(map(int, input().split())) for _ in range(n)] + [(1 << 31, 0)]
mod = 998244353
l.sort()
st = [n]
dp = [0] * n + [1]
for i in range(n - 1, -1, -1):
	(x, d) = l[i]
	v = x + d
	while l[st[-1]][0] < v:
		st.pop()
	dp[i] = (dp[i + 1] + dp[st[-1]]) % mod
	st.append(i)
print(dp[0])


import sys
input = sys.stdin.readline
N = int(input())
robot = []
for i in range(N):
	(x, d) = map(int, input().split())
	robot.append((x, d))
mod = 998244353
robot.sort()
move = [i for i in range(0, N)]
for i in range(0, N):
	(x, d) = robot[i]
	start = i
	end = N - 1
	while end - start > 1:
		test = (end + start) // 2
		if x + d > robot[test][0]:
			start = test
		else:
			end = test
	if x + d > robot[end][0]:
		move[i] = end
	else:
		move[i] = start
n = N

def segfunc(x, y):
	return max(x, y)

def init(init_val):
	for i in range(n):
		seg[i + num - 1] = init_val[i]
	for i in range(num - 2, -1, -1):
		seg[i] = segfunc(seg[2 * i + 1], seg[2 * i + 2])

def update(k, x):
	k += num - 1
	seg[k] = x
	while k:
		k = (k - 1) // 2
		seg[k] = segfunc(seg[k * 2 + 1], seg[k * 2 + 2])

def query(p, q):
	if q <= p:
		return ide_ele
	p += num - 1
	q += num - 2
	res = ide_ele
	while q - p > 1:
		if p & 1 == 0:
			res = segfunc(res, seg[p])
		if q & 1 == 1:
			res = segfunc(res, seg[q])
			q -= 1
		p = p // 2
		q = (q - 1) // 2
	if p == q:
		res = segfunc(res, seg[p])
	else:
		res = segfunc(segfunc(res, seg[p]), seg[q])
	return res
ide_ele = 0
num = 2 ** (n - 1).bit_length()
seg = [ide_ele] * 2 * num
chain = [i for i in range(N)]
for _ in range(0, N):
	i = N - 1 - _
	if move[i] == i:
		chain[i] = i
		update(i, chain[i])
	else:
		chain[i] = query(i + 1, move[i] + 1)
		update(i, chain[i])
dp = [0 for i in range(0, N + 1)]
dp[N] = 1
for j in range(0, N):
	i = N - 1 - j
	if chain[i] == i:
		dp[i] = 2 * dp[i + 1] % mod
	else:
		dp[i] = (dp[i + 1] + dp[chain[i] + 1]) % mod
print(dp[0])


import sys
input = sys.stdin.readline
from bisect import bisect_left

class SegmentTree:

	def __init__(self, param, default, func):
		if isinstance(param, list):
			n = len(param)
		else:
			n = param
		self.d = default
		self.leaf = 1 << (n - 1).bit_length()
		if isinstance(param, list):
			self.tree = [default] * (self.leaf - 1) + param + [default] * (self.leaf - n)
			for i in range(self.leaf - 2, -1, -1):
				self.tree[i] = func(self.tree[i * 2 + 1], self.tree[i * 2 + 2])
		else:
			self.tree = [default] * (self.leaf * 2 - 1)
		self.f = func

	def find(self, i):
		return self.tree[i + self.leaf - 1]

	def update(self, idx, a):
		idx += self.leaf - 1
		self.tree[idx] = a
		while idx:
			idx = idx - 1 >> 1
			self.tree[idx] = self.merge(self.tree[idx * 2 + 1], self.tree[idx * 2 + 2])

	def merge(self, a, b):
		return self.f(a, b)

	def get_top(self):
		return self.tree[0]

	def query(self, a, b):
		T = self.tree
		(l, r) = (a + self.leaf - 1, b + self.leaf - 1)
		res = self.d
		while l < r:
			if not l % 2:
				res = self.merge(res, T[l])
				l += 1
			if not r % 2:
				r -= 1
				res = self.merge(res, T[r])
			l >>= 1
			r >>= 1
		return res

def main():
	mod = 998244353
	n = int(input())
	XD = [list(map(int, input().split())) for _ in range(n)]
	XD.sort()
	X = [x for (x, d) in XD]
	seg = SegmentTree(n, -1, max)
	DP = [0] * (n + 1)
	DP[-1] = 1
	for i in reversed(range(n)):
		(x, d) = XD[i]
		j = bisect_left(X, x + d)
		r = max(i, seg.query(i + 1, j))
		seg.update(i, r)
		DP[i] = (DP[i + 1] + DP[r + 1]) % mod
	print(DP[0])
main()