CodeEff/ECCO huggingface dataset:
# Original solution
N, K = list(map(int, input().split()))
has_snack = [False]*N
# has_snack: 1つ以上のお菓子を持っているかどうか
# has_snack[i] = True なら、すぬけ君i+1は1つ以上のお菓子を持っている

for i in range(K):
    d = int(eval(input()))  # d を読む (使わないけど)
    A = list(map(int, input().split()))  # A を読む
    for v in A:  # A の各要素 v について、
        has_snack[v-1] = True  # すぬけ君vは1つ以上のお菓子を持っている

# sum(has_snack) で1つ以上のお菓子を持っているすぬけ君の人数を求める
# ↑ 暗黙に、Trueは1、Falseは0に変換される
# 求めたいのは1つも持っていないすぬけ君の人数なので、総数Nから引く
print((N - sum(has_snack)))

# Optimized solution
N, K = list(map(int, input().split()))

# setについての詳細:
# https://docs.python.org/ja/3/library/stdtypes.html#set-types-set-frozenset

has_snack = set()  # 1つ以上のお菓子を持っているすぬけ君を入れておくset
for i in range(K):
    d = int(eval(input()))  # d を読む（使わないけど）
    A = set(map(int, input().split()))  # A を set として読む
    has_snack |= A  # has_snackとの和集合を求め、それをhas_snackに代入

# len(has_snack) でhas_snackの要素数を求め、総数 N から引く
print((N-len(has_snack)))
# Original solution
n, k = list(map(int, input().split()))

A = [-1] * n

for i in range(k):
    d = int(eval(input()))
    a = list(map(int, input().split()))
    for j in range(d):
        x = a[j]-1
        if A[x] == -1:
            A[x] = a[j]-1

ans = 0
for i in range(n):
    if A[i] == -1:
        ans += 1

print(ans)


# Optimized solution
n, k = list(map(int, input().split()))
s = []

for _ in range(k):
    d = int(eval(input()))
    t = list(map(int, input().split()))
    for i in range(len(t)):
        s.append(t[i])

l = set(s)

print((n - len(l)))
# Original solution
n, k = list(map(int, input().split()))
N = [i for i in range(1, n+1)]
ans = []
for i in range(k):
    d = int(eval(input()))
    a = list(map(int, input().split()))
    for j in a:
        ans.append(j)
count = 0
for x in N:
    if x not in ans:
        count += 1
print(count)

# Optimized solution
n, k = list(map(int, input().split()))
ans = set()
for i in range(k):
    d = int(eval(input()))
    a = list(map(int, input().split()))
    for j in a:
        ans.add(j)
print((n-len(ans)))
# Original solution
N, K = list(map(int, input().split()))

n = dict()
for i in range(K):
    ds = int(eval(input()))
    d = list(map(int, input().split()))
    for j in range(ds):
        n[d[j] - 1] = 1

print((N - len(n)))


# Optimized solution
N, K = list(map(int, input().split()))

n = set()
for i in range(K):
    ds = eval(input())
    n = n | set(input().split())

print((N - len(n)))
# Original solution
n, k = list(map(int, input().split()))
a = []
d = []
for i in range(k):
    d = int(eval(input()))
    a += list(map(int, input().split()))

a_set=set(a)
a_set=list(a_set)
print((n-len(a_set)))

# Optimized solution
n, k = list(map(int, input().split()))
a = []
for i in range(k):
    d = int(eval(input()))
    a.extend(list(map(int, input().split())))

a_set = set(a)

a_set = list(a_set)

print((n - len(a_set)))
# Original solution
n,k = list(map(int,input().split()))
t = [True for i in range(n)]
for i in range(k):
    d = int(eval(input()))
    a = list(map(int,input().split()))
    for j in range(d):
        t[a[j]-1] = False
count = 0
for i in t:
    if i:
        count+=1
print(count)

# Optimized solution
n,k = list(map(int,input().split()))
su = [True for i in range(n)]
for i in range(k):
    d = int(eval(input()))
    a = list(map(int,input().split()))
    for j in range(d):
        su[a[j]-1] = False
count = 0
for i in range(n):
    if su[i]:
        count+=1
print(count)
# Original solution
n, k = list(map(int, input().split()))
a = []

