#define _USE_MATH_DEFINES
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <vector>
#include <queue>
#include <algorithm>
#include <climits>
#include <cstring>
#include <cmath>
#include <stack>
#include <iomanip>
#include <tuple>
#include <functional>
#include <cfloat>
#include <map>
#include <set>
#include <array>
#include <stdio.h>
#include <string.h>
#include <random>
using ll = long long;
using ull = unsigned long long;
using namespace std;
#define int long long
#define CONTAINS_VEC(v,n) (find((v).begin(), (v).end(), (n)) != (v).end())
#define SORT(v) sort((v).begin(), (v).end())
#define RSORT(v) sort((v).rbegin(), (v).rend())
#define ARY_SORT(a, size) sort((a), (a)+(size))
#define REMOVE(v,a) (v.erase(remove((v).begin(), (v).end(), (a)), (v).end()))
#define REVERSE(v) (reverse((v).begin(), (v).end()))
#define ARY_REVERSE(v,a) (reverse((v), (v)+(a)))
#define REP(i, n) for (int (i)=0; (i) < (n); (i)++)
#define REPE(i, n) for (int (i)=0; (i) <= (n); (i)++)
#define CONTAINS_MAP(m, a) ((m).find((a)) != m.end())
#define CONTAINS_SET(m, a) ((m).find((a)) != m.end())
void YesNo(bool b) { cout << (b ? "Yes" : "No") << endl; }
void Yes() { cout << "Yes" << endl; }
void No() { cout << "No" << endl; }



//---------- 1000000007 ----------
const int MOD = 998244353;
struct mint {
	ll x; // typedef long long ll;
	mint(ll x = 0) :x((x% MOD + MOD) % MOD) {}
	mint operator-() const { return mint(-x); }
	mint& operator+=(const mint a) {
		if ((x += a.x) >= MOD) x -= MOD;
		return *this;
	}
	mint& operator-=(const mint a) {
		if ((x += MOD - a.x) >= MOD) x -= MOD;
		return *this;
	}
	mint& operator*=(const mint a) { (x *= a.x) %= MOD; return *this; }
	mint operator+(const mint a) const { return mint(*this) += a; }
	mint operator-(const mint a) const { return mint(*this) -= a; }
	mint operator*(const mint a) const { return mint(*this) *= a; }
	mint pow(ll t) const {
		if (!t) return 1;
		mint a = pow(t >> 1);
		a *= a;
		if (t & 1) a *= *this;
		return a;
	}

	// for prime mod
	mint inv() const { return pow(MOD - 2); }
	mint& operator/=(const mint a) { return *this *= a.inv(); }
	mint operator/(const mint a) const { return mint(*this) /= a; }
};
istream& operator>>(istream& is, mint& a) { return is >> a.x; }
ostream& operator<<(ostream& os, const mint& a) { return os << a.x; }

mint m_comb(mint n, mint r)
{
	int i;
	mint p = 1;
	for (i = 1; i <= r.x; i++)
	{
		p *= n - i + 1;
		p /= i;
	}
	return p;
}
mint m_comb_with_rep(mint n, mint r)
{
	return m_comb(n + r - 1, r);
}
mint m_perm(mint n, mint r)
{
	mint a = 1;
	for (int i = n.x; i > n.x - r.x; i--)
	{
		a *= i;
	}
	return a;
}



//---------- セグ木 ----------
const int  SEG_MAX = (1 << 20); //1<<17 = 2^17 = 131072
mint seg[SEG_MAX * 2] = { 0 };

//[a,b]にxを加算 (節点kをベースに[l,r]に足す)
void add(int a, int b, mint x, int k = 0, int l = 0, int r = SEG_MAX - 1)
{
	if (a <= l && r <= b)
	{
		seg[k] += x;
	}
	else
	{
		int l0 = l;
		int r0 = l + (r - l) / 2;
		int l1 = r0 + 1;
		int r1 = r;
		if (a <= r0)
		{
			int kk = 2 * k + 1;
			add(a, b, x, kk, l0, r0);
		}
		if (l1 <= b)
		{
			int kk = 2 * k + 2;
			add(a, b, x, kk, l1, r1);
		}
	}
}

mint get(int index)
{
	mint sum = 0;
	int k = SEG_MAX - 1 + index; //根
	while (true)
	{
		sum += seg[k];
		if (k == 0) break;
		k = (k - 1) / 2;
	}
	return sum;
}


int N, K;
int L[20];
int R[20];

signed main()
{
	cin >> N >> K;
	REP(i, K)
	{
		cin >> L[i] >> R[i];
	}

	add(1, 1, 1);
	for (int i = 1; i < N; i++)
	{
		mint n = get(i);

		for (int k = 0; k < K; k++)
		{
			add(L[k] + i, R[k] + i, n);
		}
	}

	cout << get(N) << endl;
}



Measured memory_bytes: 20060