Problem:
Score : 400 points

Problem Statement

There are N cells arranged in a row, numbered 1, 2, \ldots, N from left to right.

Tak lives in these cells and is currently on Cell 1. He is trying to reach Cell N by using the procedure described below.

You are given an integer K that is less than or equal to 10, and K non-intersecting segments [L_1, R_1], [L_2, R_2], \ldots, [L_K, R_K].
Let S be the union of these K segments.
Here, the segment [l, r] denotes the set consisting of all integers i that satisfy l \leq i \leq r.

When you are on Cell i, pick an integer d from S and move to Cell i + d. You cannot move out of the cells.

To help Tak, find the number of ways to go to Cell N, modulo 998244353.

Constraints

2 \leq N \leq 2 \times 10^5

1 \leq K \leq \min(N, 10)

1 \leq L_i \leq R_i \leq N

[L_i, R_i] and [L_j, R_j] do not intersect (i \neq j)

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K
L_1 R_1
L_2 R_2
:
L_K R_K

Output

Print the number of ways for Tak to go from Cell 1 to Cell N, modulo 998244353.

Sample Input 1

5 2
1 1
3 4

Sample Output 1

4

The set S is the union of the segment [1, 1] and the segment [3, 4], therefore S = \{ 1, 3, 4 \} holds.

There are 4 possible ways to get to Cell 5:

1 \to 2 \to 3 \to 4 \to 5,

1 \to 2 \to 5,

1 \to 4 \to 5 and

1 \to 5.

Sample Input 2

5 2
3 3
5 5

Sample Output 2

0

Because S = \{ 3, 5 \} holds, you cannot reach to Cell 5.
Print 0.

Sample Input 3

5 1
1 2

Sample Output 3

5

Sample Input 4

60 3
5 8
1 3
10 15

Sample Output 4

221823067

Note that you have to print the answer modulo 998244353.

