#include <bits/stdc++.h>
using namespace std;
#define REP(i, x, n) for (int i = x; i < (int)n; i++)
#define rep(i, n) REP(i, 0, n)
#define sp(p) cout << setprecision(16) << fixed << p << endl;
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define SORT(a) sort(all(a))
#define RSORT(a) sort(rall(a))
#define UNIQ(a) unique(all(a))
#define UNIQNUM(a) UNIQ(a) - a.begin()
#define UNIQIT(a) a.erase(UNIQ(a), a.end());
#define VOUT(v, i)                                                             \\
  rep(i, v.size()) cout << v[i] << (i == v.size() - 1 ? "\\n" : " ");
#define vout(v) VOUT(v, z);
#define vdbg(v, i)                                                             \\
  cout << #v << ": ";                                                          \\
  for (int i = 0; i < (int)v.size(); i++) {                                    \\
    cout << v[i] << " ";                                                       \\
  }                                                                            \\
  cout << "\\n";
#define vmin(v) *min_element(all(v))
#define vmax(v) *max_element(all(v))
#define vsum(v) accumulate(all(v), 0LL)
#define MOUT(m, r, c)                                                          \\
  rep(i, r) {                                                                  \\
    rep(j, c) { cout << m[i][j] << " "; }                                      \\
    cout << endl;                                                              \\
  }
#define mout(m) MOUT(m, m.size(), m[0].size())
#define debg(a) cout << #a << ": " << a << endl;
#define out(a) debg(a);
#define show(a)                                                                \\
  for (cont & y : a) {                                                         \\
    for (cont & x : y) {                                                       \\
      cout << x << " ";                                                        \\
    }                                                                          \\
    cout << endl;                                                              \\
  }
#define digit(a) to_string(a).length();
// template<class T>inline int out(const T &t){ print(t); putchar('\\n'); return
// 0; } template<class T>inline T gcd(T a,T b){if(b==0)return a;
// return(gcd(b,a%b));} template<class T>inline T lcm(T a,T b){return
// a/gcd(a,b)*b;}
bool is_palindrome(string s) { return s == string(s.rbegin(), s.rend()); }
#define popcount __builtin_popcount
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> P;
typedef vector<ll> V;
typedef vector<vector<ll>> VV;
// const long long MOD=1000000007;
const long long INF = 1e18;
#define EPS (1e-7)
#define PI (acos(-1))
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <int MOD> struct Fp {
  long long val;
  constexpr Fp(long long v = 0) noexcept : val(v % MOD) {
    if (val < 0)
      val += MOD;
  }
  constexpr int getmod() { return MOD; }
  constexpr Fp operator-() const noexcept { return val ? MOD - val : 0; }
  constexpr Fp operator+(const Fp &r) const noexcept { return Fp(*this) += r; }
  constexpr Fp operator-(const Fp &r) const noexcept { return Fp(*this) -= r; }
  constexpr Fp operator*(const Fp &r) const noexcept { return Fp(*this) *= r; }
  constexpr Fp operator/(const Fp &r) const noexcept { return Fp(*this) /= r; }
  constexpr Fp &operator+=(const Fp &r) noexcept {
    val += r.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }
  constexpr Fp &operator-=(const Fp &r) noexcept {
    val -= r.val;
    if (val < 0)
      val += MOD;
    return *this;
  }
  constexpr Fp &operator*=(const Fp &r) noexcept {
    val = val * r.val % MOD;
    return *this;
  }
  constexpr Fp &operator/=(const Fp &r) noexcept {
    long long a = r.val, b = MOD, u = 1, v = 0;
    while (b) {
      long long t = a / b;
      a -= t * b;
      swap(a, b);
      u -= t * v;
      swap(u, v);
    }
    val = val * u % MOD;
    if (val < 0)
      val += MOD;
    return *this;
  }
  constexpr bool operator==(const Fp &r) const noexcept {
    return this->val == r.val;
  }
  constexpr bool operator!=(const Fp &r) const noexcept {
    return this->val != r.val;
  }
  friend constexpr ostream &operator<<(ostream &os, const Fp<MOD> &x) noexcept {
    return os << x.val;
  }
  // friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept {
  //     if (n == 0) return 1;
  //     auto t = modpow(a, n / 2);
  //     t = t * t;
  //     if (n & 1) t = t * a;
  //     return t;
  // }
};
const long long MOD = 998244353;
using mint = Fp<MOD>;

mint modpow(const mint &a, ll n) {
  if (n == 0)
    return 1;
  mint t = modpow(a, n / 2);
  t = t * t;
  if (n & 1)
    t = t * a;
  return t;
}

