Problem:
Score : 600 points

Problem Statement

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 1

2
1 5
3 3

Sample Output 1

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.

Sample Input 2

3
6 5
-1 10
3 3

Sample Output 2

5

There are five possible sets of robots remaining on the number line: \{1, 2, 3\}, \{1, 2\}, \{2\}, \{2, 3\}, and \{\}.

Sample Input 3

4
7 10
-10 3
4 3
-4 3

Sample Output 3

16

None of the robots influences others.

Sample Input 4

20
-8 1
26 4
0 5
9 1
19 4
22 20
28 27
11 8
-3 20
-25 17
10 4
-18 27
24 28
-11 19
2 27
-2 18
-1 12
-24 29
31 29
29 7

Sample Output 4

110

Remember to print the count modulo 998244353.

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Time Limit Exceeded)

import java.util.*;
import java.io.*;
import java.text.*;
public class Main{
    //SOLUTION BEGIN
    //Into the Hardware Mode
    void pre() throws Exception{}
    void solve(int TC)throws Exception {
        int n = ni();
        long[][] p = new long[n][];
        TreeSet<Long> set = new TreeSet<>();
        for(int i = 0; i< n; i++){
            p[i] = new long[]{nl(), nl()};
            set.add(p[i][0]);
            set.add(p[i][0]+p[i][1]);
        }
        HashMap<Long, Integer> mp = new HashMap<>();
        int c = 0;
        for(long l:set)mp.put(l, c++);
        c++;
        long[] dp = new long[c];
        Arrays.sort(p, (long[] l1, long[] l2) -> Long.compare(l1[0], l2[0]));
        int ptr = n-1;
        long MOD = 998244353;
        SegTree t = new SegTree(c);
        int[] end = new int[n];
        for(int i = c-1; i>= 0; i--){
            if(mp.get(p[ptr][0]) == i){
                int u = mp.get(p[ptr][0]), v = mp.get(p[ptr][0]+p[ptr][1]);
                end[ptr] = Math.max(v, t.mx(u, v-1));
                t.u(u, v, end[ptr]);
                ptr--;
            }
        }
        ptr = n-1;
        for(int i = c-1; i >= 0; i--){
            if(i+1 < c)dp[i] = dp[i+1];
            if(mp.get(p[ptr][0]) == i){
                dp[i] += dp[end[ptr]]+1;
                if(dp[i] >= MOD)dp[i] -= MOD;
                ptr--;
            }
        }
        pn((dp[0]+1)%MOD);
    }
    class SegTree{
        int m = 1;
        int[] mx, lazy;
        public SegTree(int n){
            while(m<n)m<<=1;
            mx = new int[m<<1];
            lazy = new int[m<<1];
        }
        void push(int i){
            if(lazy[i] != 0){
                mx[i] = Math.max(mx[i], lazy[i]);
                if(i< m){
                    lazy[i<<1] = Math.max(lazy[i<<1], lazy[i]);
                    lazy[i<<1|1] = Math.max(lazy[i<<1|1], lazy[i]);
                }
                lazy[i] = 0;
            }
        }
        void u(int l, int r, int x){u(l, r, x, 0, m-1, 1);}
        void u(int l, int r, int x, int ll, int rr, int i){
            push(i);
            if(l == ll && r == rr){
                lazy[i] = x;
                push(i);
                return;
            }
            int mid = (ll+rr)>>1;
            if(r <= mid){
                u(l, r, x, ll, mid, i<<1);
                push(i<<1|1);
            }else if(l > mid){
                push(i<<1);
                u(l, r, x, mid+1, rr, i<<1|1);
            }else{
                u(l, mid,x, ll, mid, i<<1);
                u(mid+1, r, x, mid+1, rr, i<<1|1);
            }
            mx[i] = Math.max(mx[i<<1], mx[i<<1|1]);
        }
        int mx(int l, int r){return mx(l, r, 0, m-1, 1);}
        int mx(int l, int r, int ll, int rr, int i){
            push(i);
            if(l == ll && r == rr)return mx[i];
            int mid = (ll+rr)>>1;
            if(r <= mid)return mx(l, r, ll, mid, i<<1);
            else if(l > mid)return mx(l, r, mid+1, rr, i<<1|1);
            else return Math.max(mx(l, mid, ll, mid, i<<1), mx(mid+1, r, mid+1, rr, i<<1|1));
        }
    }
    //SOLUTION END
    void hold(boolean b)throws Exception{if(!b)throw new Exception("Hold right there, Sparky!");}
    void exit(boolean b){if(!b)System.exit(0);}
    //    long IINF = (long)1e15;
    final int INF = (int)1e9+2, MX = (int)2e6+5;
    DecimalFormat df = new DecimalFormat("0.00000000000");
    double PI = 3.141592653589793238462643383279502884197169399, eps = 1e-8;
    static boolean multipleTC = false, memory = false, fileIO = false;
    FastReader in;PrintWriter out;
    void run() throws Exception{
        long ct = System.currentTimeMillis();
        if (fileIO) {
            in = new FastReader("");
            out = new PrintWriter("");
        } else {
            in = new FastReader();
            out = new PrintWriter(System.out);
        }
        //Solution Credits: Taranpreet Singh
        int T = (multipleTC) ? ni() : 1;
        pre();
        for (int t = 1; t <= T; t++) solve(t);
        out.flush();
        out.close();
        System.err.println(System.currentTimeMillis() - ct);
    }
    public static void main(String[] args) throws Exception{
        if(memory)new Thread(null, new Runnable() {public void run(){try{new Main().run();}catch(Exception e){e.printStackTrace();}}}, "1", 1 << 28).start();
        else new Main().run();
    }
    int[][] make(int n, int[] from, int[] to, boolean f){
        int[][] g = new int[n][];int[]cnt = new int[n];
        for(int i:from)cnt[i]++;if(f)for(int i:to)cnt[i]++;
        for(int i = 0; i< n; i++)g[i] = new int[cnt[i]];
        for(int i = 0; i< from.length; i++){
            g[from[i]][--cnt[from[i]]] = to[i];
            if(f)g[to[i]][--cnt[to[i]]] = from[i];
        }
        return g;
    }
    int find(int[] set, int u){return set[u] = (set[u] == u?u:find(set, set[u]));}
    int digit(long s){int ans = 0;while(s>0){s/=10;ans++;}return ans;}
    long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);}
    int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);}
    int bit(long n){return (n==0)?0:(1+bit(n&(n-1)));}
    void p(Object o){out.print(o);}
    void pn(Object o){out.println(o);}
    void pni(Object o){out.println(o);out.flush();}
    String n()throws Exception{return in.next();}
    String nln()throws Exception{return in.nextLine();}
    int ni()throws Exception{return Integer.parseInt(in.next());}
    long nl()throws Exception{return Long.parseLong(in.next());}
    double nd()throws Exception{return Double.parseDouble(in.next());}

    class FastReader{
        BufferedReader br;
        StringTokenizer st;
        public FastReader(){
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastReader(String s) throws Exception{
            br = new BufferedReader(new FileReader(s));
        }

        String next() throws Exception{
            while (st == null || !st.hasMoreElements()){
                try{
                    st = new StringTokenizer(br.readLine());
                }catch (IOException  e){
                    throw new Exception(e.toString());
                }
            }
            return st.nextToken();
        }

        String nextLine() throws Exception{
            String str;
            try{
                str = br.readLine();
            }catch (IOException e){
                throw new Exception(e.toString());
            }
            return str;
        }
    }
}