Solution in C# (.NET Core 3.1.201) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    public static long[] array = new long[200005];
    public static List<long> S = new List<long> { };

    static long Func(int index)
    {

        //Console.WriteLine("!Func start index : " + index);

        long count = 0;

        if(array[index] != 0)
        {
            //Console.WriteLine("!result cache hit! index : " + index + ", count : " + array[index]);
            return array[index];
        }

        foreach (int s in S)
        {
            if (index - s >= 1)
            {
                //Console.WriteLine("index : " + index + ", move : -" + s + ", To Index : " + (index - s));

                if ((index - s) == 1)
                {
                    count++;
                }
                else if((index - s) > 1)
                {
                    long ret = Func(index - s);
                    count += ret;
                }
                else
                {

                }
            }
        }

        //Console.WriteLine("!result cache setting. index : " + index +", count : "+ count);
        array[index] = count;
        return count;
    }


    static void Main(string[] args)
    {
        /////////////////////////////////////////

        //回答
        //Console.WriteLine(Math.Ceiling((double)N / X) * T);
        //Console.WriteLine("");

        //整数の入力
        //int input = int.Parse(Console.ReadLine());

        //文字列の入力
        //string input = Console.ReadLine();

        ////複数の入力
        //string[] line = Console.ReadLine().Split(' ');
        //int a = int.Parse(line[0]);
        //int b = int.Parse(line[1]);

        ///////////////////
        ///複数入力

        //int N = int.Parse(Console.ReadLine());

        //int count = 0;
        //for (int i = 0; i < N; i++)
        //{
        //    string[] inputs = Console.ReadLine().Split(' ');
        //    int[] D = inputs.Select(int.Parse).ToArray();

        //    if (D[0] == D[1])
        //    {
        //        count++;
        //        if (count == 3)
        //        {
        //            Console.WriteLine("Yes");
        //            break;
        //        }

        //    }
        //    else
        //    {
        //        count = 0;
        //    }
        //}
        //if (count != 3)
        //{
        //    Console.WriteLine("No");
        //}
        ///////////////////



        /////////////////////////////////////////


        ////A
        //string input =Console.ReadLine();

        //if(input.EndsWith("s"))
        //{
        //    Console.WriteLine(input.Substring(0, input.Length) + "es");
        //}
        //else
        //{
        //    Console.WriteLine(input + "s");
        //}

        ////B
        //int N = int.Parse(Console.ReadLine());

        //int count = 0;
        //for (int i = 0; i <N; i++)
        //{
        //    string[] inputs = Console.ReadLine().Split(' ');
        //    int[] D = inputs.Select(int.Parse).ToArray();

        //    if(D[0] == D[1])
        //    {
        //        count++;
        //        if(count == 3)
        //        {
        //            Console.WriteLine("Yes");
        //            break;
        //        }

        //    }
        //    else
        //    {
        //        count = 0;
        //    }
        //}
        //if(count != 3)
        //{
        //    Console.WriteLine("No");
        //}

        ////C
        //int N = int.Parse(Console.ReadLine());

        //int count = 0;

        //for (int i = 1; i <= N-1; i++)
        //{
        //    int maxCount = (N-1) / i;
        //    //Console.WriteLine(i + ":" + maxCount);

        //    count += maxCount;
        //}

        //Console.WriteLine(count);

        //D
        //複数の入力
        string[] inputs = Console.ReadLine().Split(' ');
        int N = int.Parse(inputs[0]);
        int K = int.Parse(inputs[1]);

        //public static int[] array = { };
        //public static List<int> S = new List<int>{ };

        for (int i = 0; i < K; i++)
        {
            string[] tmp = Console.ReadLine().Split(' ');
            int L = int.Parse(tmp[0]);
            int R = int.Parse(tmp[1]);

            for (int j = L; j <= R; j++){
                S.Add(j);
            }
        }
        
        S.Sort();
        //Console.WriteLine("[{0}]", string.Join(", ", list));

        Console.WriteLine(Func(N) % 998244353);


        /* 階乗 */
        //long fact = 1;

        ///* 自然数の入力 */
        //int num = int.Parse(Console.ReadLine()) ;


        //double tmp = ((double)num - 1) * num / 2;

        //Console.WriteLine("tmp : " + tmp);
        //Console.WriteLine("Math.Pow(8, num - 2) : " + Math.Pow(8, num - 2));
        //Console.WriteLine("res : " + ((double)tmp * Math.Pow(8, num - 2) * 2) % 1000000007);



        ////複数の入力
        //string[] line = Console.ReadLine().Split(' ');
        //int a = int.Parse(line[0]);
        //int b = int.Parse(line[1]);
        //int c = int.Parse(line[2]);
        //int d = int.Parse(line[3]);

        //if ((double)D/S <= T)
        //{
        //    Console.WriteLine("Yes");
        //}
        //else
        //{
        //    Console.WriteLine("No");
        //}



        ////文字列の入力
        //string S = Console.ReadLine();
        //string T = Console.ReadLine();

        //int ans = T.Length;
        //for (int i = 0; i < S.Length - T.Length + 1; i++)
        //{
        //    int count = 0;
        //    for (int j = 0; j < T.Length; j++)
        //    {
        //        if (S[i + j] != T[j])
        //        {
        //            count++;
        //            if (count >= ans)
        //            {
        //                break;
        //            }
        //        }
        //    }
        //    if (count < ans)
        //    {
        //        ans = count;
        //    }

        //    //Console.WriteLine(S.Substring(i, T.Length));
        //    //Console.WriteLine(count);
        //}
        //Console.WriteLine(ans);

        //////複数の入力
        //int N = int.Parse(Console.ReadLine());
        //string[] strArray = Console.ReadLine().Split(' ');
        //long[] A = strArray.Select(long.Parse).ToArray();
        //long[] sumArray = new long[A.Length];

        //long modNum = 1000000007;
        //long ans = 0;

        //long tmp = 0;
        //for(int j = N - 1; j >= 0; j--)
        //{
        //    tmp = (tmp + A[j]) % modNum;
        //    sumArray[j] = tmp;
        //}

        ////for (int i = 0; i < N; i++)
        ////{
        ////    Console.Write(sumArray[i] + " ");
        ////}
        ////Console.WriteLine();

        //for (int i = N - 1; i > 0; i--)
        //{
        //    long hoge = (A[i - 1] * sumArray[i]) % modNum;

        //    // Console.WriteLine(i + " : " + A[i - 1] + " * " + sumArray[i]);
        //    // Console.WriteLine("add : " + hoge);

        //    ans += hoge;

        //}

        //Console.WriteLine(ans % modNum);




        //    int j = i
        //    for (int j = i; j > i; j++)
        //    {
        //        long aiaj = (long)intArray[i] * intArray[j];
        //        ans += aiaj;
        //        //if(aiaj < modnum)
        //        //{
        //        //    ans += aiaj;
        //        //}
        //        //else
        //        //{
        //        //    ans += aiaj % modnum;
        //        //}
        //    }
        //}

        //Console.WriteLine(ans % modnum);



        //string[] line = Console.ReadLine().Split(' ');
        //int H = int.Parse(line[0]);
        //int W = int.Parse(line[1]);

        //line = Console.ReadLine().Split(' ');
        //int Ch = int.Parse(line[0]);
        //int Cw = int.Parse(line[1]);

        //line = Console.ReadLine().Split(' ');
        //int Dh = int.Parse(line[0]);
        //int Dw = int.Parse(line[1]);

        //string[] S = new string[H];

        //for(int i = 0; i < H; i++)
        //{
        //    // line = Console.ReadLine().Split('');
        //    string line2 = Console.ReadLine();
        //    //Console.WriteLine(line2);
        //    S[i] = line2;

        //    //for(int j = 0; j < W; j++)
        //    //{
        //    //    Console.WriteLine(line2[j]);
        //    //    //Console.WriteLine(S[i][j]);
        //    //}
        //}

        //for (int i = 0; i < H; i++)
        //{
        //    for (int j = 0; j < W; j++)
        //    {
        //    }
        //}


        ///////////////////////////////////////////////
        //long N = int.Parse(Console.ReadLine());
        //string[] A = Console.ReadLine().Split(' ');

        //long h = long.Parse(A[0]);
        //long dai_sum = 0;
        //for(long i = 1; i < N; i++)
        //{
        //    long ai = long.Parse(A[i]);
        //    //Console.WriteLine("-- " + i + "--");
        //    //Console.WriteLine("dai_sum : " + dai_sum);
        //    //Console.WriteLine("h : " + h);
        //    //Console.WriteLine("a[i] : " + ai);
        //    if (ai < h)
        //    {
        //        long dai = h - ai;
        //        dai_sum += dai;
        //        //Console.WriteLine("add dai : " + dai);
        //    }
        //    else
        //    {
        //        h = ai;
        //    }
        //}

        //Console.WriteLine(dai_sum);







        //==============
        //String N = Console.ReadLine();

        //int sum = 0;
        //for(int i =0;i< N.Length; i++)
        //{
        //    //Console.WriteLine("sum : " + sum);
        //    //Console.WriteLine("N[i] : " + (N[i] - '0'));
        //    sum += N[i] - '0';

        //}

        ////Console.WriteLine("sum : " + sum);

        //if (sum % 9 == 0)
        //{
        //    Console.WriteLine("Yes");
        //}
        //else
        //{
        //    Console.WriteLine("No");
        //}
        //=============



        //スペース区切りの整数の入力
        //string[] dates = Console.ReadLine().Split(' ');
        //string[] amounts = Console.ReadLine().Split(' ');

        //double date = double.Parse(input[0]);
        //double amount = double.Parse(input[1]);

        //double date = double.Parse(input[0]);
        //double amount = double.Parse(input[1]);

        //var L2 = L.Distinct().OrderBy(o => o);
        //var L2 = L.OrderBy(o => o).ToArray();

        //string input = Console.ReadLine();
        //int b = int.Parse(input[0]);
        //int c = int.Parse(input[1]);
        //文字列の入力
        //string s = Console.ReadLine();
        //出力


        //////////////////a
        //整数の入力
        //int N = int.Parse(Console.ReadLine());
        //if (N == 0)
        //{
        //    Console.WriteLine("1");
        //}
        //else
        //{
        //    Console.WriteLine("0");
        //}
        //////////////////b

        //////複数の入力
        //string[] line = Console.ReadLine().Split(' ');
        //int a = int.Parse(line[0]);
        //int b = int.Parse(line[1]);
        //int c = int.Parse(line[2]);
        //int d = int.Parse(line[3]);

        //long result = Math.Max(Math.Max((long)a * c, (long)a * d), Math.Max((long)b * c, (long)b * d));
        //Console.WriteLine(result);

        //////////////////b

    }
}