int main() {
  long long N;
  scanf("%lld", &N);
  long long K;
  scanf("%lld", &K);
  std::vector<long long> L(K);
  std::vector<long long> R(K);
  set<long long> s;
  for (int i = 0; i < K; i++) {
    scanf("%lld", &L[i]);
    scanf("%lld", &R[i]);
    for (long long j = L[i]; j <= R[i]; j++) {
      s.insert(j);
    }
  }
  // for (auto& e: s) {
  //     cout << e << endl;
  // }
  vector<mint> dp(N + 100);
  dp[1] = 1;
  for (long long i = 1; i <= N; i++) {
    for (auto &e : s) {
      if (i - e > 0) {
        dp[i] += dp[i - e];
      } else {
        break;
      }
    }
  }
  // vout(dp);
  cout << dp[N] << endl;

  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define REP(i, x, n) for (int i = x; i < (int)n; i++)
#define rep(i, n) REP(i, 0, n)
#define sp(p) cout << setprecision(16) << fixed << p << endl;
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define SORT(a) sort(all(a))
#define RSORT(a) sort(rall(a))
#define UNIQ(a) unique(all(a))
#define UNIQNUM(a) UNIQ(a) - a.begin()
#define UNIQIT(a) a.erase(UNIQ(a), a.end());
#define VOUT(v, i)                                                             \\
  rep(i, v.size()) cout << v[i] << (i == v.size() - 1 ? "\\n" : " ");
#define vout(v) VOUT(v, z);
#define vdbg(v, i)                                                             \\
  cout << #v << ": ";                                                          \\
  for (int i = 0; i < (int)v.size(); i++) {                                    \\
    cout << v[i] << " ";                                                       \\
  }                                                                            \\
  cout << "\\n";
#define vmin(v) *min_element(all(v))
#define vmax(v) *max_element(all(v))
#define vsum(v) accumulate(all(v), 0LL)
#define MOUT(m, r, c)                                                          \\
  rep(i, r) {                                                                  \\
    rep(j, c) { cout << m[i][j] << " "; }                                      \\
    cout << endl;                                                              \\
  }
#define mout(m) MOUT(m, m.size(), m[0].size())
#define debg(a) cout << #a << ": " << a << endl;
#define out(a) debg(a);
#define show(a)                                                                \\
  for (cont & y : a) {                                                         \\
    for (cont & x : y) {                                                       \\
      cout << x << " ";                                                        \\
    }                                                                          \\
    cout << endl;                                                              \\
  }
#define digit(a) to_string(a).length();
// template<class T>inline int out(const T &t){ print(t); putchar('\\n'); return
// 0; } template<class T>inline T gcd(T a,T b){if(b==0)return a;
// return(gcd(b,a%b));} template<class T>inline T lcm(T a,T b){return
// a/gcd(a,b)*b;}
bool is_palindrome(string s) { return s == string(s.rbegin(), s.rend()); }
#define popcount __builtin_popcount
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> P;
typedef vector<ll> V;
typedef vector<vector<ll>> VV;
// const long long MOD=1000000007;
const long long INF = 1e18;
#define EPS (1e-7)
#define PI (acos(-1))
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <int MOD> struct Fp {
  long long val;
  constexpr Fp(long long v = 0) noexcept : val(v % MOD) {
    if (val < 0)
      val += MOD;
  }
  constexpr int getmod() { return MOD; }
  constexpr Fp operator-() const noexcept { return val ? MOD - val : 0; }
  constexpr Fp operator+(const Fp &r) const noexcept { return Fp(*this) += r; }
  constexpr Fp operator-(const Fp &r) const noexcept { return Fp(*this) -= r; }
  constexpr Fp operator*(const Fp &r) const noexcept { return Fp(*this) *= r; }
  constexpr Fp operator/(const Fp &r) const noexcept { return Fp(*this) /= r; }
  constexpr Fp &operator+=(const Fp &r) noexcept {
    val += r.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }
  constexpr Fp &operator-=(const Fp &r) noexcept {
    val -= r.val;
    if (val < 0)
      val += MOD;
    return *this;
  }
  constexpr Fp &operator*=(const Fp &r) noexcept {
    val = val * r.val % MOD;
    return *this;
  }
  constexpr Fp &operator/=(const Fp &r) noexcept {
    long long a = r.val, b = MOD, u = 1, v = 0;
    while (b) {
      long long t = a / b;
      a -= t * b;
      swap(a, b);
      u -= t * v;
      swap(u, v);
    }
    val = val * u % MOD;
    if (val < 0)
      val += MOD;
    return *this;
  }
  constexpr bool operator==(const Fp &r) const noexcept {
    return this->val == r.val;
  }
  constexpr bool operator!=(const Fp &r) const noexcept {
    return this->val != r.val;
  }
  friend constexpr ostream &operator<<(ostream &os, const Fp<MOD> &x) noexcept {
    return os << x.val;
  }
  // friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept {
  //     if (n == 0) return 1;
  //     auto t = modpow(a, n / 2);
  //     t = t * t;
  //     if (n & 1) t = t * a;
  //     return t;
  // }
};
const long long MOD = 998244353;
using mint = Fp<MOD>;

mint modpow(const mint &a, ll n) {
  if (n == 0)
    return 1;
  mint t = modpow(a, n / 2);
  t = t * t;
  if (n & 1)
    t = t * a;
  return t;
}

int main() {
  long long N;
  scanf("%lld", &N);
  long long K;
  scanf("%lld", &K);
  std::vector<long long> L(K);
  std::vector<long long> R(K);
  set<long long> s;
  for (int i = 0; i < K; i++) {
    scanf("%lld", &L[i]);
    scanf("%lld", &R[i]);
    for (long long j = L[i]; j <= R[i]; j++) {
      s.insert(j);
    }
  }
  vector<mint> dp(N + 100);
  dp[1] = 1;
  vector<mint> acc(N + 100);
  // acc[1]=1;
  for (long long i = 1; i <= N; i++) {
    for (long long j = 0; j < K; j++) {
      // if(i-L[j]>0)
      //     dp[i] += dp[i-L[j]];
      // if(i-R[j]>0)
      //     dp[i] += dp[i-R[j]];
      if (i - L[j] > 0)
        dp[i] += acc[i - L[j]];
      if (i - R[j] > 1)
        dp[i] -= acc[i - R[j] - 1];
      // if(i-L[j]>0 && i-R[j]>1)
      //     dp[i] += acc[i-L[j]] - acc[i-R[j]-1];
    }
    // for (auto& e: s) {
    //     if(i-e>0){
    //         dp[i] += dp[i-e];
    //     }else{
    //         break;
    //     }
    // }
    acc[i] += acc[i - 1] + dp[i];
  }
  // for (auto& e: s) { cout << e << endl; }
  // vout(dp);
  // vout(acc);
  cout << dp[N] << endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#pragma region atcoder
// #include <atcoder/all>
// using namespace atcoder;
#pragma endregion
#pragma region macros
using ll = long long;
using vi = vector<int>;
using vs = vector<string>;
using vl = vector<ll>;
using vb = vector<bool>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<ll>>;
#define rep(i, n) for (int i = 0; i < n; i++)
#define rrep(i, n) for (int i = n - 1; i >= 0; i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#pragma endregion
#pragma region debug for var, v, vv
#define debug(var)                                                             \\
  do {                                                                         \\
    std::cout << #var << " : ";                                                \\
    view(var);                                                                 \\
  } while (0)
template <typename T> void view(T e) { std::cout << e << std::endl; }
template <typename T> void view(const std::vector<T> &v) {
  for (const auto &e : v) {
    std::cout << e << " ";
  }
  std::cout << std::endl;
}
template <typename T> void view(const std::vector<std::vector<T>> &vv) {
  cout << endl;
  int cnt = 0;
  for (const auto &v : vv) {
    cout << cnt << "th : ";
    view(v);
    cnt++;
  }
  cout << endl;
}
#pragma endregion

const ll mod = 998244353;
const int inf = 1001001001;
const ll INF = 1001001001001001001;
const int MAX = 2000005;

// using mint = modint998244353;
// These are for segment tree
/*int op(int a, int b){return max(a, b);}
int e(){return -1;}
bool f(int v){ return v < target;}
*/

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

template <class T> bool chmax(T &a, const T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
ll modpow(ll a, ll p) {
  ll ret = 1;
  while (p) {
    if (p & 1) {
      ret = ret * a % mod;
    }
    a = a * a % mod;
    p >>= 1;
  }
  return ret;
}

/*--------------------------------------------------------------------------------------------------------------------------------*/

ll dp[200005];

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n, k;
  cin >> n >> k;
  vector<int> l(k), r(k);
  for (int i = 0; i < k; i++) {
    cin >> l[i] >> r[i];
  }
  dp[1] = 1;
  for (int i = 1; i <= n; i++) {
    if (i > 2) {
      dp[i] += dp[i - 1];
      dp[i] %= mod;
    }
    for (int j = 0; j < k; j++) {
      dp[i + l[j]] += dp[i];
      dp[i + l[j]] %= mod;
      dp[i + r[j] + 1] += (mod - dp[i]) % mod;
    }
  }
  cout << dp[n] % mod << endl;
}

#include <bits/stdc++.h>
using namespace std;
#pragma region atcoder
// #include <atcoder/all>
// using namespace atcoder;
#pragma endregion
#pragma region macros
using ll = long long;
using vi = vector<int>;
using vs = vector<string>;
using vl = vector<ll>;
using vb = vector<bool>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<ll>>;
#define rep(i, n) for (int i = 0; i < n; i++)
#define rrep(i, n) for (int i = n - 1; i >= 0; i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#pragma endregion
#pragma region debug for var, v, vv
#define debug(var)                                                             \\
  do {                                                                         \\
    std::cout << #var << " : ";                                                \\
    view(var);                                                                 \\
  } while (0)
template <typename T> void view(T e) { std::cout << e << std::endl; }
template <typename T> void view(const std::vector<T> &v) {
  for (const auto &e : v) {
    std::cout << e << " ";
  }
  std::cout << std::endl;
}
template <typename T> void view(const std::vector<std::vector<T>> &vv) {
  cout << endl;
  int cnt = 0;
  for (const auto &v : vv) {
    cout << cnt << "th : ";
    view(v);
    cnt++;
  }
  cout << endl;
}
#pragma endregion

const ll mod = 998244353;
const int inf = 1001001001;
const ll INF = 1001001001001001001;
const int MAX = 2000005;

// using mint = modint998244353;
// These are for segment tree
/*int op(int a, int b){return max(a, b);}
int e(){return -1;}
bool f(int v){ return v < target;}
*/

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

template <class T> bool chmax(T &a, const T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
ll modpow(ll a, ll p) {
  ll ret = 1;
  while (p) {
    if (p & 1) {
      ret = ret * a % mod;
    }
    a = a * a % mod;
    p >>= 1;
  }
  return ret;
}

/*--------------------------------------------------------------------------------------------------------------------------------*/

ll dp[200005];

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n, k;
  cin >> n >> k;
  vector<int> l(k), r(k);
  for (int i = 0; i < k; i++) {
    cin >> l[i] >> r[i];
  }
  dp[1] = 1;
  for (int i = 1; i <= n; i++) {
    if (i > 2) {
      dp[i] += dp[i - 1];
      dp[i] %= mod;
    }
    for (int j = 0; j < k; j++) {
      if (i + l[j] <= 200004) {
        dp[i + l[j]] += dp[i];
        dp[i + l[j]] %= mod;
      }
      if (i + r[j] <= 200004)
        dp[i + r[j] + 1] += (mod - dp[i]) % mod;
    }
  }
  cout << dp[n] % mod << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define repi(i, s, n) for (int i = (s); i < (n); i++)
#ifdef LOCAL
#define INPUT_FILE                                                             \\
  ifstream in("abc179/abc179_d.txt");                                          \\
  cin.rdbuf(in.rdbuf());
#define print_vec(v)                                                           \\
  rep(l, v.size()) { cout << v[l] << " "; }                                    \\
  cout << endl;
#else
#define INPUT_FILE
#define print_vec(v)
#endif
#define CIN_OPTIMIZE                                                           \\
  cin.tie(0);                                                                  \\
  ios::sync_with_stdio(false);
typedef pair<int, int> P;
typedef long long ll;
typedef pair<ll, ll> pl;
const int INF = 100100100;
const ll LINF = 1e18 + 100;
const int MOD = 1e9 + 7;

// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
// const int mod = 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; }

int main() {
  INPUT_FILE CIN_OPTIMIZE;

  int N, K;
  cin >> N >> K;

  vector<int> c;
  rep(i, K) {
    int l, r;
    cin >> l >> r;
    repi(i, l, r + 1) { c.push_back(i); }
  }
  sort(c.begin(), c.end());

  mint ans = 0;
  vector<mint> memo(N + 1, 0);
  memo[N] = 1;
  int M = c.size();
  for (int i = N - 1; i > 0; i--) {
    mint ret = 0;
    rep(j, M) {
      if (c[j] > N - i)
        break;
      ret += memo[i + c[j]];
    }
    memo[i] = ret;
  }

  cout << memo[1] << endl;
}

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define repi(i, s, n) for (int i = (s); i < (n); i++)
#ifdef LOCAL
#define INPUT_FILE                                                             \\
  ifstream in("abc179/abc179_d.txt");                                          \\
  cin.rdbuf(in.rdbuf());
#define print_vec(v)                                                           \\
  rep(l, v.size()) { cout << v[l] << " "; }                                    \\
  cout << endl;
#else
#define INPUT_FILE
#define print_vec(v)
#endif
#define CIN_OPTIMIZE                                                           \\
  cin.tie(0);                                                                  \\
  ios::sync_with_stdio(false);
typedef pair<int, int> P;
typedef long long ll;
typedef pair<ll, ll> pl;
const int INF = 100100100;
const ll LINF = 1e18 + 100;
const int MOD = 1e9 + 7;

// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
// const int mod = 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; }

int main() {
  INPUT_FILE CIN_OPTIMIZE;

  int N, K;
  cin >> N >> K;

  vector<P> c(K);
  rep(i, K) {
    int l, r;
    cin >> l >> r;
    c[i] = {l, r + 1};
  }

  mint ans = 0;
  vector<mint> dp(N + 1, 0);
  dp[0] = 1;
  dp[1] = -1;
  rep(i, N) {
    if (i > 0)
      dp[i] += dp[i - 1];
    rep(j, K) {
      auto [l, r] = c[j];
      if (i + l < N)
        dp[i + l] += dp[i];
      if (i + r < N)
        dp[i + r] -= dp[i];
    }
  }
  cout << dp[N - 1] << endl;
}


/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author
 */

#include <fstream>
#include <iostream>

#include "bits/stdc++.h"
#include <iostream>

using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef int integer;
#define int long long
typedef pair<int, int> pii;
#define vii vector<pair<int, int>>
#define vi vector<int>
#define vvi vector<vector<int>>
#define rep(i, a, b) for (int i = a; i < (b); i++)
#define s(x) in >> x
#define s2(x, y) in >> x >> y
#define s3(x, y, z) in >> x >> y >> z
#define s4(x, y, z, w) in >> x >> y >> z >> w
#define p(x) out << (x) << endl
#define p2(x, y) out << (x) << ' ' << (y) << endl
#define p3(x, y, z) out << (x) << ' ' << (y) << ' ' << (z) << endl
#define p4(x, y, z, w)                                                         \\
  out << (x) << ' ' << (y) << ' ' << (z) << ' ' << (w) << endl
#define p1d(a, n)                                                              \\
  for (int ix = 0; ix < n - 1; ix++)                                           \\
    out << a[ix] << ' ';                                                       \\
  out << a[n - 1] << '\\n';
#define p2d(a, n, m)                                                           \\
  for (int ix = 0; ix < n; ix++) {                                             \\
    for (int jx = 0; jx < m; jx++)                                             \\
      out << a[ix][jx] << " ";                                                 \\
    out << endl;                                                               \\
  }
#define pl(x) out << (x)
#define pll(x) out << (x) << ' '
#define range(v) v.begin(), v.end()
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define rst(x) memset(x, -1, sizeof(x))
#define UNVISITED -1
#define VISITED 0
#define EXPLORED 2

#define EACH(x, a) for (auto &x : a)
template <class T> void read_v(T &x, std::istream &in) { in >> (x); }
template <class A> void read_vec(vector<A> &x, std::istream &in) {
  EACH(a, x)
  read_v(a, in);
}

ll iceildiv(const ll a, const ll b) {
  if (a == 0) {
    return 0;
  }
  return (1 + ((a - 1) / b));
}
bool sortpairbysec(const pair<int, int> &a, const pair<int, int> &b) {
  return (a.second < b.second);
}
template <typename T> T factmod(T a, T modulus) {
  int res = 1, i;
  for (i = 2; i <= a; i++) {
    res *= i;
    res %= modulus;
  }
  return res;
}
template <typename T> int powmod(T a, T b, const int m) {
  int ans = 1;
  while (b > 0) {
    if (b & 1) {
      ans *= a;
      ans %= m;
    }
    a *= a;
    a %= m;
    b >>= 1;
  }
  return ans;
}
template <typename T> int power(T a, T b) {
  int ans = 1;
  while (b > 0) {
    if (b & 1) {
      ans *= a;
    }
    a *= a;
    b >>= 1;
  }
  return ans;
}

const int CMOD = 998244353;

int dp_solve(const int n, const vector<pair<int, int>> &sv) {
  int k = sz(sv);
  vi dp(n + 1, 0);
  for (auto x : sv) {
    dp[x.first] = 1;
    dp[x.second] = -1;
  }

  for (int i = 1; i <= n; i++) {
    if (i > 1) {
      dp[i] += dp[i - 1]; // integrate
      dp[i] %= CMOD;
    }
    for (int j = 0; j < k; j++) {
      int l, r;
      tie(l, r) = sv[j];
      if (i + l <= n) {
        dp[i + l] += dp[i]; // marks
        dp[i + l] %= CMOD;
      }
      if (i + r <= n) {
        dp[i + r] -= dp[i]; // marks
        dp[i + r] %= CMOD;
        dp[i + r] = (dp[i + r] < 0 ? dp[i + r] + CMOD : dp[i + r]);
      }
    }
  }
  int ans = dp[n - 1] % CMOD;
  ans = (ans < 0 ? ans + CMOD : ans);
  return ans;
}

void ssolve(std::istream &in, std::ostream &out) {
  int n, k;
  s2(n, k);
  vii sv;
  rep(i, 0, k) {
    int l, r;
    s2(l, r);
    r++;
    sv.emplace_back(make_pair(l, r));
  }
  sort(all(sv));
  int ans = dp_solve(n, sv);
  p(ans);
  return;
}

class DLeapingTak {
public:
  void solve(std::istream &in, std::ostream &out) {
    ios_base::sync_with_stdio(false);
    in.tie(nullptr);
    out.tie(nullptr);
    int t;
    int READ = 0;
    if (READ)
      s(t);
    else
      t = 1;
    while (t--) {
      ssolve(in, out);
    }
  }
};

integer main() {
  DLeapingTak solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  solver.solve(in, out);
}

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author
 */

#include <fstream>
#include <iostream>

#include "bits/stdc++.h"
#include <iostream>

using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef int integer;
#define int long long
typedef pair<int, int> pii;
#define vii vector<pair<int, int>>
#define vi vector<int>
#define vvi vector<vector<int>>
#define rep(i, a, b) for (int i = a; i < (b); i++)
#define s(x) in >> x
#define s2(x, y) in >> x >> y
#define s3(x, y, z) in >> x >> y >> z
#define s4(x, y, z, w) in >> x >> y >> z >> w
#define p(x) out << (x) << endl
#define p2(x, y) out << (x) << ' ' << (y) << endl
#define p3(x, y, z) out << (x) << ' ' << (y) << ' ' << (z) << endl
#define p4(x, y, z, w)                                                         \\
  out << (x) << ' ' << (y) << ' ' << (z) << ' ' << (w) << endl
#define p1d(a, n)                                                              \\
  for (int ix = 0; ix < n - 1; ix++)                                           \\
    out << a[ix] << ' ';                                                       \\
  out << a[n - 1] << '\\n';
#define p2d(a, n, m)                                                           \\
  for (int ix = 0; ix < n; ix++) {                                             \\
    for (int jx = 0; jx < m; jx++)                                             \\
      out << a[ix][jx] << " ";                                                 \\
    out << endl;                                                               \\
  }
#define pl(x) out << (x)
#define pll(x) out << (x) << ' '
#define range(v) v.begin(), v.end()
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define rst(x) memset(x, -1, sizeof(x))
#define UNVISITED -1
#define VISITED 0
#define EXPLORED 2

#define EACH(x, a) for (auto &x : a)
template <class T> void read_v(T &x, std::istream &in) { in >> (x); }
template <class A> void read_vec(vector<A> &x, std::istream &in) {
  EACH(a, x)
  read_v(a, in);
}

ll iceildiv(const ll a, const ll b) {
  if (a == 0) {
    return 0;
  }
  return (1 + ((a - 1) / b));
}
bool sortpairbysec(const pair<int, int> &a, const pair<int, int> &b) {
  return (a.second < b.second);
}
template <typename T> T factmod(T a, T modulus) {
  int res = 1, i;
  for (i = 2; i <= a; i++) {
    res *= i;
    res %= modulus;
  }
  return res;
}
template <typename T> int powmod(T a, T b, const int m) {
  int ans = 1;
  while (b > 0) {
    if (b & 1) {
      ans *= a;
      ans %= m;
    }
    a *= a;
    a %= m;
    b >>= 1;
  }
  return ans;
}
template <typename T> int power(T a, T b) {
  int ans = 1;
  while (b > 0) {
    if (b & 1) {
      ans *= a;
    }
    a *= a;
    b >>= 1;
  }
  return ans;
}

const int CMOD = 998244353;

int dp_solve(const int n, const vector<pair<int, int>> &sv) {
  int k = sz(sv);
  vi dp(n, 0);
  dp[0] = 1;
  dp[1] = -1;
  //    for(auto x: sv){
  //        dp[x.first] = 1;
  //        dp[x.second] = -1;
  //    }

  for (int i = 0; i < n; i++) {
    if (i > 0) {
      dp[i] += dp[i - 1]; // integrate
      dp[i] %= CMOD;
    }
    for (int j = 0; j < k; j++) {
      int l, r;
      tie(l, r) = sv[j];
      if (i + l < n) {
        dp[i + l] += dp[i]; // marks
        dp[i + l] %= CMOD;
      }
      if (i + r < n) {
        dp[i + r] -= dp[i]; // marks
        dp[i + r] %= CMOD;
        dp[i + r] = (dp[i + r] < 0 ? dp[i + r] + CMOD : dp[i + r]);
      }
    }
  }
  int ans = dp[n - 1] % CMOD;
  ans = (ans < 0 ? ans + CMOD : ans);
  return ans;
}

void ssolve(std::istream &in, std::ostream &out) {
  int n, k;
  s2(n, k);
  vii sv;
  rep(i, 0, k) {
    int l, r;
    s2(l, r);
    r++;
    sv.emplace_back(make_pair(l, r));
  }
  sort(all(sv));
  int ans = dp_solve(n, sv);
  p(ans);
  return;
}

class DLeapingTak {
public:
  void solve(std::istream &in, std::ostream &out) {
    ios_base::sync_with_stdio(false);
    in.tie(nullptr);
    out.tie(nullptr);
    int t;
    int READ = 0;
    if (READ)
      s(t);
    else
      t = 1;
    while (t--) {
      ssolve(in, out);
    }
  }
};

integer main() {
  DLeapingTak solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  solver.solve(in, out);
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define INF 1e9
#define PI 3.14159265359
#define MOD 998244353
#define ALL(v) v.begin(), v.end()
#define ALLR(v) v.rbegin(), v.rend()
#define F first
#define S second
typedef long long ll;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
// isPrime
// modpow modinv
// getDigit
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
int main() {
  cout << fixed << setprecision(10);
  int n, k;
  cin >> n >> k;
  vector<int> l(k), r(k);
  rep(i, k) { cin >> l[i] >> r[i]; }
  vector<int> dp(n, 0);
  dp[0] = 1;
  rep(i, n) {
    rep(j, k) {
      for (int d = l[j]; d <= r[j]; d++) {
        int next = i + d;
        if (next < n && next >= 0) {
          dp[i + d] += dp[i];
          dp[i + d] = dp[i + d] % MOD;
        }
      }
    }
  }
  cout << dp[n - 1] << endl;
}

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define INF 1e9
#define PI 3.14159265359
#define MOD 998244353
#define ALL(v) v.begin(), v.end()
#define ALLR(v) v.rbegin(), v.rend()
#define F first
#define S second
typedef long long ll;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
// isPrime
// modpow modinv
// getDigit
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
int main() {
  cout << fixed << setprecision(10);
  int n, k;
  cin >> n >> k;
  vector<int> l(k), r(k);
  rep(i, k) { cin >> l[i] >> r[i]; }
  vector<int> dp(n, 0);
  dp[0] = 1;
  rep(i, n) {
    rep(j, k) {
      int d = l[j];
      int e = r[j];
      // cout << "d" << d << endl;
      if (i + d < n) {
        dp[i + d] += dp[i];
        dp[i + d] = dp[i + d] % MOD;
      }
      if (i + e + 1 < n) {
        dp[i + e + 1] = dp[i + e + 1] - dp[i] + MOD;
        dp[i + e + 1] = dp[i + e + 1] % MOD;
      }
    }
    if (i >= 1) {
      dp[i + 1] = dp[i] + dp[i + 1];
      dp[i + 1] = dp[i + 1] % MOD;
    }
    /*
    cout << "n" << i  << endl;
    rep(k,n){
      cout << dp[k] << endl;
    }
    */
  }
  cout << dp[n - 1] << endl;
}


#include <algorithm>
#include <iostream>
#include <queue>
#include <string>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define REP(i, n) for (int i = 0; i < (n); i++)
#define RREP(i, n) for (int i = (n)-1; i >= 0; i--)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define RFOR(i, a, b) for (int i = (a); i > (b); i--)
#define ALL(a) (a).begin(), (a).end()
const ll MOD = 998244353;

int main() {
  int N, K, L[10], R[10];
  cin >> N >> K;

  REP(i, K) {
    cin >> L[i] >> R[i];
    R[i]++;
  }

  ll dp[200001] = {};
  dp[0] = 1;
  FOR(i, 1, N) {
    dp[i] += dp[i - 1];
    dp[i] %= MOD;
    REP(j, K) {
      dp[i + L[j]] += dp[i];
      dp[i + L[j]] %= MOD;
      dp[i + R[j]] -= dp[i];
    }
  }
  cout << dp[N] << endl;
  return 0;
}

#include <algorithm>
#include <iostream>
#include <queue>
#include <string>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define REP(i, n) for (int i = 0; i < (n); i++)
#define RREP(i, n) for (int i = (n)-1; i >= 0; i--)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define RFOR(i, a, b) for (int i = (a); i > (b); i--)
#define ALL(a) (a).begin(), (a).end()
const ll MOD = 998244353;

int main() {
  int N, K, L[10], R[10];
  cin >> N >> K;

  REP(i, K) {
    cin >> L[i] >> R[i];
    R[i]++;
  }

  ll dp[200001] = {};
  dp[0] = 1;
  FOR(i, 1, N) {
    dp[i] += dp[i - 1];
    dp[i] %= MOD;
    REP(j, K) {
      if (i + L[j] <= N) {
        dp[i + L[j]] += dp[i];
        dp[i + L[j]] %= MOD;
      }
      if (i + R[j] <= N) {
        dp[i + R[j]] -= dp[i] - MOD;
        dp[i + R[j]] %= MOD;
      }
    }
  }
  cout << dp[N] << endl;
  return 0;
}


// ######      ###      #######    #######    ##     #     #####        ###
// ##### // #     #    #   #          #        #       # #    #    #     # #   #
// ###  // #     #   #     #        #         #       #  #   #   #       #    #
// #    ###  //
// ######   #########      #          #       #   #  #   #           #########
// #   // #     #  #       #     #           #       #    # #   #    ####   # #
// #   // #     #  #       #    #            #       #     ##   #    #  #   # #
// //
// ######   #       #   #######    #######    #      #    #####  #   #       #
// #   //

// #pragma GCC optimize(2)
// #pragma GCC optimize(3)
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("avx,avx2,fma")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double lld;
typedef vector<ll> vl;
typedef vector<vector<ll>> vvl;
typedef pair<ll, ll> ppl;
#define ain(a, n)                                                              \\
  for (ll i = 0; i < (n); ++i)                                                 \\
    cin >> (a)[i];
#define DEBUG(x) cout << '>' << #x << ':' << x << endl;
#define loop(i, n) for (ll i = 0; i < (n); ++i)
#define FOR(i, a, b) for (ll i = (a); i <= (b); ++i)
#define FORD(i, a, b) for (ll i = (a); i >= (b); --i)
#define cases                                                                  \\
  ll T = 0;                                                                    \\
  cin >> T;                                                                    \\
  while (T--)
#define ff first
#define ss second
#define all(v) v.begin(), v.end()
#define END "\\n"
#define pb push_back
#define mp make_pair
#define go(c, itr) for (auto itr = (c).begin(); itr != (c).end(); ++itr)
// #define back(c,itr) for(auto itr=(c).rbegin(); itr!=(c).rend(); ++itr)
#define PI 3.14159265359
#define inf 9e18
#define MOD 1000000007
#define MODU 998244353
#define fast                                                                   \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define MAXN 1000005
#define BLOCK 555
const string alpha = "abcdefghijklmnopqrstuvwxyz";
const ll N = 200005;
const long double epsilon = 1e-9;
inline ll myceil(ll a, ll b) {
  if (a % b == 0)
    return (a / b);
  return (a / b + 1);
}
ll spf[MAXN];
void sieve() {
  spf[1] = 1;
  for (ll i = 2; i < MAXN; i++)
    spf[i] = i;

  for (ll i = 4; i < MAXN; i += 2)
    spf[i] = 2;

  for (ll i = 3; i * i < MAXN; i++) {
    if (spf[i] == i) {
      for (ll j = i * i; j < MAXN; j += i)
        if (spf[j] == j)
          spf[j] = i;
    }
  }
}
inline ll binlen(ll n) {
  ll c = 0;
  while (n > 0)
    ++c, n /= 2;
  return c;
}
ll binexp(ll a, ll b, ll m) {
  a %= m;
  ll res = 1;
  while (b > 0) {
    if (b & 1)
      res = res * a % m;
    a = a * a % m;
    b >>= 1;
  }
  return res;
}
ll modinvfermat(ll a, ll m) { return binexp(a, m - 2, m); }
void task(bool flag) {
  if (flag)
    cout << "YES\\n";
  else
    cout << "NO\\n";
}
ll lcm(ll a, ll b) { return ((1LL * a * b) / (__gcd(a, b))); }

signed main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  // fast
  ll n, k;
  scanf("%lld%lld", &n, &k);
  vl a;
  vector<ppl> lr(k);
  loop(i, k) { scanf("%lld%lld", &lr[i].ff, &lr[i].ss); }
  loop(i, k) {
    FOR(j, lr[i].ff, lr[i].ss) { a.pb(j); }
  }
  ll m = a.size();
  vl dp(n + 1, 0);
  dp[1] = 1;
  FOR(i, 1, n) {
    loop(j, m) {
      if (i - a[j] < 0)
        continue;
      (dp[i] += dp[i - a[j]]) %= MODU;
    }
  }
  printf("%lld\\n", dp[n]);

  // #ifndef ONLINE_JUDGE
  //     cout << "\\nTime Elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << "
  //     sec\\n";
  // #endif
  return 0;
}

// ######      ###      #######    #######    ##     #     #####        ###
// ##### // #     #    #   #          #        #       # #    #    #     # #   #
// ###  // #     #   #     #        #         #       #  #   #   #       #    #
// #    ###  //
// ######   #########      #          #       #   #  #   #           #########
// #   // #     #  #       #     #           #       #    # #   #    ####   # #
// #   // #     #  #       #    #            #       #     ##   #    #  #   # #
// //
// ######   #       #   #######    #######    #      #    #####  #   #       #
// #   //

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
#pragma GCC target("avx,avx2,fma")
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double lld;
typedef vector<ll> vl;
typedef vector<vector<ll>> vvl;
typedef pair<ll, ll> ppl;
#define ain(a, n)                                                              \\
  for (ll i = 0; i < (n); ++i)                                                 \\
    cin >> (a)[i];
#define DEBUG(x) cout << '>' << #x << ':' << x << endl;
#define loop(i, n) for (ll i = 0; i < (n); ++i)
#define FOR(i, a, b) for (ll i = (a); i <= (b); ++i)
#define FORD(i, a, b) for (ll i = (a); i >= (b); --i)
#define cases                                                                  \\
  ll T = 0;                                                                    \\
  cin >> T;                                                                    \\
  while (T--)
#define ff first
#define ss second
#define all(v) v.begin(), v.end()
#define END "\\n"
#define pb push_back
#define mp make_pair
#define go(c, itr) for (auto itr = (c).begin(); itr != (c).end(); ++itr)
// #define back(c,itr) for(auto itr=(c).rbegin(); itr!=(c).rend(); ++itr)
#define PI 3.14159265359
#define inf 9e18
#define MOD 1000000007
#define MODU 998244353
#define fast                                                                   \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define MAXN 300005
#define BLOCK 555
const string alpha = "abcdefghijklmnopqrstuvwxyz";
const ll N = 200005;
const long double epsilon = 1e-9;
inline ll myceil(ll a, ll b) { return (ceil(1.0 * a / b * 1.0)); }
ll binexp(ll a, ll b, ll m) {
  a %= m;
  ll res = 1;
  while (b > 0) {
    if (b & 1)
      res = res * a % m;
    a = a * a % m;
    b >>= 1;
  }
  return res;
}
ll modinvfermat(ll a, ll m) { return binexp(a, m - 2, m); }
void task(bool flag) {
  if (flag)
    cout << "YES\\n";
  else
    cout << "NO\\n";
}
ll lcm(ll a, ll b) { return ((1LL * a * b) / (__gcd(a, b))); }

signed main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  fast ll n, k;
  cin >> n >> k;
  vector<ppl> range(k);
  loop(i, k) cin >> range[i].ff >> range[i].ss;

  vl dp(n + 1, 0), pref(n + 1, 0);
  pref[1] = 1, pref[2] = -1;
  FOR(i, 1, n) {
    (pref[i] += pref[i - 1] + dp[i]) %= MODU;
    (pref[i] += MODU) %= MODU;
    loop(j, k) {
      if (i + range[j].ff <= n)
        (dp[i + range[j].ff] += pref[i]) %= MODU;
      if (i + range[j].ss + 1 <= n) {
        (dp[i + range[j].ss + 1] -= pref[i]) %= MODU;
        (dp[i + range[j].ss + 1] += MODU) %= MODU;
      }
    }
  }

  cout << pref[n] << END;

#ifndef ONLINE_JUDGE
  cout << "\\nTime Elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " sec\\n";
#endif
  return 0;
}


#include <bits/stdc++.h>
#define rep(i, N) for (int i = 0; i < (N); i++)
#define rrep(i, n) for (int i = (int)n - 1; i >= 0; --i)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
using namespace std;
const long long MOD = 1e9 + 7;
const long long INF = 1e12;
const int inf = 1e9;
const int mod = 998244353;
typedef long long ll;
typedef pair<ll, int> P;
typedef set<int> S;

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

__attribute__((constructor)) void fastio() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << fixed << setprecision(10);
}

// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
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 {
    mint res(*this);
    return res += a;
  }
  mint operator-(const mint a) const {
    mint res(*this);
    return res -= a;
  }
  mint operator*(const mint a) const {
    mint res(*this);
    return res *= 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 {
    mint res(*this);
    return res /= a;
  }
};

istream &operator>>(istream &is, mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }

// n -> big, a -> small
mint choose(int n, int a) {
  mint x = 1, y = 1;
  rep(i, a) {
    x *= n - i;
    y *= i + 1;
  }
  return x / y;
}

vector<mint> dp(200010, 0), dpsum(200010, 0);
int main() {
  ll n, k;
  cin >> n >> k;
  vector<pair<int, int>> v(k);
  rep(i, k) cin >> v[i].first >> v[i].second;
  dp[1] = 1;
  FOR(i, 2, n + 1) {
    rep(j, k) {
      int li = max(i - v[i].second - 1, 0);
      int ri = max(i - v[i].first, 0);
      dp[i] += dpsum[ri] - dpsum[li];
    }
    dpsum[i] += dp[i - 1] + dp[i];
  }
  cout << dp[n] << endl;
  return 0;
}

#include <bits/stdc++.h>
#define rep(i, N) for (int i = 0; i < (N); i++)
#define rrep(i, n) for (int i = (int)n - 1; i >= 0; --i)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
using namespace std;
const long long MOD = 1e9 + 7;
const long long INF = 1e12;
const int inf = 1e9;
const int mod = 998244353;
typedef long long ll;
typedef pair<ll, int> P;
typedef set<int> S;

template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

__attribute__((constructor)) void fastio() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << fixed << setprecision(10);
}

