def numba_compile(numba_config):
    import os, sys
    if sys.argv[-1] == "ONLINE_JUDGE":
        from numba import njit
        from numba.pycc import CC
        cc = CC("my_module")
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature)(func)
            cc.export(func.__name__, signature)(func)
        cc.compile()
        exit()
    elif os.name == "posix":
        exec(f"from my_module import {','.join(func.__name__ for func, _ in numba_config)}")
        for func, _ in numba_config:
            globals()[func.__name__] = vars()[func.__name__]
    else:
        from numba import njit
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature, cache=True)(func)
        print("compiled!", file=sys.stderr)


import sys
from bisect import bisect_left
from operator import itemgetter


import numpy as np

def segment_tree_op(a, b):
    return a if a[0] > b[0] else b

def segment_tree_get(seg, l, r):
    elem_size, tree, result, _ = seg
    l += elem_size
    r += elem_size
    while l < r:
        if l & 1:
            result = segment_tree_op(tree[l], result)
            l += 1
        if r & 1:
            r -= 1
            result = segment_tree_op(tree[r], result)
        l, r = l >> 1, r >> 1
    return result

def segment_tree_set(seg, i, value):
    elem_size, tree, _, _ = seg
    k = elem_size + i
    tree[k] = value
    while k > 1:
        k >>= 1
        tree[k] = segment_tree_op(tree[k<<1], tree[k<<1|1])

def segment_tree_get_one(seg, i):
    elem_size, tree, _, _ = seg
    return tree[i+elem_size]

def segment_tree_construct(arr):
    identity = np.array([0], dtype=np.int64)
    real_size = len(arr)
    elem_size = 1 << int(np.log2(real_size-1))+1
    tree = np.empty((elem_size*2, len(identity)), dtype=np.int64)
    tree[elem_size:elem_size+real_size] = arr
    tree[elem_size+real_size:] = identity
    for i in range(elem_size - 1, 0, -1):
        tree[i] = segment_tree_op(tree[i<<1], tree[i<<1|1])
    return elem_size, tree, identity, real_size

class SegmentTree:
    element_type = "i8[:]"
    a_type = f"Tuple((i8,i8[:,:],{element_type},i8))"
    numba_config = [
        [segment_tree_op, f"{element_type}({element_type},{element_type})"],
        [segment_tree_construct, f"{a_type}(i8[:,:])"],
        [segment_tree_get, f"{element_type}({a_type},i8,i8)"],
        [segment_tree_set, f"void({a_type},i8,{element_type})"],
        [segment_tree_get_one, f"{element_type}({a_type},i8)"],
    ]
    def __init__(self, arr):
        self.a = segment_tree_construct(arr)

    def get(self, l, r):
        return segment_tree_get(self.a, l, r)

    def set(self, i, value):
        return segment_tree_set(self.a, i, value)

    def get_one(self, i):
        return segment_tree_get_one(self.a, i)

numba_compile(SegmentTree.numba_config)

def main():
    mod = 998244353
    N = int(sys.stdin.buffer.readline())
    m = map(int, sys.stdin.buffer.read().split())
    XD = list(zip(m, m))
    XD.sort(key=itemgetter(0))
    X, D = zip(*XD)
    seg = SegmentTree(np.arange(N, dtype=np.int64).reshape(N, 1))
    for i, (x, d) in zip(range(N-1,-1,-1), XD[::-1]):
        r = bisect_left(X, x+d, lo=i)
        seg.set(i, seg.get(i, r))
    D2 = seg.a[1][seg.a[0]:seg.a[0]+seg.a[3]].ravel()
    Q = [0] * N
    ans = 1
    cnt = 1
    for i, d in enumerate(D2):
        ans += cnt
        Q[d] += cnt
        cnt = (cnt + Q[i]) % mod
    print(ans % mod)

main()


Measured memory_bytes: 76552