Buggy python submission (verdict: Time Limit Exceeded):
import sys
sys.setrecursionlimit(10 ** 7)
from bisect import bisect_left

N = int(input())
XD = [[int(i) for i in input().split()] for _ in range(N)]
XD.sort()
MOD = 998244353
sorted_X = [X for X,_ in XD]

edge = [[] for _ in range(N)]

parent = [-1] * N

MAXIDX = N
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)

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

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

print(ans)

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

if __name__ == "__main__":
    main()

Buggy python submission (verdict: Time Limit Exceeded):
import sys
sys.setrecursionlimit(10 ** 7)

N = int(input())
XD = [[int(i) for i in input().split()] for _ in range(N)]
XD.sort()
MOD = 998244353
sorted_X = [X for X,_ in XD]

edge = [[] for _ in range(N)]

from bisect import bisect_left

parent = [-1] * N

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, idx):
        if parent[j] < 0:
            parent[j] = i

for i,par in enumerate(parent):
    if par < 0:
        continue
    edge[par].append(i)

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

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

print(ans)

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

if __name__ == "__main__":
    main()

Buggy python submission (verdict: Runtime Error):
N = int(input())
XD = [[int(i) for i in input().split()] for _ in range(N)]
XD.sort()
MOD = 998244353
sorted_X = [X for X,_ in XD]

edge = [[] for _ in range(N)]

from bisect import bisect_left

parent = [-1] * N

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, idx):
        if parent[j] < 0:
            parent[j] = i

for i,par in enumerate(parent):
    if par < 0:
        continue
    edge[par].append(i)

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

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

print(ans)

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

if __name__ == "__main__":
    main()