using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Threading.Tasks;


/*
・概要
区間加算（RAQ）に対応したBIT。mod計算にも対応。
（Range Add Query）
なお、回答は区間和（RSQ : Range Sum Query）に対応。

数列の各要素が動的に加算される場合かつ、
「数列のleft要素からright番目までの区間和」を求めるために使用。
（SegmentTreeを簡略化・特殊化したものとも。）

　→要素数・クエリ数がともに10^5でも十分に間に合う

以下の2つのクエリに対し、ともにO(logN)で応答可能。
1. ある区間の和を求める（GetSum()）
2. 特定の区間の要素全体に加算する（AddBetween()）

※本ライブラリはRAQ と RSQの問題に特化しているので、（区間加算と区間和取得）
抽象化セグメントツリーを使うより、こちらの方が早い。

・使用法
1. RangeAddQueryクラスのオブジェクトを作成（引数は要素数と、modを使う場合にはmod）
（e.g. RangeAddQuery raq = new RangeAddQuery(N);）

2. 配列の初期化（元の配列を渡す）（計算量はO(N * logN)）
（e.g. raq.Initialize(arr);）

3. 適宜、クエリに回答（計算量はO(logN)）
	a. AddBetweenメソッドで、閉区間[s,t]の全要素にxを加算
	（e.g. raq.AddBetween(s,t,x);）

	b. GetSumメソッドで、閉区間[s,t]の合計値を取得（閉区間）
	（e.g. long res = raq.GetSum(s,t);）
*/


class Program
{
	//Main
	static void Main(string[] args)
	{
		//読み込む
		string[] S = Console.ReadLine().Split(' ');
		//要素数
		int N = int.Parse(S[0]);
		//区間数
		int K = int.Parse(S[1]);

		//mod
		long mod = 998244353;

		//1. RangeAddQueryクラスのオブジェクトを作成
		RangeAddQuery raq = new RangeAddQuery(N,mod);

		//初期状態の配列を作成
		long[] arr = new long[N];
		arr[0] = 1;

		//2. 配列の初期化（元の配列を渡す）
		raq.Initialize(arr);

		//区間を読み込む
		int[,] range = new int[K,2];
		for(int i=0; i<K; i++){
			string[] line = Console.ReadLine().Split(' ');
			int L = int.Parse(line[0]);
			int R = int.Parse(line[1]);
			range[i,0] = L;
			range[i,1] = R;
		}

		//下から順番に更新
		for(int i=0; i<N; i++){
			//現在のi番目の値を取得
			long tempo = raq.GetSum(i,i);

			//debug
			//Console.WriteLine("i={0},tempo={1}",i,tempo);

			//各区間を更新
			for(int j=0; j<K; j++){
				//更新対象の左端
				int L = range[j,0]+i;
				if(L >= N){
					continue;
				}
				//右端
				int R = Math.Min(N-1, range[j,1]+i);

				//Console.Write("区間[{0},{1}] / ",L,R);

				//この区間（閉区間）に対し、tempoだけ加算する
				raq.AddBetween(L,R,tempo);
			}
			//Console.WriteLine("");
		}

		//N-1番目の値を取得
		long ans = raq.GetSum(N-1,N-1);
		if(ans < 0){
			ans -= mod;
		}

		//出力
		Console.WriteLine(ans);

	}
}


//RangeAddQueryクラス
/*
	2つのBinaryIndexedTreeオブジェクトを使って実現
	long型とする
*/

class RangeAddQuery
{
	//BITオブジェクトの配列
	private BinaryIndexedTree[] trees;
	//modを使う場合
	private long mod;

	//コンストラクタ
	/*
	引数は要素数
	modを使う場合には、modも渡すこと
	*/
	public RangeAddQuery(int len, long mod = 0){
		//modを設定
		this.mod = mod;

		//BinaryIndexedTreeオブジェクト2つを初期化
		this.trees = new BinaryIndexedTree[2];
		for(int i=0; i<2; i++){
			this.trees[i] = new BinaryIndexedTree(len,this.mod);
		}
	}

	//元の配列に合わせ、BITを初期化するメソッド
	/*
	初期化にO(N * lonN)かかるので注意
	*/
	public void Initialize(long[] arr){
		for(int i=0; i<arr.Length; i++){
			this.AddBetween(i,i,arr[i]);
		}
	}