for i in range(k):
    d = int(eval(input()))
    ai = list(map(int, input().split()))
    a = a+ai

a = set(a)
ans = 0

for i in range(1, n+1):
    if i not in a:
        ans += 1

print(ans)

# Optimized solution
n, k = list(map(int, input().split()))
a = []

for i in range(k):
    d = int(eval(input()))
    ai = list(map(int, input().split()))
    a = a + ai

print((n-len(set(a))))
# Original solution
n,k=list(map(int,input().split()))
ans=[0]*n
for i in range(k):
    d=int(eval(input()))
    a=list(map(int,input().split()))
    for j in a:
        ans[j-1]=1
print((n-sum(ans)))



# Optimized solution
N, K = list(map(int, input().split()))
A = set()
for _ in range(K):
  d = eval(input())
  A = A.union(set(map(int, input().split())))
print((N - len(A)))
# Original solution
N, K = list(map(int,input().split()))
counts = [0 for i in range(N)]

for i in range(K):
    d = int(eval(input()))
    A = list(map(int,input().split()))
    for a in A:
        counts[a-1] += 1
    
print((counts.count(0)))

# Optimized solution
N, K = list(map(int,input().split()))
counts = [0]*N
for i in range(K):
    d = int(eval(input()))
    A = list(map(int,input().split()))
    for a in A:
        counts[a-1] += 1

print((counts.count(0)))
# Original solution
import sys
sys.setrecursionlimit(10 ** 5 + 10)
def input(): return sys.stdin.readline().strip()

def resolve():

    n,k=list(map(int,input().split()))
    c=[False]*n
    for i in range(k):
        d=int(eval(input()))
        A=list(map(int,input().split()))
        for j in A:
            if c[j-1]==False:
                c[j-1]=True
    print((n-sum(c)))



resolve()

# Optimized solution
import sys
sys.setrecursionlimit(10 ** 5 + 10)
def input(): return sys.stdin.readline().strip()

def resolve():
    
    N,K=list(map(int,input().split()))
    S=[0]*N
    for i in range(K):
        d=int(eval(input()))
        A=list(map(int,input().split()))
        for i in range(len(A)):
            S[A[i]-1]+=1
    
    print((S.count(0)))

    
resolve()
# Original solution
from operator import itemgetter
N = int(eval(input()))
a = [tuple(map(int, input().split())) for _ in [0]*N]
ans = float("inf")

a.sort()
for (x1, y1), (x2, y2) in zip(a, a[1:]):
    dist = (x1-x2)**2 + (y1-y2)**2
    if ans > dist:
        ans = dist

a.sort(key=itemgetter(1))
for (x1, y1), (x2, y2) in zip(a, a[1:]):
    dist = (x1-x2)**2 + (y1-y2)**2
    if ans > dist:
        ans = dist

print(ans)


# Optimized solution
import sys
from operator import itemgetter
N = int(eval(input()))
a = sorted(tuple(map(int, l.split())) for l in sys.stdin.readlines())
ans = float("inf")

for (x1, y1), (x2, y2) in zip(a, a[1:]):
    dist = (x1-x2)**2 + (y1-y2)**2
    if ans > dist:
        ans = dist

a.sort(key=itemgetter(1))
for (x1, y1), (x2, y2) in zip(a, a[1:]):
    dist = (x1-x2)**2 + (y1-y2)**2
    if ans > dist:
        ans = dist

print(ans)
# Original solution
# -*- coding: utf-8 -*-
"""
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0585

"""
import sys
from sys import stdin
from collections import namedtuple
input = stdin.readline


def closest_part(points, n):
    # ?????¬???p324???
    if n <= 1:
        return float('inf')
    m = n // 2
    x = points[m].x
    d = min(closest_part(points[:m], m), closest_part(points[m:], n-m))

    points.sort(key=lambda p:p.y)
    b = []
    for p in points:
        if (p.x - x)**2 >= d:
            continue
        for j in range(len(b)):
            dx = p.x - b[-j-1].x
            dy = p.y - b[-j-1].y
            if dy**2 >= d:
                break
            d = min(d, (dx**2 + dy**2))
        b.append(p)
    return d

