Buggy python submission (verdict: Time Limit Exceeded):
import sys
from bisect import bisect_left
from operator import itemgetter
class SegmentTree(object):
    # 検証: https://atcoder.jp/contests/nikkei2019-2-qual/submissions/8434117
    # 参考: https://atcoder.jp/contests/abc014/submissions/3935971
    __slots__ = ["elem_size", "tree", "default", "op", "real_size"]

    def __init__(self, a, default, op):
        self.default = default
        self.op = op
        if hasattr(a, "__iter__"):
            self.real_size = len(a)
            self.elem_size = elem_size = 1 << (self.real_size-1).bit_length()
            self.tree = tree = [default] * (elem_size * 2)
            tree[elem_size:elem_size + self.real_size] = a
            for i in range(elem_size - 1, 0, -1):
                tree[i] = op(tree[i << 1], tree[(i << 1) + 1])
        elif isinstance(a, int):
            self.real_size = a
            self.elem_size = elem_size = 1 << (self.real_size-1).bit_length()
            self.tree = [default] * (elem_size * 2)

    def get_value(self, x: int, y: int) -> int:  # 半開区間
        l, r = x + self.elem_size, y + self.elem_size
        tree, result, op = self.tree, self.default, self.op
        while l < r:
            if l & 1:
                result = op(tree[l], result)
                l += 1
            if r & 1:
                r -= 1
                result = op(tree[r], result)
            l, r = l >> 1, r >> 1
        return result

    def set_value(self, i: int, value: int) -> None:
        k = self.elem_size + i
        op, tree = self.op, self.tree
        tree[k] = value
        while k > 1:
            k >>= 1
            tree[k] = op(tree[k << 1], tree[(k << 1) + 1])

    def get_one_value(self, i):
        return self.tree[i+self.elem_size]

    def debug(self):
        print(self.tree[self.elem_size:self.elem_size+self.real_size])

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(list(range(N)), 0, lambda a,b: a if a>b else b)
    for i, (x, d) in zip(range(N-1,-1,-1), XD[::-1]):
        r = bisect_left(X, x+d, lo=i)
        seg.set_value(i, seg.get_value(i, r))
    D2 = seg.tree[seg.elem_size:seg.elem_size+seg.real_size]
    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()


Fixed submission:
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()