// auto mod int
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
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 {
    mint res(*this);
    return res += a;
  }
  mint operator-(const mint a) const {
    mint res(*this);
    return res -= a;
  }
  mint operator*(const mint a) const {
    mint res(*this);
    return res *= 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 {
    mint res(*this);
    return res /= a;
  }
};

istream &operator>>(istream &is, mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }

// n -> big, a -> small
mint choose(int n, int a) {
  mint x = 1, y = 1;
  rep(i, a) {
    x *= n - i;
    y *= i + 1;
  }
  return x / y;
}

int main() {
  ll n, k;
  cin >> n >> k;
  vector<int> l(k), r(k);
  rep(i, k) cin >> l[i] >> r[i];
  vector<mint> dp(n + 1), dpsum(n + 1);
  dp[1] = 1;
  dpsum[1] = 1;
  FOR(i, 2, n + 1) {
    rep(j, k) {
      int li = i - r[j];
      int ri = i - l[j];
      if (ri < 0)
        continue;
      li = max(li, 1);
      dp[i] += dpsum[ri] - dpsum[li - 1];
    }
    dpsum[i] += dpsum[i - 1] + dp[i];
  }
  cout << dp[n] << endl;
  return 0;
}


using namespace std;
#include <bits/stdc++.h>
#define FASTIO                                                                 \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define ll long long
#define debug(x) cout << #x << " = " << x << endl
#define MOD 998244353
int dp[1000001];
void solve() {
  int n, k;
  cin >> n >> k;
  vector<pair<int, int>> v(k);
  for (int i = 0; i < k; i++) {
    int a, b;
    cin >> a >> b;
    v[i] = {a, b};
  }
  sort(v.begin(), v.end());
  dp[1] = 1;
  for (int i = 0; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      if (v[j].first > i)
        break;
      else {
        for (int x = v[j].first; x <= v[j].second; x++) {
          if (x > i)
            break;
          dp[i] = (dp[i] + dp[i - x]) % MOD;
        }
      }
    }
  }
  cout << dp[n] << endl;
}
int main() {

  FASTIO
  long long int t = 1;
  // cin>>t;
  while (t--)
    solve();
  return 0;
}