pos = namedtuple('pos', ['x', 'y'])
def main(args):
    n = int(eval(input()))
    points = [pos(*list(map(int, input().split()))) for _ in range(n)]
    points.sort()               #  x????????§??????????????????

    result = closest_part(points, n)
    print(result)


if __name__ == '__main__':
    main(sys.argv[1:])

# Optimized solution
# -*- coding: utf-8 -*-
"""
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0585

"""
import sys
from sys import stdin
from collections import namedtuple
input = stdin.readline


def closest_part(points, n):
    # ?????¬???p324???
    if n <= 1:
        return float('inf')
    m = n // 2
    x = points[m][0]
    d = min(closest_part(points[:m], m), closest_part(points[m:], n-m))

    points.sort(key=lambda p:p[1])
    b = []
    for p in points:
        if (p[0] - x)**2 >= d:
            continue
        for q in b[::-1]:
            # dx = p[0] - b[-j-1][0]
            # dy = p[1] - b[-j-1][1]
            dx = p[0] - q[0]
            dy = p[1] - q[1]
            if dy**2 >= d:
                break
            d = min(d, (dx**2 + dy**2))
        b.append(p)
    return d

def main(args):
    n = int(eval(input()))
    points = [tuple(map(int, input().split())) for _ in range(n)]
    points.sort()               #  x????????§??????????????????

    result = closest_part(points, n)
    print(result)


if __name__ == '__main__':
    main(sys.argv[1:])
# Original solution
# -*- coding: utf-8 -*-
"""
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0585

"""
import sys
from sys import stdin
from collections import namedtuple
input = stdin.readline


def closest_part(points, n):
    # ?????¬???p324???
    if n <= 1:
        return float('inf')
    m = n // 2
    x = points[m][0]
    d = min(closest_part(points[:m], m), closest_part(points[m:], n-m))

    points.sort(key=lambda p:p[1])
    b = []
    for p in points:
        if (p[0] - x)**2 >= d:
            continue
        for q in b[::-1]:
            # dx = p[0] - b[-j-1][0]
            # dy = p[1] - b[-j-1][1]
            dx = p[0] - q[0]
            dy = p[1] - q[1]
            if dy**2 >= d:
                break
            d = min(d, (dx**2 + dy**2))
        b.append(p)
    return d

def main(args):
    n = int(eval(input()))
    points = [tuple(map(int, input().split())) for _ in range(n)]
    points.sort()               #  x????????§??????????????????

    result = closest_part(points, n)
    print(result)


if __name__ == '__main__':
    main(sys.argv[1:])

# Optimized solution
# -*- coding: utf-8 -*-
"""
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0585

"""
import sys
from sys import stdin
input = stdin.readline


def closest_part(points, n):
    # ?????¬???p324???
    if n <= 1:
        return float('inf')
    m = n // 2
    x = points[m][0]
    d = min(closest_part(points[:m], m), closest_part(points[m:], n-m))

    points.sort(key=lambda p:p[1])
    b = []
    for p in points:
        if (p[0] - x)**2 >= d:
            continue
        for q in b:
            dx = p[0] - q[0]
            dy = p[1] - q[1]
            if dy**2 >= d:
                break
            d = min(d, (dx**2 + dy**2))
        b.insert(0, p)
    return d


def main(args):
    n = int(eval(input()))
    points = [tuple(map(int, input().split())) for _ in range(n)]
    points.sort()               #  x????????§??????????????????

    result = closest_part(points, n)
    print(result)


if __name__ == '__main__':
    main(sys.argv[1:])
# Original solution
n=int(eval(input()))-1
A=list(map(int,input().split()))
i=0
for j in range(n):
 if A[j]<=A[-1]:A[i],A[j]=A[j],A[i];i+=1
A[i],A[n]=A[n],A[i]
print((" ".join(map(str,A[:i]))+" ["+str(A[i])+"] "+" ".join(map(str,A[i+1:]))))


# Optimized solution
def s():
 n=int(eval(input()))-1
 A=list(map(int,input().split()))
 i=0
 for j in range(n):
  if A[j]<=A[-1]:A[i],A[j]=A[j],A[i];i+=1
 A[i],A[n]=A[n],A[i]
 print((" ".join(map(str,A[:i]))+" ["+str(A[i])+"] "+" ".join(map(str,A[i+1:]))))
