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)

fn main() {
	let mut s = String::new();
	use std::io::Read;
	std::io::stdin().read_to_string(&mut s).unwrap();
	let mut s = s.split_whitespace();
	let n: usize = s.next().unwrap().parse().unwrap();
	let k: usize = s.next().unwrap().parse().unwrap();
	let mut range = vec![];
	for _ in 0..k {
		let l: i32 = s.next().unwrap().parse().unwrap();
		let r: i32 = s.next().unwrap().parse().unwrap();
		range.push((l, r));
	}
	let mut dp = vec![0; n + 1];
	dp[1] = 1;
	const MOD: i64 = 998244353;
	let mut st = SegmentTree::construct(dp, 0i64, |a, b| (a + b) % MOD);
	for i in 2..=n {
		for &(il, ir) in range.iter() {
			let l = std::cmp::max(0, i as i32 - ir);
			let r = std::cmp::max(0, i as i32 - il + 1);
			let v = st.fold(l as usize, r as usize);
			let x = st.get(i).unwrap().clone();
			st.set(i, (v + x) % MOD);
		}
	}
	println!("{}", st.get(n).unwrap());
}

pub struct SegmentTree<T, F> {
	n: usize,
	data: Vec<T>,
	e: T,
	op: F,
}

impl<T, F> SegmentTree<T, F>
where
	T: Clone,
	F: Fn(T, T) -> T,
{
	pub fn new(n: usize, e: T, op: F) -> Self {
		Self {
			n: n,
			data: vec![e.clone(); n << 1],
			e: e,
			op: op,
		}
	}

	pub fn construct(src: Vec<T>, e: T, op: F) -> Self {
		let mut data = vec![e.clone(); src.len()];
		data.extend(src);
		for i in (1..data.len() / 2).rev() {
			data[i] = op(data[i << 1].clone(), data[i << 1 | 1].clone());
		}
		Self {
			n: data.len() / 2,
			data,
			e,
			op,
		}
	}

	pub fn fold(&self, l: usize, r: usize) -> T {
		let mut s = self.e.clone();
		let mut t = self.e.clone();
		let mut l = l + self.n;
		let mut r = r + self.n;
		while l < r {
			if l & 1 != 0 {
				s = (self.op)(s, self.data[l].clone());
				l += 1;
			}
			if r & 1 != 0 {
				t = (self.op)(self.data[r - 1].clone(), t);
			}
			l >>= 1;
			r >>= 1;
		}
		(self.op)(s, t)
	}

	pub fn set(&mut self, i: usize, v: T) {
		let mut i = i + self.n;
		self.data[i] = v;
		while {
			i >>= 1;
			i > 0
		} {
			self.data[i] = (self.op)(self.data[i << 1].clone(), self.data[i << 1 | 1].clone());
		}
	}

	pub fn get(&self, i: usize) -> Option<&T> {
		self.data.get(self.n + i)
	}

	pub fn len(&self) -> usize {
		self.n
	}
}