#include <bits/stdc++.h>
#define fastio                                                                 \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define ll long long
#define all(x) (x).begin(), (x).end()
#define print(x)                                                               \\
  if (x)                                                                       \\
    cout << "YES\\n";                                                           \\
  else                                                                         \\
    cout << "NO\\n";
#define f(i, x, y) for (ll i = x; i <= y; i++)
#define rf(i, x, y) for (ll i = x; i >= y; i--)
#define pb push_back
#define F first
#define S second
#define mod 998244353
using namespace std;
ll dp[200000 + 1];
unsigned ll pre[200000 + 1];
int main() {
  // #ifndef HP
  //   freopen("in.txt", "r", stdin);
  //   freopen("out.txt", "w", stdout);
  // #endif

  fastio;
  int t = 1;
  // cin >> t;
  while (t--) {
    ll n, k;
    cin >> n >> k;
    vector<pair<ll, ll>> v;
    f(i, 0, k - 1) {
      ll p, q;
      cin >> p >> q;
      v.pb({p, q});
    }
    dp[0] = 0;
    dp[1] = 1;
    pre[0] = 0;
    pre[1] = 1;
    for (ll i = 2; i <= n; i++) {
      for (ll j = 0; j < v.size(); j++) {
        {
          ll x = max(0LL, i - v[j].F);
          ll y = max(0LL, i - v[j].S - 1);
          dp[i] = (dp[i] + pre[x] - pre[y]) % mod;
        }
      }
      pre[i] = (pre[i - 1] + dp[i]);
    }
    cout << dp[n] << endl;
  }
}


#define LOCAL

#include <bits/stdc++.h>

using namespace std;

#define IOS                                                                    \\
  ios::sync_with_stdio(false);                                                 \\
  cin.tie(0)
#define all(x) x.begin(), x.end()
#define ff first
#define ss second
#define LLINF 0x3f3f3f3f3f3f3f3f
#define INF 0x3f3f3f3f

using llong = long long;
using PII = pair<int, int>;

const llong MOD = 998244353LL;
const double PI = acos(-1);

llong add(llong a, llong b) {
  a += b;
  if (a >= MOD)
    return a - MOD;
  return a;
}

int main() {
  IOS;
  int n, k;
  cin >> n >> k;
  vector<llong> jump;
  for (int i = 0; i < k; i++) {
    int l, r;
    cin >> l >> r;
    for (int j = l; j <= r; j++) {
      jump.push_back(j);
    }
  }
  sort(jump.begin(), jump.end());
  vector<llong> dp(n);
  dp[0] = 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < jump.size(); j++) {
      if (i + jump[j] >= n)
        break;
      dp[i + jump[j]] = add(dp[i + jump[j]], dp[i]);
    }
  }
  cout << dp[n - 1];
}

#define LOCAL

#include <bits/stdc++.h>

using namespace std;

#define IOS                                                                    \\
  ios::sync_with_stdio(false);                                                 \\
  cin.tie(0)
#define all(x) x.begin(), x.end()
#define ff first
#define ss second
#define LLINF 0x3f3f3f3f3f3f3f3f
#define INF 0x3f3f3f3f

#define LOCAL

// Copied from Gennady-Korotkevich's template

template <typename A, typename B> string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string &s) { return '"' + s + '"'; }

string to_string(const char *s) { return to_string((string)s); }

string to_string(bool b) { return (b ? "true" : "false"); }

string to_string(vector<bool> v) {
  bool first = true;
  string res = "{";
  for (int i = 0; i < static_cast<int>(v.size()); i++) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(v[i]);
  }
  res += "}\\n";
  return res;
}

template <size_t N> string to_string(bitset<N> v) {
  string res = "";
  for (size_t i = 0; i < N; i++) {
    res += static_cast<char>('0' + v[i]);
  }
  return res;
}

template <typename A> string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}\\n";
  return res;
}

template <typename A, typename B> string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " +
         to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " +
         to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

template <typename A, typename B, typename C, typename D, typename E>
string to_string(tuple<A, B, C, D, E> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " +
         to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + "," +
         to_string(get<4>(p)) + ")";
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}

#ifdef LOCAL
#define debug(...)                                                             \\
  cerr << "\\n[" << #__VA_ARGS__ << "]:\\n", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

// End of Gennady-Korotkevich's template

using llong = long long;
using PII = pair<int, int>;

const llong MOD = 998244353LL;
const double PI = acos(-1);

llong add(llong a, llong b) {
  a += b;
  if (a >= MOD)
    return a - MOD;
  return a;
}