if'__main__'==__name__:s()
# Original solution
class Partition:
    def partion(self, a, p, r): 
        x = a[-1]
        i = p - 1
        for j in range(p, r):
            if a[j] <= x:
                i += 1
                a[i], a[j] = a[j], a[i]
        # a[i + 1], a[-1] = a[-1], a[i + 1]
        return((a, i))

if __name__ == '__main__':
    n = int(input().rstrip())
    a = [int(x) for x in input().rstrip().split(" ")]
    x = Partition()
    a, i = x.partion(a, 0, n)
    res = []
    for j in range(len(a)):
        if j == i:
            res.append("[{}]".format(a[j]))
        else:
            res.append(str(a[j]))
    print((" ".join(res)))

# Optimized solution
class Partition:
    def partion(self, a, p, r): 
        x = a[r]
        i = p - 1
        for j in range(p, r):
            if a[j] <= x:
                i += 1
                a[i], a[j] = a[j], a[i]
        a[i + 1], a[r] = a[r], a[i + 1]
        return(i+1)

if __name__ == '__main__':
    n = int(input().rstrip())
    a = [int(x) for x in input().rstrip().split(" ")]
    x = Partition()
    i = x.partion(a, 0, n-1)
    a = [str(i) for i in a]
    a[i] = "[{}]".format(a[i])
    print((" ".join(a)))
# Original solution
def partition(A, p, r):
    x = A[r - 1]
    i = p - 1
    for j in range(p, r-1):
        if A[j] <= x:
            i += 1
            temp = A[i]
            A[i] = A[j]
            A[j] = temp
    temp = A[i+1]
    A[i+1] = A[r-1]
    A[r-1] = temp
    return i




if __name__ == '__main__':
    # ??????????????\???
    # A = [13, 19, 9, 5, 12, 8, 7, 4, 21, 2, 6, 11]
    num_of_data = int(eval(input()))
    A = [int(x) for x in input().split(' ')]

    # ???????????????
    p = partition(A, 0, len(A))

    # ???????????¨???
    left = A[:p+1]
    partition = A[p+1]
    right = A[p+2:]
    print(('{0} [{1}] {2}'.format(' '.join(map(str, left)), partition, ' '.join(map(str, right)))))

# Optimized solution
def partition(A, p, r):
    x = A[r]
    i = p - 1
    for j in range(p, r):
        if A[j] <= x:
            i += 1
            temp = A[i]
            A[i] = A[j]
            A[j] = temp
    temp = A[i+1]
    A[i+1] = A[r]
    A[r] = temp
    return i




if __name__ == '__main__':
    # ??????????????\???
    # A = [13, 19, 9, 5, 12, 8, 7, 4, 21, 2, 6, 11]
    num_of_data = int(eval(input()))
    A = [int(x) for x in input().split(' ')]

    # ???????????????
    p = partition(A, 0, len(A)-1)

    # ???????????¨???
    left = A[:p+1]
    partition = A[p+1]
    right = A[p+2:]
    print(('{0} [{1}] {2}'.format(' '.join(map(str, left)), partition, ' '.join(map(str, right)))))
# Original solution
from heapq import heappush, heappop
import sys
input = sys.stdin.readline

