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 Rust (1.42.0) (judge verdict: Accepted)

#![doc = " # Bundled libraries"]
#[allow(unused_imports)]
use itertools::Itertools;
use proconio::input;
#[allow(unused_imports)]
use proconio::marker::*;
type Mint = modint::Mint998_244_353;
fn main() {
    input! { n : usize , k : usize , lr : [(usize , usize) ; k] , }
    let mut dp = vec![Mint::new(0); n];
    let mut s = vec![Mint::new(0); k];
    dp[0] = Mint::new(1);
    for i in 0..n {
        for j in 0..k {
            if let Some(l) = i.checked_sub(lr[j].1 + 1) {
                s[j] -= dp[l];
            }
            if let Some(r) = i.checked_sub(lr[j].0) {
                s[j] += dp[r];
            }
            dp[i] += s[j];
        }
    }
    println!("{}", dp[n - 1]);
}
mod modint {
    pub trait Modulation {
        const MOD: u64;
    }
    #[derive(PartialEq, Eq)]
    pub struct ModInt<M: Modulation> {
        x: u64,
        phantom: std::marker::PhantomData<M>,
    }
    impl<M: Modulation> Clone for ModInt<M> {
        fn clone(&self) -> Self {
            Self::new_uncheck(self.x)
        }
    }
    impl<M: Modulation> Copy for ModInt<M> {}
    impl<M: Modulation> std::fmt::Display for ModInt<M> {
        fn fmt(&self, dest: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
            write!(dest, "{}", self.x)
        }
    }
    impl<M: Modulation> ModInt<M> {
        #[inline]
        pub fn new(x: u64) -> Self {
            Self {
                x: x % M::MOD,
                phantom: std::marker::PhantomData,
            }
        }
        #[inline]
        pub fn from_signed(x: i64) -> Self {
            let x = if x >= 0 {
                x as u64 % M::MOD
            } else {
                (M::MOD as i64 + x % M::MOD as i64) as u64
            };
            Self {
                x: x,
                phantom: std::marker::PhantomData,
            }
        }
        #[inline]
        pub fn new_uncheck(x: u64) -> Self {
            Self {
                x: x,
                phantom: std::marker::PhantomData,
            }
        }
        #[inline]
        pub fn val(&self) -> u64 {
            self.x
        }
    }
    macro_rules! def_from_trait {
        (u , $ t : ty) => {
            impl<M: Modulation> std::convert::From<$t> for ModInt<M> {
                #[inline]
                fn from(x: $t) -> Self {
                    Self::new(x as u64)
                }
            }
        };
        (i , $ t : ty) => {
            impl<M: Modulation> std::convert::From<$t> for ModInt<M> {
                #[inline]
                fn from(x: $t) -> Self {
                    Self::from_signed(x as i64)
                }
            }
        };
    }
    def_from_trait!(u, u8);
    def_from_trait!(u, u16);
    def_from_trait!(u, u32);
    def_from_trait!(u, u64);
    def_from_trait!(u, usize);
    def_from_trait!(i, i8);
    def_from_trait!(i, i16);
    def_from_trait!(i, i32);
    def_from_trait!(i, i64);
    def_from_trait!(i, isize);
    impl<M: Modulation> std::ops::Neg for ModInt<M> {
        type Output = Self;
        #[inline]
        fn neg(self) -> Self {
            Self {
                x: if self.x == 0 { 0 } else { M::MOD - self.x },
                phantom: std::marker::PhantomData,
            }
        }
    }
    impl<M: Modulation> std::ops::AddAssign for ModInt<M> {
        #[inline]
        fn add_assign(&mut self, rhs: Self) {
            self.x += rhs.x;
            if M::MOD <= self.x {
                self.x -= M::MOD;
            }
        }
    }
    impl<M: Modulation> std::ops::Add for ModInt<M> {
        type Output = Self;
        #[inline]
        fn add(self, rhs: Self) -> Self {
            let mut res = self;
            res += rhs;
            res
        }
    }
    impl<M: Modulation> std::ops::SubAssign for ModInt<M> {
        #[inline]
        fn sub_assign(&mut self, rhs: Self) {
            if self.x >= rhs.x {
                self.x -= rhs.x;
            } else {
                self.x += M::MOD - rhs.x;
            }
        }
    }
    impl<M: Modulation> std::ops::Sub for ModInt<M> {
        type Output = Self;
        #[inline]
        fn sub(self, rhs: Self) -> Self {
            let mut res = self;
            res -= rhs;
            res
        }
    }
    impl<M: Modulation> std::ops::MulAssign for ModInt<M> {
        #[inline]
        fn mul_assign(&mut self, rhs: Self) {
            self.x *= rhs.x;
            self.x %= M::MOD;
        }
    }
    impl<M: Modulation> std::ops::Mul for ModInt<M> {
        type Output = Self;
        #[inline]
        fn mul(self, rhs: Self) -> Self {
            let mut res = self;
            res *= rhs;
            res
        }
    }
    fn ext_gcd(a: u64, b: u64) -> (i64, i64, u64) {
        if b == 0 {
            (1, 0, a)
        } else {
            let (mut y, x, d) = ext_gcd(b, a % b);
            y -= (a / b) as i64 * x;
            (x, y, d)
        }
    }
    impl<M: Modulation> ModInt<M> {
        pub fn pow(&self, mut n: u64) -> Self {
            let mut res = Self::new_uncheck(1);
            let mut d = *self;
            while n != 0 {
                if n & 1 != 0 {
                    res *= d;
                }
                d *= d;
                n >>= 1;
            }
            res
        }
        pub fn inv(&self) -> Self {
            let (mut x, _, _) = ext_gcd(self.x, M::MOD);
            if x < 0 {
                x %= M::MOD as i64;
                x += M::MOD as i64;
            }
            Self::new(x as u64)
        }
        pub fn gen_factorial(n: u64) -> Factorial<M> {
            let n = n as usize;
            let mut pos = vec![Self::new_uncheck(1); n + 1];
            let mut neg = vec![Self::new_uncheck(1); n + 1];
            for i in 1..n {
                pos[i + 1] = pos[i] * Self::new(i as u64 + 1);
            }
            neg[n] = pos[n].inv();
            for i in (1..n).rev() {
                neg[i] = neg[i + 1] * Self::new(i as u64 + 1);
            }
            Factorial { pos: pos, neg: neg }
        }
        pub fn gen_inv(n: u64) -> Vec<Self> {
            let mut res = vec![Self::new_uncheck(1); (n + 1) as usize];
            for i in 2..=n {
                res[i as usize] =
                    Self::new_uncheck(M::MOD - M::MOD / i) * res[(M::MOD % i) as usize];
            }
            res
        }
    }
    pub struct Factorial<M: Modulation> {
        pos: Vec<ModInt<M>>,
        neg: Vec<ModInt<M>>,
    }
    impl<M: Modulation> Factorial<M> {
        pub fn permutation(&self, n: u64, r: u64) -> ModInt<M> {
            if r > n {
                ModInt::new(0)
            } else {
                self.pos[n as usize] * self.neg[(n - r) as usize]
            }
        }
        pub fn binomial(&self, n: u64, r: u64) -> ModInt<M> {
            if r > n {
                ModInt::new(0)
            } else {
                self.pos[n as usize] * self.neg[r as usize] * self.neg[(n - r) as usize]
            }
        }
        pub fn cmb_with_rep(&self, n: u64, r: u64) -> ModInt<M> {
            self.binomial(n + r - 1, r)
        }
    }
    #[cfg(test)]
    mod test {
        use crate::modint::*;
        struct F;
        impl Modulation for F {
            const MOD: u64 = 7;
        }
        type Mint = ModInt<F>;
        #[test]
        fn test_modint_construct() {
            let x = Mint::new(12);
            assert_eq!(x.val(), 5);
            let y = x;
            assert_eq!(x.val(), 5);
            assert_eq!(y.val(), 5);
            let z = Mint::from_signed(-2);
            assert_eq!(z.val(), 5);
            let x = Mint::from(12);
            assert_eq!(x.val(), 5);
            let x = Mint::from(-2);
            assert_eq!(x.val(), 5);
        }
        #[test]
        fn test_modint_add() {
            let mut x = Mint::new(12) + Mint::new(3);
            assert_eq!(x.val(), 1);
            x += Mint::new(6);
            assert_eq!(x.val(), 0);
        }
        #[test]
        fn test_modint_sub() {
            let mut x = Mint::new(2) - Mint::new(5);
            assert_eq!(x.val(), 4);
            x -= Mint::new(5);
            assert_eq!(x.val(), 6);
            x -= Mint::new(1);
            assert_eq!(x.val(), 5);
        }
        #[test]
        fn test_modint_multi() {
            let mut x = Mint::new(2) * Mint::new(5);
            assert_eq!(x.val(), 3);
            x *= Mint::new(5);
            assert_eq!(x.val(), 1);
        }
        #[test]
        fn test_modint_pow() {
            assert_eq!(Mint::new(3).pow(0).val(), 1);
            assert_eq!(Mint::new(3).pow(1).val(), 3);
            assert_eq!(Mint::new(3).pow(2).val(), 2);
            assert_eq!(Mint::new(3).pow(3).val(), 6);
            assert_eq!(Mint::new(3).pow(4).val(), 4);
            assert_eq!(Mint::new(3).pow(5).val(), 5);
            assert_eq!(Mint::new(3).pow(6).val(), 1);
            assert_eq!(Mint::new(3).pow(7).val(), 3);
        }
        #[test]
        fn test_modint_inv() {
            assert_eq!(Mint::new(1).inv().val(), 1);
            assert_eq!(Mint::new(2).inv().val(), 4);
            assert_eq!(Mint::new(3).inv().val(), 5);
            assert_eq!(Mint::new(4).inv().val(), 2);
            assert_eq!(Mint::new(5).inv().val(), 3);
            assert_eq!(Mint::new(6).inv().val(), 6);
        }
        #[test]
        fn test_ext_gcd() {
            assert_eq!(ext_gcd(2, 3), (-1, 1, 1));
            assert_eq!(ext_gcd(4, 6), (-1, 1, 2));
            assert_eq!(ext_gcd(6, 4), (1, -1, 2));
        }
        #[test]
        fn test_gen_inv() {
            assert_eq!(
                Mint::gen_inv(6).iter().map(|x| x.val()).collect::<Vec<_>>(),
                &[1, 1, 4, 5, 2, 3, 6]
            )
        }
        #[test]
        fn test_modint_factorial() {
            let fac = Mint::gen_factorial(5);
            let pos = fac.pos.iter().map(|x| x.val()).collect::<Vec<_>>();
            let neg = fac.neg.iter().map(|x| x.val()).collect::<Vec<_>>();
            assert_eq!(pos, &[1, 1, 2, 6, 3, 1]);
            assert_eq!(neg, &[1, 1, 4, 6, 5, 1]);
        }
        #[test]
        fn test_display() {
            assert_eq!(format!("{}", Mint::new(3)), "3");
        }
    }
    pub struct F1_000_000_007;
    impl Modulation for F1_000_000_007 {
        const MOD: u64 = 1_000_000_007;
    }
    pub type Mint1_000_000_007 = ModInt<F1_000_000_007>;
    pub struct F998_244_353;
    impl Modulation for F998_244_353 {
        const MOD: u64 = 998_244_353;
    }
    pub type Mint998_244_353 = ModInt<F998_244_353>;
}