int main() {
  IOS;
  int n, k;
  cin >> n >> k;
  vector<PII> jump(k);
  for (int i = 0; i < k; i++) {
    int l, r;
    cin >> l >> r;
    jump[i] = {l, r};
  }
  sort(jump.begin(), jump.end());
  vector<llong> dp(n + 1), realAns(n + 1);
  dp[0] = 1;
  for (int i = 0; i < n; i++) {
    if (i == 0)
      realAns[i] = dp[i];
    else {
      realAns[i] = realAns[i - 1] + dp[i];
      realAns[i] %= MOD;
    }
    for (int j = 0; j < jump.size(); j++) {
      if (i + jump[j].ff >= n)
        break;
      dp[i + jump[j].ff] += realAns[i];
      dp[i + jump[j].ff] %= MOD;
      dp[min(n, i + jump[j].ss + 1)] -= realAns[i];
      dp[min(n, i + jump[j].ss + 1)] %= MOD;
      dp[min(n, i + jump[j].ss + 1)] += MOD;
      dp[min(n, i + jump[j].ss + 1)] %= MOD;
    }
  }
  cout << dp[n - 1];
}


#include <bits/stdc++.h>
#define F first
#define S second
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define repi(n) for (int i = 0; i < (n); i++)
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define all(p) p.begin(), p.end()
#define pop_count(p) __builtin_popcountll(p)
#define len(s, e) ((e) - (s) + 1)
#define mid(s, e) ((s) + ((e) - (s)) / 2)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
const int mod = 998244353;
const int oo = 1e9;
const ll OO = 1e18;
#ifdef ONLINE_JUDGE
#define endl '\\n'
#endif
template <typename A, typename B>
std::istream &operator>>(std::istream &in, pair<A, B> &a) {
  in >> a.first >> a.second;
  return in;
}
template <typename T> std::istream &operator>>(std::istream &in, vector<T> &a) {
  for (auto &v : a)
    in >> v;
  return in;
}
template <typename T, size_t N>
std::istream &operator>>(std::istream &in, array<T, N> &a) {
  for (size_t i = 0; i < N; i++)
    in >> a[i];
  return in;
}
template <typename A, typename B>
std::ostream &operator<<(std::ostream &out, const pair<A, B> &a) {
  out << "(" << a.first << "," << a.second << ")";
  return out;
}
template <typename T, size_t N>
std::ostream &operator<<(std::ostream &out, const array<T, N> &a) {
  out << "[";
  bool first = true;
  for (auto &v : a) {
    out << (first ? "" : ", ");
    out << v;
    first = 0;
  }
  out << "]";
  return out;
}
template <typename T, class Cmp>
std::ostream &operator<<(std::ostream &out, const set<T, Cmp> &a) {
  out << "{";
  bool first = true;
  for (auto &v : a) {
    out << (first ? "" : ", ");
    out << v;
    first = 0;
  }
  out << "}";
  return out;
}
template <typename U, typename T, class Cmp>
std::ostream &operator<<(std::ostream &out, const map<U, T, Cmp> &a) {
  out << "{";
  bool first = true;
  for (auto &p : a) {
    out << (first ? "" : ", ");
    out << p.first << ":" << p.second;
    first = 0;
  }
  out << "}";
  return out;
}
template <typename T>
std::ostream &operator<<(std::ostream &out, const list<T> &a) {
  out << "[";
  bool first = true;
  for (auto &v : a) {
    out << (first ? "" : ", ");
    out << v;
    first = 0;
  }
  out << "]";
  return out;
}
#ifdef ANEEE_LOCAL
template <typename T>
std::ostream &operator<<(std::ostream &out, const vector<T> &a) {
  out << "[";
  bool first = true;
  for (auto &v : a) {
    out << (first ? "" : ", ");
    out << v;
    first = 0;
  }
  out << "]";
  return out;
}
#else
template <typename T>
std::ostream &operator<<(std::ostream &out, const vector<T> &a) {
  for (const auto &v : a)
    out << v << ' ';
  return out;
}
#endif
#ifdef ANEEE_LOCAL
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
#else
#define trace(...) 7
#endif
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << "[" << name << ": " << arg1 << "]" << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr << "[";
  cerr.write(names, comma - names) << ": " << arg1 << "]  ";
  __f(comma + 2, args...);
}
template <typename Arg1> void print(Arg1 &&arg1) { cout << arg1 << endl; }
template <typename Arg1, typename... Args>
void print(Arg1 &&arg1, Args &&...args) {
  cout << arg1 << ' ';
  print(args...);
}
template <typename Arg1> void read(Arg1 &&arg1) { cin >> arg1; }
template <typename Arg1, typename... Args>
void read(Arg1 &&arg1, Args &&...args) {
  cin >> arg1;
  read(args...);
}
int nextInt() {
  int x;
  read(x);
  return x;
}
ll nextLong() {
  ll x;
  read(x);
  return x;
}

class Timer {
  string _name;
  clock_t _start;

public:
  Timer(string name = "Runtime") {
    _name = "[" + name + ": ", _start = clock();
  }
  ~Timer() {
    cerr << _name << double(clock() - _start) / CLOCKS_PER_SEC << "]\\n";
  }
};

#ifdef ONLINE_JUDGE
#undef CASE_INFO
#endif

template <class val_t> struct segment_tree {
  int n;
  vector<val_t> T;

  template <typename X> void init(int sz, const vector<X> a) {
    n = sz;
    T.resize(2 * n);
    for (int i = 0; i < n; ++i) {
      T[n + i] = a[i];
    }
    for (int i = n - 1; i > 0; --i) {
      T[i] = T[i << 1] + T[i << 1 | 1];
      if (T[i] >= mod)
        T[i] -= mod;
    }
  }

  val_t query(int i) {
    val_t ret = 0;
    for (i += n; i > 0; i >>= 1) {
      ret += T[i];
      if (ret >= mod)
        ret -= mod;
    }
    return ret;
  }

  void update(int l, int r, val_t val) {
    for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        T[l] += val, T[l] -= (T[l] >= mod ? mod : 0), ++l;
      if (r & 1)
        --r, T[r] += val, T[r] -= (T[r] >= mod ? mod : 0);
    }
  }
};

void solve() {
  int n, k;
  read(n, k);
  vector<pair<int, int>> a(n);
  read(a);
  segment_tree<long long> st;
  st.init(n, vector<int>(n));
  st.update(0, 0, 1);
  for (int i = 0; i + 1 < n; ++i) {
    long long ways = st.query(i);
    trace(i, ways);
    for (const auto &ra : a) {
      st.update(i + ra.F, min(i + ra.S, n - 1), ways);
    }
  }
  print(st.query(n - 1));
}

signed main() {
  Timer ti;
  std::ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  int T = 1;
#ifdef TEST_CASES
  cin >> T;
#endif
  for (int tt = 1; tt <= T; tt++) {
#ifdef CASE_INFO
    cout << "Case #" << tt << ": ";
#endif
    solve();
  }
  return 0;
}

#include <bits/stdc++.h>
#define F first
#define S second
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define repi(n) for (int i = 0; i < (n); i++)
#define rep(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define all(p) p.begin(), p.end()
#define pop_count(p) __builtin_popcountll(p)
#define len(s, e) ((e) - (s) + 1)
#define mid(s, e) ((s) + ((e) - (s)) / 2)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<int, ll> pil;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
const int mod = 998244353;
const int oo = 1e9;
const ll OO = 1e18;
#ifdef ONLINE_JUDGE
#define endl '\\n'
#endif
template <typename A, typename B>
std::istream &operator>>(std::istream &in, pair<A, B> &a) {
  in >> a.first >> a.second;
  return in;
}
template <typename T> std::istream &operator>>(std::istream &in, vector<T> &a) {
  for (auto &v : a)
    in >> v;
  return in;
}
template <typename T, size_t N>
std::istream &operator>>(std::istream &in, array<T, N> &a) {
  for (size_t i = 0; i < N; i++)
    in >> a[i];
  return in;
}
template <typename A, typename B>
std::ostream &operator<<(std::ostream &out, const pair<A, B> &a) {
  out << "(" << a.first << "," << a.second << ")";
  return out;
}
template <typename T, size_t N>
std::ostream &operator<<(std::ostream &out, const array<T, N> &a) {
  out << "[";
  bool first = true;
  for (auto &v : a) {
    out << (first ? "" : ", ");
    out << v;
    first = 0;
  }
  out << "]";
  return out;
}
template <typename T, class Cmp>
std::ostream &operator<<(std::ostream &out, const set<T, Cmp> &a) {
  out << "{";
  bool first = true;
  for (auto &v : a) {
    out << (first ? "" : ", ");
    out << v;
    first = 0;
  }
  out << "}";
  return out;
}
template <typename U, typename T, class Cmp>
std::ostream &operator<<(std::ostream &out, const map<U, T, Cmp> &a) {
  out << "{";
  bool first = true;
  for (auto &p : a) {
    out << (first ? "" : ", ");
    out << p.first << ":" << p.second;
    first = 0;
  }
  out << "}";
  return out;
}
template <typename T>
std::ostream &operator<<(std::ostream &out, const list<T> &a) {
  out << "[";
  bool first = true;
  for (auto &v : a) {
    out << (first ? "" : ", ");
    out << v;
    first = 0;
  }
  out << "]";
  return out;
}
#ifdef ANEEE_LOCAL
template <typename T>
std::ostream &operator<<(std::ostream &out, const vector<T> &a) {
  out << "[";
  bool first = true;
  for (auto &v : a) {
    out << (first ? "" : ", ");
    out << v;
    first = 0;
  }
  out << "]";
  return out;
}
#else
template <typename T>
std::ostream &operator<<(std::ostream &out, const vector<T> &a) {
  for (const auto &v : a)
    out << v << ' ';
  return out;
}
#endif
#ifdef ANEEE_LOCAL
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
#else
#define trace(...) 7
#endif
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << "[" << name << ": " << arg1 << "]" << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr << "[";
  cerr.write(names, comma - names) << ": " << arg1 << "]  ";
  __f(comma + 2, args...);
}
template <typename Arg1> void print(Arg1 &&arg1) { cout << arg1 << endl; }
template <typename Arg1, typename... Args>
void print(Arg1 &&arg1, Args &&...args) {
  cout << arg1 << ' ';
  print(args...);
}
template <typename Arg1> void read(Arg1 &&arg1) { cin >> arg1; }
template <typename Arg1, typename... Args>
void read(Arg1 &&arg1, Args &&...args) {
  cin >> arg1;
  read(args...);
}
int nextInt() {
  int x;
  read(x);
  return x;
}
ll nextLong() {
  ll x;
  read(x);
  return x;
}

class Timer {
  string _name;
  clock_t _start;

public:
  Timer(string name = "Runtime") {
    _name = "[" + name + ": ", _start = clock();
  }
  ~Timer() {
    cerr << _name << double(clock() - _start) / CLOCKS_PER_SEC << "]\\n";
  }
};

#ifdef ONLINE_JUDGE
#undef CASE_INFO
#endif

template <class val_t> struct segment_tree {
  int n;
  vector<val_t> T;

  template <typename X> void init(int sz, const vector<X> a) {
    n = sz;
    T.resize(2 * n);
    for (int i = 0; i < n; ++i) {
      T[n + i] = a[i];
    }
    for (int i = n - 1; i > 0; --i) {
      T[i] = T[i << 1] + T[i << 1 | 1];
      if (T[i] >= mod)
        T[i] -= mod;
    }
  }

  val_t query(int i) {
    val_t ret = 0;
    for (i += n; i > 0; i >>= 1) {
      ret += T[i];
      if (ret >= mod)
        ret -= mod;
    }
    return ret;
  }

  void update(int l, int r, val_t val) {
    for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        T[l] += val, T[l] -= (T[l] >= mod ? mod : 0), ++l;
      if (r & 1)
        --r, T[r] += val, T[r] -= (T[r] >= mod ? mod : 0);
    }
  }
};

void solve() {
  int n, k;
  read(n, k);
  vector<pair<int, int>> a(k);
  read(a);
  segment_tree<long long> st;
  st.init(n, vector<int>(n));
  st.update(0, 0, 1);
  for (int i = 0; i + 1 < n; ++i) {
    long long ways = st.query(i);
    trace(i, ways);
    for (const auto &ra : a) {
      st.update(i + ra.F, min(i + ra.S, n - 1), ways);
    }
  }
  print(st.query(n - 1));
}

signed main() {
  Timer ti;
  std::ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  int T = 1;
#ifdef TEST_CASES
  cin >> T;
#endif
  for (int tt = 1; tt <= T; tt++) {
#ifdef CASE_INFO
    cout << "Case #" << tt << ": ";
#endif
    solve();
  }
  return 0;
}