mod = 998244353
N = int(eval(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)

# Optimized solution
import sys
input = sys.stdin.readline

mod = 998244353
N = int(eval(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)
# Original solution
class SegmentTreeMax():
  def __init__(self,n,init):
    self.offset=2**((n-1).bit_length())
    self.tree=[init]*(2*self.offset)
    self.init=init
  def update(self,pos,val):
    pos+=self.offset
    self.tree[pos]=val
    while pos>1:
      pos=pos//2
      self.tree[pos]=max(self.tree[2*pos],self.tree[2*pos+1])
  def query(self,l,r):
    l+=self.offset
    r+=self.offset
    ret=self.init
    while l<=r:
      ret=max(ret,self.tree[r])
      r=(r-1)//2
      ret=max(ret,self.tree[l])
      l=(l+1)//2
    return ret

mod=998244353
n=int(eval(input()))
arr=[list(map(int,input().split())) for _ in range(n)]
arr=sorted(arr,key=lambda x:x[0])
st=SegmentTreeMax(n,0)
ranges=[]
for i in range(n):
  x=arr[i][0]+arr[i][1]
  l=-1
  r=n
  while r-l!=1:
    mid=(l+r)//2
    if arr[mid][0]>=x:
      r=mid
    else:
      l=mid
  ranges.append(l)
  st.update(i,r)
for i in range(n-1,-1,-1):
  ranges[i]=st.query(i,ranges[i])
  st.update(i,ranges[i])
dp=[0]*(n+1)
dp[-1]=1
for i in range(n-1,-1,-1):
  j=ranges[i]
  dp[i]=dp[i+1]+dp[j]
  dp[i]%=mod
print((dp[0]))

# Optimized solution
class SegmentTreeMax():
  def __init__(self,n,init):
    self.offset=2**((n-1).bit_length())
    self.tree=[init]*(2*self.offset)
    self.init=init
  def update(self,pos,val):
    pos+=self.offset
    self.tree[pos]=val
    while pos>1:
      pos=pos//2
      self.tree[pos]=max(self.tree[2*pos],self.tree[2*pos+1])
  def query(self,l,r):
    l+=self.offset
    r+=self.offset
    ret=self.init
    while l<=r:
      ret=max(ret,self.tree[r])
      r=(r-1)//2
      ret=max(ret,self.tree[l])
      l=(l+1)//2
    return ret

mod=998244353
n=int(eval(input()))
arr=[list(map(int,input().split())) for _ in range(n)]
arr=sorted(arr,key=lambda x:x[0])
st=SegmentTreeMax(n,0)
ranges=[]
for i in range(n):
  x=arr[i][0]+arr[i][1]
  l=-1
  r=n
  while r-l!=1:
    mid=(l+r)//2
    if arr[mid][0]>=x:
      r=mid
    else:
      l=mid
  ranges.append(r-1)
  st.update(i,r-1)
for i in range(n-1,-1,-1):
  ranges[i]=st.query(i,ranges[i])
  st.update(i,ranges[i])
dp=[0]*(n+1)
dp[-1]=1
for i in range(n-1,-1,-1):
  j=ranges[i]+1
  dp[i]=dp[i+1]+dp[j]
  dp[i]%=mod
print((dp[0]))
# Original solution
from bisect import bisect_left, bisect_right
MOD = 998244353

class SegmentTree:
    def __init__(self, n, func=lambda x, y: min(x, y), ide=float("inf")):
        self.n = 2 ** (n-1).bit_length()
        self.data = [ide] * (self.n*2)
        self.func, self.ide = func, ide
    
    def build(self, data):
        for i, x in enumerate(data):
            self.data[self.n+i] = x
        for i in range(self.n-1, 0, -1):
            self.data[i] = self.func(self.data[i*2], self.data[i*2+1])

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

    def query(self, l, r):
        l += self.n; r += self.n 
        res = self.ide
        while l < r:
            if l & 1:
                res = self.func(res, self.data[l])
                l += 1
            if r & 1:
                res = self.func(res, self.data[r-1])
            l //= 2; r //= 2
        return res
    
    def get(self, i):
        return self.data[self.n + i]

n = int(eval(input()))
xd = [tuple(map(int, input().split())) for _ in range(n)]
xd.sort()
x, d = list(zip(*xd))

s = SegmentTree(n, lambda x, y: max(x, y), -float("inf"))
for i in range(n)[::-1]:
    r = bisect_left(x, x[i]+d[i])
    s.update(i, max(r-1, s.query(i, r)))

dp = [[0] * 2 for _ in range(n)]
dp[-1][0], dp[-1][1] = 1, 1

for i in range(n-1)[::-1]:
    dp[i][0] = dp[i+1][0] + dp[i+1][1] % MOD
    dp[i][1] = dp[s.get(i)][0]

print((sum(dp[0]) % MOD))


# Optimized solution
import sys
from bisect import bisect_left, bisect_right
input = lambda: sys.stdin.readline()
MOD = 998244353

class SegmentTree:
    def __init__(self, n, func=lambda x, y: min(x, y), ide=float("inf")):
        self.n = 2 ** (n-1).bit_length()
        self.data = [ide] * (self.n*2)
        self.func, self.ide = func, ide
    
    def build(self, data):
        for i, x in enumerate(data):
            self.data[self.n+i] = x
        for i in range(self.n-1, 0, -1):
            self.data[i] = self.func(self.data[i*2], self.data[i*2+1])

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

    def query(self, l, r):
        l += self.n; r += self.n 
        res = self.ide
        while l < r:
            if l & 1:
                res = self.func(res, self.data[l])
                l += 1
            if r & 1:
                res = self.func(res, self.data[r-1])
            l >>= 1; r >>= 1
        return res
    
    def get(self, i):
        return self.data[self.n + i]

n = int(eval(input()))
xd = [tuple(map(int, input().split())) for _ in range(n)]
xd.sort()
x, d = list(zip(*xd))

s = SegmentTree(n, lambda x, y: max(x, y), -float("inf"))
for i in range(n)[::-1]:
    r = bisect_left(x, x[i]+d[i])
    s.update(i, max(r-1, s.query(i, r)))

dp1, dp2 = [0] * n, [0] * n
dp1[-1], dp2[-1] = 1, 1

for i in range(n-1)[::-1]:
    dp1[i] = dp1[i+1] + dp2[i+1] % MOD
    dp2[i] = dp1[s.get(i)]

print(((dp1[0] + dp2[0]) % MOD))
# Original solution
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)


if __name__ == "__main__":
    xd = []
    n = int(eval(input()))
    for i in range(n):
        xi, di = list(map(int, input().split()))
        xd.append((xi, di))

    xd.sort()
    x = list([x[0] for x in xd])
    d = list([x[1] for x in xd])

    dp = [0] * (n+1)
    dp[-1] = 1
    next = [0] * n

    for i in range(n-1, -1, -1):
        currend = search(x[i] + d[i])
        j =  i+1
        while j < currend:
            currend = max(search(x[j] + d[j]), currend)
            j += 1
        next[i] = currend

    for i in range(n - 1, -1, -1):
        dp[i] = (dp[next[i]] + dp[i + 1]) % mod
    
    print((dp[0]))
    
    # print(x, d)
    # print(dp)
    # print(next)



# Optimized solution
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)