	//区間の全要素に加算するメソッド
	/*
	引数は、加算対象のインデックス（閉区間）と、加える値
	*/
	public void AddBetween(int left, int right, long val){
		this.trees[0].AddTo(left, -val * left);
		this.trees[0].AddTo(right+1, val * (right+1));
		this.trees[1].AddTo(left, val);
		this.trees[1].AddTo(right+1, -val);
	}

	//区間和を計算するメソッド
	/*
	引数は区間。
	閉区間[left, right]の合計値を吐き出す。
	*/
	public long GetSum(int left, int right){
		long res = this.Sum(right) - this.Sum(left-1);

		if(this.mod != 0){
			res %= this.mod;
			if(res < 0){
				res += this.mod;
			}
		}

		return res;
	}

	//インデックス0からi番目までの合計値を計算
	private long Sum(int right){
		if(right < 0){
			return 0;
		}
		else{
			long res = 0;
			res += this.trees[0].GetSum(0,right);
			if(this.mod != 0){
				res %= this.mod;
			}
			res += (this.trees[1].GetSum(0,right) * (right+1));
			if(this.mod != 0){
				res %= this.mod;
			}

			return res;
		}
	}

	//debug用の出力メソッド
	public void DebugWrite(){
		foreach(BinaryIndexedTree bit in this.trees){
			bit.DebugWrite();
		}
	}

}


//BinaryIndexedTreeのクラス
/*
 	転倒数に関する部分は便宜上削除しているので注意。
	（この部分については、別途ファイルを使用せよ。）
	long型とする。
*/
class BinaryIndexedTree
{
	//BITの配列
	/*
	元の配列を1-indexedに直して実装しているので注意。
	*/
	private long[] tree;
	//配列の要素数（元の配列の要素数+1となる）
	private int length;
	//mod
	private long mod;

	//コンストラクタ
	/*
	引数は要素数
	modを使う場合には、modも渡すこと
	*/
	public BinaryIndexedTree(int len, long mod = 0){
		//modを設定
		this.mod = mod;
		//要素数は元の要素数+1となる
		this.length = len + 1;
		//treeの初期化
		this.tree = new long[this.length];
	}

	//元の配列に合わせ、BITを初期化するメソッド
	/*
	初期化にO(N * lonN)かかるので注意
	*/
	public void Initialize(long[] arr){
		for(int i=0; i<arr.Length; i++){
			this.AddTo(i, arr[i]);
		}
	}

	//要素に加算するメソッド
	/*
	引数は、加算対象のインデックスと、加える値
	*/
	public void AddTo(int idx, long val){
		//1-indexedに直していることを反映
		idx ++;

		//cf. i & -iにより、iの立っているビットのうち最下位のものが求まる。
		for(int i=idx; i<this.length; i+=(i & -i)){
			if(this.mod != 0){
				val %= this.mod;
			}
			this.tree[i] += val;
			if(this.mod != 0){
				this.tree[i] %= this.mod;
			}
		}
	}

	//区間和を計算するメソッド
	/*
	引数は区間。
	閉区間[left, right]の合計値を吐き出す。
	*/
	public long GetSum(int left, int right){
		//1-indexedに直していることを反映
		left ++;
		right ++;

		//計算
		long res = this.Sum(right) - this.Sum(left-1);
		if(this.mod != 0){
			res %= this.mod;
			if(res < 0){
				res += this.mod;
			}
		}

		return res;
	}

	//インデックス0からi番目までの合計値を計算
	/*
	実装の上では、1-indexedに書き直しているので注意
	*/
	private long Sum(int right){
		if(right < 1){
			return 0;
		}
		else{
			long res = 0;
			for(int i=right; i>0; i-=(i & -i)){
				res += this.tree[i];
				if(this.mod != 0){
					res %= this.mod;
				}
			}
			return res;
		}
	}

	//debug用の出力メソッド
	public void DebugWrite(){
		for(int i=0; i<this.length; i++){
			Console.Write("t[{0}]={1},",i,this.tree[i]);
		}
		Console.WriteLine("");
	}
}



Measured memory_bytes: 20412