#include "bits/stdc++.h"

#define _USE_MATH_DEFINES
#include <math.h>
using namespace std;

using ll = long long;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using ld = long double;
using vld = std::vector<ld>;
using vvld = std::vector<vld>;
using vvvld = std::vector<vvld>;
using bl = bool;
using vbl = std::vector<bl>;
using vvbl = std::vector<vbl>;
using vvvbl = std::vector<vvbl>;
using ss = string;
using vss = std::vector<ss>;

#define rep(i, n) for (ll(i) = 0; (i) < (ll)(n); (i)++)
#define repm(i, n, m) for (ll(i) = m; (i) < (ll)(n); (i)++)
#define repi(i, n) for (ll(i) = (n - 1); (i) >= (ll)(0); (i)--)
#define repit(itr, ds) for (auto itr = ds.begin(); itr != ds.end(); itr++)

#define all(v) v.begin(), v.end()
#define println(v)                                                             \\
  {                                                                            \\
    ll i = 0;                                                                  \\
    for (auto(a) : v) {                                                        \\
      cerr << setw(2) << i << " : " << a << endl;                              \\
      i++;                                                                     \\
    }                                                                          \\
  }
template <class T> void printsp(vector<T> v, size_t w = 3) {
  for (auto(a) : v) {
    cerr << setw(w) << a << " ";
  }
  cerr << endl;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> void bye(T a) {
  cout << a << '\\n';
  exit(0);
}
template <class T1, class T2> void bye(T1 a, T2 b) {
  cout << a << " " << b << '\\n';
  exit(0);
}
template <class T1, class T2, class T3> void bye(T1 a, T2 b, T3 c) {
  cout << a << " " << b << " " << c << '\\n';
  exit(0);
}
template <class T> void bye(vector<T> A) {
  rep(i, (ll)A.size()) {
    cout << A[i];
    if (i != (ll)A.size() - 1) {
      cout << " ";
    }
  }
  cout << endl;
  exit(0);
}
// vector
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (T &x : vec)
    is >> x;
  return is;
}
// pair
template <typename T, typename U>
ostream &operator<<(ostream &os, pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}
// vector<string>
ostream &operator<<(ostream &os, const vector<string> &vec) {

  ll N = to_string((ll)vec.size()).length();
  string head;
  rep(i, N + 2) { head += "-"; }
  rep(i, 40) { head += to_string(i % 10); }
  os << setw(N) << head << endl;

  for (ll i = 0; i < (ll)vec.size(); i++) {
    os << setw(N) << i << ": " << vec[i] << endl;
  }
  return os;
}
// vector<ll>
ostream &operator<<(ostream &os, const vector<ll> &vec) {
  ll N = to_string((ll)vec.size()).length();
  for (ll i = 0; i < (ll)vec.size(); i++) {
    os << setw(N) << i << ": " << vec[i] << endl;
  }
  return os;
}
// vector<ld>
ostream &operator<<(ostream &os, const vector<ld> &vec) {
  ll N = to_string((ll)vec.size()).length();
  for (ll i = 0; i < (ll)vec.size(); i++) {
    os << setw(N) << i << ": " << vec[i] << endl;
    // os <<vec[i] << endl;
  }
  return os;
}
// vvll
ostream &operator<<(ostream &os, const vector<vector<ll>> &mat) {
  ll keta = 1;
  rep(i, mat.size()) {
    rep(j, mat[i].size()) {
      ll x = mat[i][j];
      chmax(keta, (ll)to_string(x).length());
    }
  }
  ll N = to_string((ll)mat.size()).length();
  rep(i, mat.size()) {
    os << setw(N) << i << ": ";
    rep(j, mat[i].size()) {
      ll x = mat[i][j];
      os << setw(keta + 1) << x;
    }
    os << endl;
  }
  return os;
}