if __name__ == "__main__":
    xd = []
    n = int(eval(input()))
    for i in range(n):
        xi, di = list(map(int, input().split()))
        xd.append((xi, di))

    xd.sort()
    x = list([x[0] for x in xd])
    d = list([x[1] for x in xd])

    dp = [0] * (n+1)
    dp[-1] = 1
    next = [0] * n

    st = []
    st.append((n, 2e9))

    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]))
# Original solution
from bisect import bisect_left, bisect_right
import sys
input = sys.stdin.readline

def solve():
    MOD = 998244353
    INF = float('inf')

    N = int(eval(input()))
    XDs = [tuple(map(int, input().split())) for _ in range(N)] + [(10**12, 0)]

    XDs.sort()
    Xs = [X for X, D in XDs]

    def max2(x, y): return x if x >= y else y
    def makeBIT(numEle):
        numPow2 = 2 ** (numEle-1).bit_length()
        data = [-INF] * (numPow2+1)
        return data, numPow2
    def setInit(As):
        for iB, A in enumerate(As, 1):
            data[iB] = A
        for iB in range(1, numPow2):
            i = iB + (iB & -iB)
            data[i] = max2(data[i], data[iB])
    def setValue(iA, A):
        iB = iA + 1
        while iB <= numPow2:
            data[iB] = max2(data[iB], A)
            iB += iB & -iB
    def getMax(iA):
        iB = iA + 1
        ans = -INF
        while iB > 0:
            ans = max2(ans, data[iB])
            iB -= iB & -iB
        return ans

    data, numPow2 = makeBIT(N+1)
    setInit(list(range(N)))

    dp = [0] * (N+1)
    dp[-1] = 1
    for i in reversed(list(range(N))):
        X, D = XDs[i]
        j = bisect_left(Xs, X+D) - 1
        pos = getMax(j)
        setValue(i, pos)
        dp[i] = dp[pos+1] + dp[i+1]
        dp[i] %= MOD

    print((dp[0]))


solve()


# Optimized solution
import sys
input = sys.stdin.readline

def solve():
    MOD = 998244353

    N = int(eval(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()