// vector
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {

  for (ll i = 0; i < (ll)vec.size(); i++) {
    // os << setw(3) <<i <<" : "<< setw(5) << vec[i] << endl;
    os << setw(5) << vec[i];
  }
  os << endl;
  return os;
}
// map
template <typename T, typename U>
ostream &operator<<(ostream &os, map<T, U> &map_var) {
  os << "{";
  repit(itr, map_var) {
    // for(auto itr :  map_var) {
    os << *itr;
    itr++;
    if (itr != map_var.end())
      os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
// set
template <typename T> ostream &operator<<(ostream &os, set<T> &set_var) {
  os << "{";
  repit(itr, set_var) {
    // for( auto itr : set_var) {
    os << *itr;
    itr++;
    if (itr != set_var.end())
      os << ", ";
    itr--;
  }
  os << "}";

  return os;
}
#define DUMPOUT cerr
#define DUMPCOLOR ("\\033[36m")
void dump_func() { DUMPOUT << endl; }
template <class Head, class... Tail>
void dump_func(Head &&head, Tail &&...tail) {
  DUMPOUT << DUMPCOLOR;
  DUMPOUT << head;
  if (sizeof...(Tail) > 0) {
    DUMPOUT << ", ";
  }
  dump_func(std::move(tail)...);
  DUMPOUT << "\\033[m";
}
#ifdef DEBUG_
#define DEB
#define dump(...)                                                              \\
  DUMPOUT << DUMPCOLOR << "" << string(#__VA_ARGS__) << ": "                   \\
          << "[" << to_string(__LINE__) << ":" << __FUNCTION__ << "]" << endl  \\
          << "\\033[m"                                                          \\
          << "",                                                               \\
      dump_func(__VA_ARGS__)
#else
#define DEB if (false)
#define dump(...)
#endif

struct Fast {
  Fast() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(std::numeric_limits<double>::max_digits10);
  }
} fast;

inline vll cinvll(ll N, ll minus = 0) {
  vll A(N);
  rep(i, N) {
    cin >> A[i];
    A[i] -= minus;
  }
  return move(A);
}
inline vvll zerosll(ll H, ll W, ll val = 0) {
  vvll A(H, vll(W, val));
  return move(A);
}
inline vvvll zerosll3(ll H, ll W, ll C, ll val = 0) {
  vvvll A(H, vvll(W, vll(C, val)));
  return move(A);
}

vvll cinvll2(ll H, ll W, ll bias = 0) {
  vvll A = zerosll(H, W);
  rep(i, H) {
    rep(j, W) {
      cin >> A[i][j];
      A[i][j] += bias;
    }
  }
  return move(A);
}
tuple<vll, vll> aho2(ll N) {
  vll A(N), B(N);
  rep(i, N) { cin >> A[i] >> B[i]; }
  return (make_tuple(A, B));
}

template <class T = ll> inline vector<T> cinv(ll N, T val = 0) {
  vector<T> v(N);
  rep(i, N) {
    cin >> v[i];
    v[i] += val;
  }
  return move(v);
}
template <class T = ll> inline vector<vector<T>> zeros(ll H, ll W, T val = 0) {
  vector<vector<T>> A(H, vector<T>(W, val));
  return move(A);
}
template <class T = ll>
inline vector<vector<vector<T>>> zeros3(ll H, ll W, ll C, T val = 0) {
  vector<vector<vector<T>>> A(H, vector<vector<T>>(W, vector<T>(C, val)));
  return move(A);
}

template <typename TTT>
vector<ll> arg_sort(const vector<TTT> &A, bool ascend = true) {
  vector<ll> index(A.size());
  iota(index.begin(), index.end(), 0);
  if (ascend) {
    std::sort(all(index), [&A](TTT i1, TTT i2) { return A[i1] < A[i2]; });
  } else {
    std::sort(all(index), [&A](TTT i1, TTT i2) { return A[i1] > A[i2]; });
  }
  return index;
}
template <typename TTT> vector<TTT> permute(vector<TTT> src, vll idx) {
  vector<TTT> dst(src.size());
  rep(i, src.size()) { dst[i] = src[idx[i]]; }
  return move(dst);
}

ll powll(ll a, ll b) {
  ll c = 1LL;
  rep(i, b) { c *= a; }
  return c;
}

void funcA() {
  ss S;
  cin >> S;
  if (S[S.length() - 1] == 's') {
    bye(S + "es");
  }
  bye(S + "s");
}
void funcB() {
  ll N;
  cin >> N;

  ll cnt = 0;
  vll Z(N);
  rep(i, N) {
    ll a, b;
    cin >> a >> b;
    if (a == b) {
      Z[i] = 1;
    }
  }
  rep(i, N - 2) {
    if (Z[i] == 1 and Z[i + 1] == 1 and Z[i + 2] == 1) {
      bye("Yes");
    }
  }
  bye("No");
}
void funcC() {
  ll N;
  cin >> N;

  ll cnt = 0;
  repm(a, N + 1, 1) {
    repm(b, N + 1, 1) {
      ll n = a * b;
      if (N - n >= 1) {
        cnt++;
      } else {
        break;
      }
    }
  }
  bye(cnt);
}
void func() {
  ll N, K;
  cin >> N >> K;
  ll MOD = 998244353;
  vvll LR = zeros(K, 2);
  rep(i, K) {
    cin >> LR[i][0];
    cin >> LR[i][1];
    LR[i][0];
    LR[i][1];
  }
  vll imos(N + 1, 0);
  vll cnts(N + 1, 0);
  cnts[0] = 0;
  rep(i, N) {
    // cnt %=MOD;
    rep(k, K) {
      ll l = LR[k][0];
      ll r = LR[k][1];
      ll cnt = cnts[i];
      if (i == 0) {
        cnt = 1;
      }
      imos[i + l] += cnt;
      imos[i + l] %= MOD;
      if (i + r + 1 <= N) {
        imos[i + r + 1] -= cnt;
        imos[i + r + 1] %= MOD;
      }
      cnts[i + 1] = cnts[i] + imos[i + 1];
      cnts[i + 1] %= MOD;
    }
    // dump(imos);
    // dump(cnts);
  }
  dump(LR);
  rep(i, N) { imos[i + 1] = imos[i + 1] + imos[i]; }
  dump(cnts);
  ll ans = cnts[N - 1] % MOD;
  if (ans < 0) {
    ans += MOD;
  }
  bye(ans);
}

int main() {
  dump("start");
  func();
  return 0;
}

#include "bits/stdc++.h"

#define _USE_MATH_DEFINES
#include <math.h>
using namespace std;

using ll = long long;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using ld = long double;
using vld = std::vector<ld>;
using vvld = std::vector<vld>;
using vvvld = std::vector<vvld>;
using bl = bool;
using vbl = std::vector<bl>;
using vvbl = std::vector<vbl>;
using vvvbl = std::vector<vvbl>;
using ss = string;
using vss = std::vector<ss>;

#define rep(i, n) for (ll(i) = 0; (i) < (ll)(n); (i)++)
#define repm(i, n, m) for (ll(i) = m; (i) < (ll)(n); (i)++)
#define repi(i, n) for (ll(i) = (n - 1); (i) >= (ll)(0); (i)--)
#define repit(itr, ds) for (auto itr = ds.begin(); itr != ds.end(); itr++)

#define all(v) v.begin(), v.end()
#define println(v)                                                             \\
  {                                                                            \\
    ll i = 0;                                                                  \\
    for (auto(a) : v) {                                                        \\
      cerr << setw(2) << i << " : " << a << endl;                              \\
      i++;                                                                     \\
    }                                                                          \\
  }
template <class T> void printsp(vector<T> v, size_t w = 3) {
  for (auto(a) : v) {
    cerr << setw(w) << a << " ";
  }
  cerr << endl;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> void bye(T a) {
  cout << a << '\\n';
  exit(0);
}
template <class T1, class T2> void bye(T1 a, T2 b) {
  cout << a << " " << b << '\\n';
  exit(0);
}
template <class T1, class T2, class T3> void bye(T1 a, T2 b, T3 c) {
  cout << a << " " << b << " " << c << '\\n';
  exit(0);
}
template <class T> void bye(vector<T> A) {
  rep(i, (ll)A.size()) {
    cout << A[i];
    if (i != (ll)A.size() - 1) {
      cout << " ";
    }
  }
  cout << endl;
  exit(0);
}
// vector
template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (T &x : vec)
    is >> x;
  return is;
}
// pair
template <typename T, typename U>
ostream &operator<<(ostream &os, pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}
// vector<string>
ostream &operator<<(ostream &os, const vector<string> &vec) {

  ll N = to_string((ll)vec.size()).length();
  string head;
  rep(i, N + 2) { head += "-"; }
  rep(i, 40) { head += to_string(i % 10); }
  os << setw(N) << head << endl;

  for (ll i = 0; i < (ll)vec.size(); i++) {
    os << setw(N) << i << ": " << vec[i] << endl;
  }
  return os;
}
// vector<ll>
ostream &operator<<(ostream &os, const vector<ll> &vec) {
  ll N = to_string((ll)vec.size()).length();
  for (ll i = 0; i < (ll)vec.size(); i++) {
    os << setw(N) << i << ": " << vec[i] << endl;
  }
  return os;
}
// vector<ld>
ostream &operator<<(ostream &os, const vector<ld> &vec) {
  ll N = to_string((ll)vec.size()).length();
  for (ll i = 0; i < (ll)vec.size(); i++) {
    os << setw(N) << i << ": " << vec[i] << endl;
    // os <<vec[i] << endl;
  }
  return os;
}
// vvll
ostream &operator<<(ostream &os, const vector<vector<ll>> &mat) {
  ll keta = 1;
  rep(i, mat.size()) {
    rep(j, mat[i].size()) {
      ll x = mat[i][j];
      chmax(keta, (ll)to_string(x).length());
    }
  }
  ll N = to_string((ll)mat.size()).length();
  rep(i, mat.size()) {
    os << setw(N) << i << ": ";
    rep(j, mat[i].size()) {
      ll x = mat[i][j];
      os << setw(keta + 1) << x;
    }
    os << endl;
  }
  return os;
}

// vector
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {

  for (ll i = 0; i < (ll)vec.size(); i++) {
    // os << setw(3) <<i <<" : "<< setw(5) << vec[i] << endl;
    os << setw(5) << vec[i];
  }
  os << endl;
  return os;
}
// map
template <typename T, typename U>
ostream &operator<<(ostream &os, map<T, U> &map_var) {
  os << "{";
  repit(itr, map_var) {
    // for(auto itr :  map_var) {
    os << *itr;
    itr++;
    if (itr != map_var.end())
      os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
// set
template <typename T> ostream &operator<<(ostream &os, set<T> &set_var) {
  os << "{";
  repit(itr, set_var) {
    // for( auto itr : set_var) {
    os << *itr;
    itr++;
    if (itr != set_var.end())
      os << ", ";
    itr--;
  }
  os << "}";

  return os;
}
#define DUMPOUT cerr
#define DUMPCOLOR ("\\033[36m")
void dump_func() { DUMPOUT << endl; }
template <class Head, class... Tail>
void dump_func(Head &&head, Tail &&...tail) {
  DUMPOUT << DUMPCOLOR;
  DUMPOUT << head;
  if (sizeof...(Tail) > 0) {
    DUMPOUT << ", ";
  }
  dump_func(std::move(tail)...);
  DUMPOUT << "\\033[m";
}
#ifdef DEBUG_
#define DEB
#define dump(...)                                                              \\
  DUMPOUT << DUMPCOLOR << "" << string(#__VA_ARGS__) << ": "                   \\
          << "[" << to_string(__LINE__) << ":" << __FUNCTION__ << "]" << endl  \\
          << "\\033[m"                                                          \\
          << "",                                                               \\
      dump_func(__VA_ARGS__)
#else
#define DEB if (false)
#define dump(...)
#endif

struct Fast {
  Fast() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(std::numeric_limits<double>::max_digits10);
  }
} fast;

inline vll cinvll(ll N, ll minus = 0) {
  vll A(N);
  rep(i, N) {
    cin >> A[i];
    A[i] -= minus;
  }
  return move(A);
}
inline vvll zerosll(ll H, ll W, ll val = 0) {
  vvll A(H, vll(W, val));
  return move(A);
}
inline vvvll zerosll3(ll H, ll W, ll C, ll val = 0) {
  vvvll A(H, vvll(W, vll(C, val)));
  return move(A);
}

vvll cinvll2(ll H, ll W, ll bias = 0) {
  vvll A = zerosll(H, W);
  rep(i, H) {
    rep(j, W) {
      cin >> A[i][j];
      A[i][j] += bias;
    }
  }
  return move(A);
}
tuple<vll, vll> aho2(ll N) {
  vll A(N), B(N);
  rep(i, N) { cin >> A[i] >> B[i]; }
  return (make_tuple(A, B));
}

template <class T = ll> inline vector<T> cinv(ll N, T val = 0) {
  vector<T> v(N);
  rep(i, N) {
    cin >> v[i];
    v[i] += val;
  }
  return move(v);
}
template <class T = ll> inline vector<vector<T>> zeros(ll H, ll W, T val = 0) {
  vector<vector<T>> A(H, vector<T>(W, val));
  return move(A);
}
template <class T = ll>
inline vector<vector<vector<T>>> zeros3(ll H, ll W, ll C, T val = 0) {
  vector<vector<vector<T>>> A(H, vector<vector<T>>(W, vector<T>(C, val)));
  return move(A);
}

template <typename TTT>
vector<ll> arg_sort(const vector<TTT> &A, bool ascend = true) {
  vector<ll> index(A.size());
  iota(index.begin(), index.end(), 0);
  if (ascend) {
    std::sort(all(index), [&A](TTT i1, TTT i2) { return A[i1] < A[i2]; });
  } else {
    std::sort(all(index), [&A](TTT i1, TTT i2) { return A[i1] > A[i2]; });
  }
  return index;
}
template <typename TTT> vector<TTT> permute(vector<TTT> src, vll idx) {
  vector<TTT> dst(src.size());
  rep(i, src.size()) { dst[i] = src[idx[i]]; }
  return move(dst);
}

ll powll(ll a, ll b) {
  ll c = 1LL;
  rep(i, b) { c *= a; }
  return c;
}

void funcA() {
  ss S;
  cin >> S;
  if (S[S.length() - 1] == 's') {
    bye(S + "es");
  }
  bye(S + "s");
}
void funcB() {
  ll N;
  cin >> N;

  ll cnt = 0;
  vll Z(N);
  rep(i, N) {
    ll a, b;
    cin >> a >> b;
    if (a == b) {
      Z[i] = 1;
    }
  }
  rep(i, N - 2) {
    if (Z[i] == 1 and Z[i + 1] == 1 and Z[i + 2] == 1) {
      bye("Yes");
    }
  }
  bye("No");
}
void funcC() {
  ll N;
  cin >> N;

  ll cnt = 0;
  repm(a, N + 1, 1) {
    repm(b, N + 1, 1) {
      ll n = a * b;
      if (N - n >= 1) {
        cnt++;
      } else {
        break;
      }
    }
  }
  bye(cnt);
}
void func() {
  ll N, K;
  cin >> N >> K;
  ll MOD = 998244353;
  vvll LR = zeros(K, 2);
  rep(i, K) {
    cin >> LR[i][0];
    cin >> LR[i][1];
    LR[i][0];
    LR[i][1];
  }
  vll imos(N + 1, 0);
  vll cnts(N + 1, 0);
  cnts[0] = 0;
  rep(i, N) {
    // cnt %=MOD;
    rep(k, K) {
      ll l = LR[k][0];
      ll r = LR[k][1];
      ll cnt = cnts[i];
      if (i == 0) {
        cnt = 1;
      }
      if (i + l <= N) {
        imos[i + l] += cnt;
        imos[i + l] %= MOD;
      }
      if (i + r + 1 <= N) {
        imos[i + r + 1] -= cnt;
        imos[i + r + 1] %= MOD;
      }
      cnts[i + 1] = cnts[i] + imos[i + 1];
      cnts[i + 1] %= MOD;
    }
    // dump(imos);
    // dump(cnts);
  }
  dump(LR);
  dump(cnts);
  ll ans = cnts[N - 1] % MOD;
  if (ans < 0) {
    ans += MOD;
  }
  bye(ans);
}

int main() {
  dump("start");
  func();
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <deque>
#include <iostream>
#include <numeric>
#include <queue>
#include <string>
#include <utility>
#include <vector>

using namespace std;
#define ALL(a) (a).begin(), (a).end()
#define REP(i, n) for (size_t i = 0; i < (n); i++)
#define nvec(T, v, n)                                                          \\
  vector<T> v(n);                                                              \\
  REP(i, n) { cin >> (v)[i]; }
#define npairs(T1, T2, v, n)                                                   \\
  vector<pair<T1, T2>> v(n);                                                   \\
  REP(i, n) { cin >> v[i].first >> v[i].second; }
#define ntuples(T1, T2, T3, v, n)                                              \\
  vector<tuple<T1, T2, T3>> v(n);                                              \\
  REP(i, n) { cin >> get<0>(v[i]) >> get<1>(v[i]) >> get<2>(v[i]); }
#define vec2d(T, v, m, n) vector<vector<T>>(v)(m, vector<T>(n))
#define nvec2d(T, v, m, n)                                                     \\
  vec2d(T, v, m, n);                                                           \\
  REP(j, m) {                                                                  \\
    REP(i, n) { cin >> (v[j])[i]; }                                            \\
  }

#define min_index(v) size_t(min_element(all(v)) - (v).begin())
#define max_index(v) size_t(max_element(all(v)) - (v).begin())
#define min_e(v) *min_element(ALL(v))
#define max_e(v) *max_element(ALL(v))

#define count_le(v, a) size_t(upper_bound(ALL(v), a) - (v).begin())
#define count_lt(v, a) size_t(lower_bound(ALL(v), a) - (v).begin())
#define count_ge(v, a) size_t((v).end() - lower_bound(ALL(v), a))
#define count_gt(v, a) size_t((v).end() - upper_bound(ALL(v), a))

#define order(neq_sl) [](const auto s, const auto l) { return neq_sl; }
#define make_lr(v, type, l, r)                                                 \\
  vector<type> l(n + 1), r(n + 1);                                             \\
  FOR(i, n) {                                                                  \\
    l[i + 1] = l[i] + v[i];                                                    \\
    r[i + 1] = r[i] + v[n - 1 - i];                                            \\
  }

#define acm accumulate
#define SUM(v) accumulate(ALL(v), 0l)
#define SORT(v) sort(ALL(v))
#define P 1000000007
long powP(long a, long b) {
  if (b == 1)
    return a;
  else if (b == 0)
    return 1;
  else if (b < 0)
    return powP(a, P + b - 1);
  else
    return (powP(a, b / 2) * powP(a, b / 2 + b % 2)) % P;
}

#define GCD(v) gcd(ALL(v), 0l)

/*template <typename T>
T gcd(T a, T b) {
    if (a > b) swap(a, b);
    if (a == 0) return b;
    return gcd(b%a, a);
}
template <typename InputItr, typename T>
T gcd(InputItr first, InputItr last, T init) {
    for (; first != last; ++first) init = gcd(init, *first);
    return init;
}*/

template <typename T> using vec = vector<T>;

template <typename T> using vvec = vector<vector<T>>;

int main() {
  int n, k;
  cin >> n >> k;
  vec<bool> v(n + 1, 0);
  int l, r;
  for (int i = 0; i < k; i++) {
    cin >> l >> r;
    for (int j = l; j <= r; j++) {
      v[j] = 1;
    }
  }
  vec<long long> dp(n + 1, 0);
  dp[n] = 1;
  for (size_t i = n - 1; i > 0; i--) {
    for (int j = i + 1; j <= n; j++) {
      dp[i] += dp[j] * v[j - i];
      dp[i] %= 998244353;
    }
  }
  cout << dp[1];
}

/* きょむ〜 */

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <deque>
#include <iostream>
#include <numeric>
#include <queue>
#include <string>
#include <utility>
#include <vector>

using namespace std;
#define ALL(a) (a).begin(), (a).end()
#define REP(i, n) for (size_t i = 0; i < (n); i++)
#define nvec(T, v, n)                                                          \\
  vector<T> v(n);                                                              \\
  REP(i, n) { cin >> (v)[i]; }
#define npairs(T1, T2, v, n)                                                   \\
  vector<pair<T1, T2>> v(n);                                                   \\
  REP(i, n) { cin >> v[i].first >> v[i].second; }
#define ntuples(T1, T2, T3, v, n)                                              \\
  vector<tuple<T1, T2, T3>> v(n);                                              \\
  REP(i, n) { cin >> get<0>(v[i]) >> get<1>(v[i]) >> get<2>(v[i]); }
#define vec2d(T, v, m, n) vector<vector<T>>(v)(m, vector<T>(n))
#define nvec2d(T, v, m, n)                                                     \\
  vec2d(T, v, m, n);                                                           \\
  REP(j, m) {                                                                  \\
    REP(i, n) { cin >> (v[j])[i]; }                                            \\
  }

#define min_index(v) size_t(min_element(all(v)) - (v).begin())
#define max_index(v) size_t(max_element(all(v)) - (v).begin())
#define min_e(v) *min_element(ALL(v))
#define max_e(v) *max_element(ALL(v))

#define count_le(v, a) size_t(upper_bound(ALL(v), a) - (v).begin())
#define count_lt(v, a) size_t(lower_bound(ALL(v), a) - (v).begin())
#define count_ge(v, a) size_t((v).end() - lower_bound(ALL(v), a))
#define count_gt(v, a) size_t((v).end() - upper_bound(ALL(v), a))

#define order(neq_sl) [](const auto s, const auto l) { return neq_sl; }
#define make_lr(v, type, l, r)                                                 \\
  vector<type> l(n + 1), r(n + 1);                                             \\
  FOR(i, n) {                                                                  \\
    l[i + 1] = l[i] + v[i];                                                    \\
    r[i + 1] = r[i] + v[n - 1 - i];                                            \\
  }

#define acm accumulate
#define SUM(v) accumulate(ALL(v), 0l)
#define SORT(v) sort(ALL(v))
#define P 1000000007
long powP(long a, long b) {
  if (b == 1)
    return a;
  else if (b == 0)
    return 1;
  else if (b < 0)
    return powP(a, P + b - 1);
  else
    return (powP(a, b / 2) * powP(a, b / 2 + b % 2)) % P;
}

#define GCD(v) gcd(ALL(v), 0l)

/*template <typename T>
T gcd(T a, T b) {
    if (a > b) swap(a, b);
    if (a == 0) return b;
    return gcd(b%a, a);
}
template <typename InputItr, typename T>
T gcd(InputItr first, InputItr last, T init) {
    for (; first != last; ++first) init = gcd(init, *first);
    return init;
}*/

template <typename T> using vec = vector<T>;

template <typename T> using vvec = vector<vector<T>>;

int main() {
  int n, k;
  cin >> n >> k;
  vec<int> l(k), r(k);
  for (int i = 0; i < k; i++) {
    cin >> l[i] >> r[i];
  }
  vec<long long> dp(n + 1, 0);
  dp[0] = 1;
  for (int i = 1; i <= n; i++) {
    dp[i] = dp[i - 1];
    if (i == 1)
      dp[i] = 0;
    for (int j = 0; j < k; j++) {
      if (i - l[j] >= 0)
        dp[i] += dp[i - l[j]];
      if (i - r[j] - 1 >= 0) {
        dp[i] -= dp[i - r[j] - 1];
        dp[i] += 998244353;
      }
      dp[i] %= 998244353;
    }
  }
  cout << dp[n - 1];
}

/* きょむ〜 */


#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

// template
#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define ALL(v) (v).begin(), (v).end()
typedef long long int ll;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;
const double eps = 1e-12;
template <typename T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
// end

template <unsigned mod = 998244353> struct fp {
  int v;
  static unsigned get_mod() { return mod; }
  int inv() const {
    int tmp, a = v, b = mod, x = 1, y = 0;
    while (b)
      tmp = a / b, a -= tmp * b, swap(a, b), x -= tmp * y, swap(x, y);
    if (x < 0) {
      x += mod;
    }
    return x;
  }
  fp() : v(0) {}
  fp(ll x) : v(x >= 0 ? x % mod : mod + (x % mod)) {}
  fp operator-() const { return fp(-v); }
  fp pow(ll t) {
    fp res = 1, b = *this;
    while (t) {
      if (t & 1)
        res *= b;
      b *= b;
      t >>= 1;
    }
    return res;
  }
  fp &operator+=(const fp &x) {
    if ((v += x.v) >= (int)mod)
      v -= mod;
    return *this;
  }
  fp &operator-=(const fp &x) {
    if ((v += mod - x.v) >= (int)mod)
      v -= mod;
    return *this;
  }
  fp &operator*=(const fp &x) {
    v = ll(v) * x.v % mod;
    return *this;
  }
  fp &operator/=(const fp &x) {
    v = ll(v) * x.inv() % mod;
    return *this;
  }
  fp operator+(const fp &x) const { return fp(*this) += x; }
  fp operator-(const fp &x) const { return fp(*this) -= x; }
  fp operator*(const fp &x) const { return fp(*this) *= x; }
  fp operator/(const fp &x) const { return fp(*this) /= x; }
  bool operator==(const fp &x) const { return v == x.v; }
  bool operator!=(const fp &x) const { return v != x.v; }
};
using Fp = fp<>;

template <typename M, typename N = M> struct LazySegmentTree {
  using F = function<M(M, M)>;
  using G = function<M(M, N)>;
  using H = function<N(N, N)>;
  int sz, height;
  vector<M> data;
  vector<N> lazy;
  const F f;
  const G g;
  const H h;
  const M m1;
  const N n1;
  LazySegmentTree(int n, const F f, const G g, const H h, const M &m1,
                  const N n1)
      : f(f), g(g), h(h), m1(m1), n1(n1) {
    sz = 1, height = 0;
    while (sz < n)
      sz <<= 1, height++;
    data.assign(2 * sz, m1);
    lazy.assign(2 * sz, n1);
  }
  void build(vector<M> v) {
    rep(i, 0, v.size()) data[i + sz] = v[i];
    for (int k = sz - 1; k > 0; k--)
      data[k] = f(data[2 * k], data[2 * k + 1]);
  }
  M ref(int k) { return lazy[k] == n1 ? data[k] : g(data[k], lazy[k]); }
  void recalc(int k) {
    while (k >>= 1)
      data[k] = f(ref(2 * k), ref(2 * k + 1));
  }
  void thrust(int k) {
    for (int i = height; i > 0; i--)
      eval(k >> i);
  }
  void eval(int k) {
    if (lazy[k] != n1) {
      lazy[2 * k] = h(lazy[2 * k], lazy[k]);
      lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      data[k] = ref(k);
      lazy[k] = n1;
    }
  }
  void set(int a, M x) {
    thrust(a += sz);
    data[a] = x;
    recalc(a);
  }
  void update(int a, int b, N x) {
    thrust(a += sz);
    thrust(b += sz - 1);
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        lazy[l] = h(lazy[l], x), ++l;
      if (r & 1)
        --r, lazy[r] = h(lazy[r], x);
    }
    recalc(a);
    recalc(b);
  }
  M query(int a, int b) {
    thrust(a += sz);
    thrust(b += sz - 1);
    M L = m1, R = m1;
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        L = f(L, ref(l++));
      if (r & 1)
        R = f(ref(--r), R);
    }
    return f(L, R);
  }
};

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> lb(k), rb(k);
  rep(i, 0, k) {
    cin >> lb[i] >> rb[i];
    rb[i]++;
  }
  auto f = [&](Fp a, Fp b) { return a + b; };
  auto g = [&](Fp a, Fp b) { return a + b; };
  auto h = [&](Fp a, Fp b) { return a + b; };
  LazySegmentTree<Fp, Fp> seg(n + 10, f, g, h, 0, 0);
  seg.update(0, 1, 1);
  rep(i, 0, n) {
    Fp x = seg.query(i, i + 1);
    rep(j, 0, k) { seg.update(i + lb[j], i + rb[j], x); }
  }
  Fp res = seg.query(n - 1, n);
  cout << res.v << endl;
  return 0;
}

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

// template
#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define ALL(v) (v).begin(), (v).end()
typedef long long int ll;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;
const double eps = 1e-12;
template <typename T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
// end

template <unsigned mod = 998244353> struct fp {
  int v;
  static unsigned get_mod() { return mod; }
  int inv() const {
    int tmp, a = v, b = mod, x = 1, y = 0;
    while (b)
      tmp = a / b, a -= tmp * b, swap(a, b), x -= tmp * y, swap(x, y);
    if (x < 0) {
      x += mod;
    }
    return x;
  }
  fp() : v(0) {}
  fp(ll x) : v(x >= 0 ? x % mod : mod + (x % mod)) {}
  fp operator-() const { return fp(-v); }
  fp pow(ll t) {
    fp res = 1, b = *this;
    while (t) {
      if (t & 1)
        res *= b;
      b *= b;
      t >>= 1;
    }
    return res;
  }
  fp &operator+=(const fp &x) {
    if ((v += x.v) >= (int)mod)
      v -= mod;
    return *this;
  }
  fp &operator-=(const fp &x) {
    if ((v += mod - x.v) >= (int)mod)
      v -= mod;
    return *this;
  }
  fp &operator*=(const fp &x) {
    v = ll(v) * x.v % mod;
    return *this;
  }
  fp &operator/=(const fp &x) {
    v = ll(v) * x.inv() % mod;
    return *this;
  }
  fp operator+(const fp &x) const { return fp(*this) += x; }
  fp operator-(const fp &x) const { return fp(*this) -= x; }
  fp operator*(const fp &x) const { return fp(*this) *= x; }
  fp operator/(const fp &x) const { return fp(*this) /= x; }
  bool operator==(const fp &x) const { return v == x.v; }
  bool operator!=(const fp &x) const { return v != x.v; }
};
using Fp = fp<>;

template <typename M, typename N = M> struct LazySegmentTree {
  using F = function<M(M, M)>;
  using G = function<M(M, N)>;
  using H = function<N(N, N)>;
  int sz, height;
  vector<M> data;
  vector<N> lazy;
  const F f;
  const G g;
  const H h;
  const M m1;
  const N n1;
  LazySegmentTree(int n, const F f, const G g, const H h, const M &m1,
                  const N n1)
      : f(f), g(g), h(h), m1(m1), n1(n1) {
    sz = 1, height = 0;
    while (sz < n)
      sz <<= 1, height++;
    data.assign(2 * sz, m1);
    lazy.assign(2 * sz, n1);
  }
  void build(vector<M> v) {
    rep(i, 0, v.size()) data[i + sz] = v[i];
    for (int k = sz - 1; k > 0; k--)
      data[k] = f(data[2 * k], data[2 * k + 1]);
  }
  M ref(int k) { return lazy[k] == n1 ? data[k] : g(data[k], lazy[k]); }
  void recalc(int k) {
    while (k >>= 1)
      data[k] = f(ref(2 * k), ref(2 * k + 1));
  }
  void thrust(int k) {
    for (int i = height; i > 0; i--)
      eval(k >> i);
  }
  void eval(int k) {
    if (lazy[k] != n1) {
      lazy[2 * k] = h(lazy[2 * k], lazy[k]);
      lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
      data[k] = ref(k);
      lazy[k] = n1;
    }
  }
  void set(int a, M x) {
    thrust(a += sz);
    data[a] = x;
    recalc(a);
  }
  void update(int a, int b, N x) {
    thrust(a += sz);
    thrust(b += sz - 1);
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        lazy[l] = h(lazy[l], x), ++l;
      if (r & 1)
        --r, lazy[r] = h(lazy[r], x);
    }
    recalc(a);
    recalc(b);
  }
  M query(int a, int b) {
    thrust(a += sz);
    thrust(b += sz - 1);
    M L = m1, R = m1;
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        L = f(L, ref(l++));
      if (r & 1)
        R = f(ref(--r), R);
    }
    return f(L, R);
  }
};

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> lb(k), rb(k);
  rep(i, 0, k) {
    cin >> lb[i] >> rb[i];
    rb[i]++;
  }
  auto f = [&](Fp a, Fp b) { return a + b; };
  auto g = [&](Fp a, Fp b) { return a + b; };
  auto h = [&](Fp a, Fp b) { return a + b; };
  LazySegmentTree<Fp, Fp> seg(n + 10, f, g, h, 0, 0);
  seg.update(0, 1, 1);
  rep(i, 0, n) {
    Fp x = seg.query(i, i + 1);
    rep(j, 0, k) {
      int L = min(i + lb[j], n), R = min(i + rb[j], n);
      seg.update(L, R, x);
    }
  }
  Fp res = seg.query(n - 1, n);
  cout << res.v << endl;
  return 0;
}