#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
#define repi(i, a, b) for (ll i = (a); i < (b); ++i)
#define rep(i, a) repi(i, 0, a)
#define repdi(i, a, b) for (ll i = (a)-1; i >= (b); --i)
#define repd(i, a) repdi(i, a, 0)
#define itr(it, a) for (auto it = (a).begin(); it != (a).end(); ++it)
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define endl '\\n'
#define debug(x) std::cerr << #x << " = " << (x) << endl;

using ll = long long;
using P = std::pair<ll, ll>;

using namespace std;

constexpr ll INF = 1ll << 60;

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;
}

template <class S, class T>
std::ostream &operator<<(std::ostream &out, const std::pair<S, T> &a) {
  std::cout << '(' << a.first << ", " << a.second << ')';
  return out;
}

template <class T>
std::ostream &operator<<(std::ostream &out, const std::vector<T> &a) {
  std::cout << '[';
  rep(i, a.size()) {
    std::cout << a[i];
    if (i != a.size() - 1)
      std::cout << ", ";
  }
  std::cout << ']';
  return out;
}

const ll 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 {
    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;
  }

  bool operator==(const mint a) const { return this->x == a.x; }
};

template <typename T, typename E> struct SegmentTree {
  using F = function<T(T, T)>;
  using G = function<T(T, E)>;
  using H = function<E(E, E)>;
  int n, height;
  F f;
  G g;
  H h;
  T ti;
  E ei;
  vector<T> dat;
  vector<E> laz;
  SegmentTree(F f, G g, H h, T ti, E ei) : f(f), g(g), h(h), ti(ti), ei(ei) {}

  void init(int n_) {
    n = 1;
    height = 0;
    while (n < n_)
      n <<= 1, height++;
    dat.assign(2 * n, ti);
    laz.assign(2 * n, ei);
  }

  void build(const vector<T> &v) {
    int n_ = v.size();
    init(n_);
    for (int i = 0; i < n_; i++)
      dat[n + i] = v[i];
    for (int i = n - 1; i; i--)
      dat[i] = f(dat[(i << 1) | 0], dat[(i << 1) | 1]);
  }

  inline T reflect(int k) { return laz[k] == ei ? dat[k] : g(dat[k], laz[k]); }

  inline void propagate(int k) {
    if (laz[k] == ei)
      return;
    laz[(k << 1) | 0] = h(laz[(k << 1) | 0], laz[k]);
    laz[(k << 1) | 1] = h(laz[(k << 1) | 1], laz[k]);
    dat[k] = reflect(k);
    laz[k] = ei;
  }

  inline void thrust(int k) {
    for (int i = height; i; i--)
      propagate(k >> i);
  }

  inline void recalc(int k) {
    while (k >>= 1)
      dat[k] = f(reflect((k << 1) | 0), reflect((k << 1) | 1));
  }

  void update(int a, int b, E x) {
    if (a >= b)
      return;
    thrust(a += n);
    thrust(b += n - 1);
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        laz[l] = h(laz[l], x), l++;
      if (r & 1)
        --r, laz[r] = h(laz[r], x);
    }
    recalc(a);
    recalc(b);
  }

  void set_val(int a, T x) {
    thrust(a += n);
    dat[a] = x;
    laz[a] = ei;
    recalc(a);
  }

  T query(int a, int b) {
    if (a >= b)
      return ti;
    thrust(a += n);
    thrust(b += n - 1);
    T vl = ti, vr = ti;
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        vl = f(vl, reflect(l++));
      if (r & 1)
        vr = f(reflect(--r), vr);
    }
    return f(vl, vr);
  }

  template <typename C>
  int find(int st, C &check, T &acc, int k, int l, int r) {
    if (l + 1 == r) {
      acc = f(acc, reflect(k));
      return check(acc) ? k - n : -1;
    }
    propagate(k);
    int m = (l + r) >> 1;
    if (m <= st)
      return find(st, check, acc, (k << 1) | 1, m, r);
    if (st <= l && !check(f(acc, dat[k]))) {
      acc = f(acc, dat[k]);
      return -1;
    }
    int vl = find(st, check, acc, (k << 1) | 0, l, m);
    if (~vl)
      return vl;
    return find(st, check, acc, (k << 1) | 1, m, r);
  }

  template <typename C> int find(int st, C &check) {
    T acc = ti;
    return find(st, check, acc, 1, 0, n);
  }
};

struct combination {
  std::vector<mint> fact, ifact;
  combination(int n) : fact(n + 1), ifact(n + 1) {
    assert(n < mod);
    fact[0] = 1;
    for (int i = 1; i <= n; ++i)
      fact[i] = fact[i - 1] * i;
    ifact[n] = fact[n].inv();
    for (int i = n; i >= 1; --i)
      ifact[i - 1] = ifact[i] * i;
  }
  mint operator()(int n, int k) {
    if (k < 0 || k > n)
      return 0;
    return fact[n] * ifact[k] * ifact[n - k];
  }
};

ll N, K;
ll L[200010], R[200010];
mint dp[200010], S[200010];

int main() {
  std::cin >> N >> K;

  rep(i, K) std::cin >> L[i] >> R[i], ++R[i];

  auto madd = [&](mint a, mint b) { return a + b; };

  SegmentTree<mint, mint> seg(madd, madd, madd, 0, 0);

  seg.init(N + 10);
  seg.set_val(0, 1);

  rep(i, N) {
    mint x = seg.query(i, i + 1);

    rep(j, K) { seg.update(i + L[j], i + R[j], x); }
  }

  mint ans = seg.query(N - 1, N);

  std::cout << ans.x << endl;

  return 0;
}

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <vector>
#define repi(i, a, b) for (ll i = (a); i < (b); ++i)
#define rep(i, a) repi(i, 0, a)
#define repdi(i, a, b) for (ll i = (a)-1; i >= (b); --i)
#define repd(i, a) repdi(i, a, 0)
#define itr(it, a) for (auto it = (a).begin(); it != (a).end(); ++it)
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define endl '\\n'
#define debug(x) std::cerr << #x << " = " << (x) << endl;

using ll = long long;
using P = std::pair<ll, ll>;

using namespace std;

constexpr ll INF = 1ll << 60;

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;
}

template <class S, class T>
std::ostream &operator<<(std::ostream &out, const std::pair<S, T> &a) {
  std::cout << '(' << a.first << ", " << a.second << ')';
  return out;
}

template <class T>
std::ostream &operator<<(std::ostream &out, const std::vector<T> &a) {
  std::cout << '[';
  rep(i, a.size()) {
    std::cout << a[i];
    if (i != a.size() - 1)
      std::cout << ", ";
  }
  std::cout << ']';
  return out;
}

const ll 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 {
    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;
  }

  bool operator==(const mint a) const { return this->x == a.x; }
};

template <typename T, typename E> struct SegmentTree {
  using F = function<T(T, T)>;
  using G = function<T(T, E)>;
  using H = function<E(E, E)>;
  int n, height;
  F f;
  G g;
  H h;
  T ti;
  E ei;
  vector<T> dat;
  vector<E> laz;
  SegmentTree(F f, G g, H h, T ti, E ei) : f(f), g(g), h(h), ti(ti), ei(ei) {}

  void init(int n_) {
    n = 1;
    height = 0;
    while (n < n_)
      n <<= 1, height++;
    dat.assign(2 * n, ti);
    laz.assign(2 * n, ei);
  }

  void build(const vector<T> &v) {
    int n_ = v.size();
    init(n_);
    for (int i = 0; i < n_; i++)
      dat[n + i] = v[i];
    for (int i = n - 1; i; i--)
      dat[i] = f(dat[(i << 1) | 0], dat[(i << 1) | 1]);
  }

  inline T reflect(int k) { return laz[k] == ei ? dat[k] : g(dat[k], laz[k]); }

  inline void propagate(int k) {
    if (laz[k] == ei)
      return;
    laz[(k << 1) | 0] = h(laz[(k << 1) | 0], laz[k]);
    laz[(k << 1) | 1] = h(laz[(k << 1) | 1], laz[k]);
    dat[k] = reflect(k);
    laz[k] = ei;
  }

  inline void thrust(int k) {
    for (int i = height; i; i--)
      propagate(k >> i);
  }

  inline void recalc(int k) {
    while (k >>= 1)
      dat[k] = f(reflect((k << 1) | 0), reflect((k << 1) | 1));
  }

  void update(int a, int b, E x) {
    if (a >= b)
      return;
    thrust(a += n);
    thrust(b += n - 1);
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        laz[l] = h(laz[l], x), l++;
      if (r & 1)
        --r, laz[r] = h(laz[r], x);
    }
    recalc(a);
    recalc(b);
  }

  void set_val(int a, T x) {
    thrust(a += n);
    dat[a] = x;
    laz[a] = ei;
    recalc(a);
  }

  T query(int a, int b) {
    if (a >= b)
      return ti;
    thrust(a += n);
    thrust(b += n - 1);
    T vl = ti, vr = ti;
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        vl = f(vl, reflect(l++));
      if (r & 1)
        vr = f(reflect(--r), vr);
    }
    return f(vl, vr);
  }

  template <typename C>
  int find(int st, C &check, T &acc, int k, int l, int r) {
    if (l + 1 == r) {
      acc = f(acc, reflect(k));
      return check(acc) ? k - n : -1;
    }
    propagate(k);
    int m = (l + r) >> 1;
    if (m <= st)
      return find(st, check, acc, (k << 1) | 1, m, r);
    if (st <= l && !check(f(acc, dat[k]))) {
      acc = f(acc, dat[k]);
      return -1;
    }
    int vl = find(st, check, acc, (k << 1) | 0, l, m);
    if (~vl)
      return vl;
    return find(st, check, acc, (k << 1) | 1, m, r);
  }

  template <typename C> int find(int st, C &check) {
    T acc = ti;
    return find(st, check, acc, 1, 0, n);
  }
};

struct combination {
  std::vector<mint> fact, ifact;
  combination(int n) : fact(n + 1), ifact(n + 1) {
    assert(n < mod);
    fact[0] = 1;
    for (int i = 1; i <= n; ++i)
      fact[i] = fact[i - 1] * i;
    ifact[n] = fact[n].inv();
    for (int i = n; i >= 1; --i)
      ifact[i - 1] = ifact[i] * i;
  }
  mint operator()(int n, int k) {
    if (k < 0 || k > n)
      return 0;
    return fact[n] * ifact[k] * ifact[n - k];
  }
};

ll N, K;
ll L[200010], R[200010];
mint dp[200010], S[200010];

int main() {
  std::cin >> N >> K;

  rep(i, K) std::cin >> L[i] >> R[i], ++R[i];

  auto madd = [&](mint a, mint b) { return a + b; };

  SegmentTree<mint, mint> seg(madd, madd, madd, 0, 0);

  seg.init(N + 10);
  seg.set_val(0, 1);

  rep(i, N - 1) {
    mint x = seg.query(i, i + 1);

    rep(j, K) {
      if (i + L[j] >= N)
        continue;

      seg.update(i + L[j], std::min(N, i + R[j]), x);
    }
  }

  mint ans = seg.query(N - 1, N);

  std::cout << ans.x << endl;

  return 0;
}


#include <bits/stdc++.h>
#define LOCAL
using namespace std;
template <typename A, typename B>
ostream &operator<<(ostream &out, const pair<A, B> &a) {
  out << "(" << a.first << "," << a.second << ")";
  return out;
}
template <typename T, size_t N>
ostream &operator<<(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> ostream &operator<<(ostream &out, const vector<T> &a) {
  out << "[";
  bool first = true;
  for (auto &v : a) {
    out << (first ? "" : ", ");
    out << v;
    first = 0;
  }
  out << "]";
  return out;
}
template <typename T, class Cmp>
ostream &operator<<(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>
ostream &operator<<(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;
}
#ifdef LOCAL
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
#else
#define trace(...) 42
#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.write(names, comma - names) << ": " << arg1 << " |";
  __f(comma + 1, args...);
}
#define rep(i, n) for (int i = 0; i < (n); i++)
using ll = long long;
#define int long long
using P = pair<int, int>;
// #########################################

const int mod = 998244353;
void add(int &a, int b) {
  a = (a + b) % mod;
  a = (a % mod + mod) % mod;
}
signed main() {
  int n, k;
  cin >> n >> k;
  vector<int> l(k), r(k);
  rep(i, k) cin >> l[i] >> r[i];
  vector<int> dp(n + 3);
  dp[1] = 1;
  add(dp[2], -1);
  int sum = 0;
  for (int i = 1; i <= n; i++) {
    add(sum, dp[i]);
    rep(j, k) {
      add(dp[r[j] + 1 + i], -sum);
      add(dp[l[j] + i], sum);
    }
    // trace(i,sum,dp);
  }
  for (int i = 1; i <= n; i++)
    add(dp[i + 1], dp[i]);

  cout << dp[n] << endl;
  return 0;
}

#include <bits/stdc++.h>
#define LOCAL
using namespace std;
template <typename A, typename B>
ostream &operator<<(ostream &out, const pair<A, B> &a) {
  out << "(" << a.first << "," << a.second << ")";
  return out;
}
template <typename T, size_t N>
ostream &operator<<(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> ostream &operator<<(ostream &out, const vector<T> &a) {
  out << "[";
  bool first = true;
  for (auto &v : a) {
    out << (first ? "" : ", ");
    out << v;
    first = 0;
  }
  out << "]";
  return out;
}
template <typename T, class Cmp>
ostream &operator<<(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>
ostream &operator<<(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;
}
#ifdef LOCAL
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
#else
#define trace(...) 42
#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.write(names, comma - names) << ": " << arg1 << " |";
  __f(comma + 1, args...);
}
#define rep(i, n) for (int i = 0; i < (n); i++)
using ll = long long;
#define int long long
using P = pair<int, int>;
// #########################################

const int mod = 998244353;
void add(int &a, int b) {
  a = (a + b) % mod;
  a = (a % mod + mod) % mod;
}
signed main() {
  int n, k;
  cin >> n >> k;
  vector<int> l(k), r(k);
  rep(i, k) cin >> l[i] >> r[i];
  vector<int> dp(n + 3);
  dp[1] = 1;
  add(dp[2], -1);
  int sum = 0;
  for (int i = 1; i <= n; i++) {
    add(sum, dp[i]);
    rep(j, k) {
      if (r[j] + 1 + i < n + 3)
        add(dp[r[j] + 1 + i], -sum);
      if (l[j] + i < n + 3)
        add(dp[l[j] + i], sum);
    }
    // trace(i,sum,dp);
  }
  for (int i = 1; i <= n; i++)
    add(dp[i + 1], dp[i]);

  cout << dp[n] << endl;
  return 0;
}


#ifndef DEBUG
#pragma GCC optimize("O3,no-stack-protector")
#pragma GCC optimize("unroll-loops")

#if __cplusplus < 201703L
#pragma GCC target("avx")
#else
#pragma GCC target("avx2")
#endif

#endif

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
#define dump(x) cout << x << endl
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define REP(i, n) for (int i = 0, i##_len = (n); i <= i##_len; ++i)
#define rep3(i, l, r) for (int i = l, i##_len = (r); i < i##_len; ++i)
#define REP3(i, l, r) for (int i = l, i##_len = (r); i <= i##_len; ++i)
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
typedef int64_t Int;
typedef long double Ld;

using namespace std;
template <class T> using Graph = vector<vector<T>>;

const Ld pi = M_PI;
const Int MOD = 998244353;
const Int INF = 1LL << 62;

Int Floor(Int a, Int b) { return (a - (a % b)) / b; }

template <class T> inline bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <class T> inline bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T> inline T Gcd(T a, T b) {
  T c;
  while (b) {
    c = b;
    b = a % b;
    a = c;
  }
  return a;
}

Int Lcm(Int a, Int b) {
  if (a < b) {
    swap(a, b);
  }

  return a / Gcd(a, b) * b;
}

vector<Int> divisor(Int n) {
  vector<Int> ret;
  for (Int i = 1; i * i <= n; i++) {
    if (n % i == 0) {
      ret.push_back(i);
      if (i * i != n)
        ret.push_back(n / i);
    }
  }

  return ret;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  Int n, k;
  cin >> n >> k;
  vector<Int> ans(n + n + 5, 0), s;
  ans[0] = 1;
  for (Int i = 0; i < k; i++) {
    Int l, r;
    cin >> l >> r;

    for (Int j = l; j <= r; j++) {
      s.push_back(j);
    }
  }
  sort(all(s));

  for (Int i = 1; i <= n; i++) {
    for (auto e : s) {
      if (0 <= i - e) {
        ans[i] += ans[i - e];
        ans[i] %= MOD;
      } else {
        break;
      }
    }
  }

  cout << ans[n - 1] << endl;

  return 0;
}

#ifndef DEBUG
#pragma GCC optimize("O3,no-stack-protector")
#pragma GCC optimize("unroll-loops")

#if __cplusplus < 201703L
#pragma GCC target("avx")
#else
#pragma GCC target("avx2")
#endif

#endif

#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
#define dump(x) cout << x << endl
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define REP(i, n) for (int i = 0, i##_len = (n); i <= i##_len; ++i)
#define rep3(i, l, r) for (int i = l, i##_len = (r); i < i##_len; ++i)
#define REP3(i, l, r) for (int i = l, i##_len = (r); i <= i##_len; ++i)
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
typedef int64_t Int;
typedef long double Ld;

using namespace std;
template <class T> using Graph = vector<vector<T>>;

const Ld pi = M_PI;
const Int MOD = 998244353;
const Int INF = 1LL << 62;

Int Floor(Int a, Int b) { return (a - (a % b)) / b; }

template <class T> inline bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <class T> inline bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T> inline T Gcd(T a, T b) {
  T c;
  while (b) {
    c = b;
    b = a % b;
    a = c;
  }
  return a;
}

Int Lcm(Int a, Int b) {
  if (a < b) {
    swap(a, b);
  }

  return a / Gcd(a, b) * b;
}

vector<Int> divisor(Int n) {
  vector<Int> ret;
  for (Int i = 1; i * i <= n; i++) {
    if (n % i == 0) {
      ret.push_back(i);
      if (i * i != n)
        ret.push_back(n / i);
    }
  }

  return ret;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  Int n, k;
  cin >> n >> k;
  vector<Int> ans(n + n + 5, 0);
  vector<pair<Int, Int>> s;
  for (Int i = 0; i < k; i++) {
    Int l, r;
    cin >> l >> r;
    s.push_back({l, r});
  }

  ans[1] = 1;
  ans[2] = -1;

  for (Int i = 1; i <= n; i++) {
    ans[i] += ans[i - 1];
    ans[i] %= MOD;

    for (auto [l, r] : s) {
      ans[i + l] += ans[i] + MOD;
      ans[i + l] %= MOD;
      ans[i + r + 1] -= (ans[i] - MOD);
      ans[i + r + 1] %= MOD;
    }
  }

  cout << ans[n] << endl;

  return 0;
}


// include
//------------------------------------------
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <locale>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

// typedef
//------------------------------------------
typedef long long LL;
typedef vector<int> VI;
typedef vector<bool> VB;
typedef vector<char> VC;
typedef vector<double> VD;
typedef vector<string> VS;
typedef vector<LL> VLL;
typedef vector<VI> VVI;
typedef vector<VB> VVB;
typedef vector<VS> VVS;
typedef vector<VLL> VVLL;
typedef vector<VVI> VVVI;
typedef vector<VVLL> VVVLL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<int, string> PIS;
typedef pair<string, int> PSI;
typedef pair<string, string> PSS;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<VPII> VVPII;
typedef vector<VPLL> VVPLL;
typedef vector<VS> VVS;
typedef map<int, int> MII;
typedef map<LL, LL> MLL;
typedef map<string, int> MSI;
typedef map<int, string> MIS;

// container util
//------------------------------------------

typedef int pInt[4];
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define EACH(i, arr)                                                           \\
  for (typeof((arr).begin()) i = (arr).begin(); i != (arr).end(); ++i)
#define EXIST(str, e) ((str).find(e) != (str).end())
#define COUNT(arr, v) count((arr).begin(), (arr).end(), v)
#define SEARCH(v, w) search((v).begin(), (v).end(), (w).begin(), (w).end())
#define SORT(c) sort((c).begin(), (c).end())
#define RSORT(c) sort((c).rbegin(), (c).rend())
#define REVERSE(c) reverse((c).begin(), (c).end())
#define ROTATE_LEFT(arr, c)                                                    \\
  rotate((arr).begin(), (arr).begin() + (c), (arr).end())
#define ROTATE_RIGHT(arr, c)                                                   \\
  rotate((arr).rbegin(), (arr).rbegin() + (c), (arr).rend())
#define SUMI(arr) accumulate((arr).begin(), (arr).end(), 0)
#define SUMD(arr) accumulate((arr).begin(), (arr).end(), 0.)
#define SUMLL(arr) accumulate((arr).begin(), (arr).end(), 0LL)
#define MULD(arr)                                                              \\
  accumulate((arr).begin(), (arr).end(), 1., multiplies<double>())
#define UB(arr, n) upper_bound((arr).begin(), (arr).end(), n)
#define LB(arr, n) lower_bound((arr).begin(), (arr).end(), n)
#define PB push_back
#define MP make_pair
#define ft first
#define sd second

// input output
//------------------------------------------
#define GL(s) getline(cin, (s))
#define INIT()                                                                 \\
  std::ios::sync_with_stdio(false);                                            \\
  std::cin.tie(0)
#define OUT(d) std::cout << (d)
#define OUT_L(d) std::cout << (d) << endl
#define FOUT(n, data) std::cout << std::fixed << std::setprecision(n) << (data)
#define FOUT_L(n, data)                                                        \\
  std::cout << std::fixed << std::setprecision(n) << (data) << "\\n"
#define EL() printf("\\n")
#define SHOW_VECTOR(v)                                                         \\
  {                                                                            \\
    std::cerr << #v << "\\t:";                                                  \\
    for (const auto &xxx : v) {                                                \\
      std::cerr << xxx << " ";                                                 \\
    }                                                                          \\
    std::cerr << "\\n";                                                         \\
  }
#define SHOW_MAP(v)                                                            \\
  {                                                                            \\
    std::cerr << #v << endl;                                                   \\
    for (const auto &xxx : v) {                                                \\
      std::cerr << xxx.first << " " << xxx.second << "\\n";                     \\
    }                                                                          \\
  }
#define Yes() printf("Yes\\n")
#define No() printf("No\\n")
#define YES() printf("YES\\n")
#define NO() printf("NO\\n")
#define Yay() printf("Yay!\\n")
#define Nnn() printf(":(\\n")
#define CE(x, y) ((x + y - 1) / (y))

template <typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &p) {
  in >> p.first >> p.second;
  return in;
}

template <typename T> istream &operator>>(istream &in, vector<T> &v) {
  for (auto &x : v)
    in >> x;
  return in;
}

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
  out << "[" << p.first << ", " << p.second << "]"
      << "\\n";
  return out;
}

template <class T1, class T2> inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <class T1, class T2> inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

// repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define RFOR(i, a, b) for (int i = (b)-1; i >= (a); --i)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) for (int i = n - 1; i >= 0; i--)
#define FORLL(i, a, b) for (LL i = LL(a); i < LL(b); ++i)
#define RFORLL(i, a, b) for (LL i = LL(b) - 1; i >= LL(a); --i)
#define REPLL(i, n) for (LL i = 0; i < LL(n); ++i)
#define RREPLL(i, n) for (LL i = LL(n) - 1; i >= 0; --i)
#define FOREACH(x, arr) for (auto &(x) : (arr))

// Option + Control + K  Terminal
// Command + Control + K    Run
// Command + b   EOF
// #include "atcoder/all"

//------------------------------------------
//------------------------------------------

template <int_fast64_t Modulas = 1000000007ul> class ModInt {
  using u64 = int_fast64_t;

public:
  u64 x;

  constexpr ModInt() : x(0) {}
  constexpr ModInt(int_fast64_t v) : x((v % Modulas + Modulas) % Modulas) {}
  constexpr ModInt operator+(const ModInt rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  constexpr ModInt operator-(const ModInt rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  constexpr ModInt operator*(const ModInt rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  constexpr ModInt operator/(const ModInt rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }
  constexpr ModInt operator/(const long long rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }
  constexpr ModInt operator+=(const ModInt rhs) noexcept {
    x += rhs.x;
    if (x >= Modulas)
      x -= Modulas;
    return *this;
  }
  constexpr ModInt operator+=(const long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) += hs;
    return *this;
  }
  constexpr ModInt operator-=(const ModInt rhs) noexcept {
    if (x < rhs.x)
      x += Modulas;
    x -= rhs.x;
    return *this;
  }
  constexpr ModInt operator-=(const long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) -= hs;
    return *this;
  }
  constexpr ModInt operator*=(const ModInt rhs) noexcept {
    x = x * rhs.x % Modulas;
    return *this;
  }
  constexpr ModInt operator*=(const long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) *= hs;
    return *this;
  }
  constexpr ModInt &operator/=(ModInt rhs) noexcept {
    u64 exp = Modulas - 2;
    while (exp > 0) {
      if (exp & 1ul)
        *this *= rhs;
      rhs *= rhs;
      exp >>= 1ul;
    }
    return *this;
  }
  constexpr ModInt &operator/=(long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) /= hs;
    return *this;
  }

  constexpr ModInt &operator++() noexcept {
    x++;
    if (x >= Modulas)
      x -= Modulas;
    return *this;
  }
  constexpr ModInt &operator--() noexcept {
    if (x == 0)
      x += Modulas;
    x--;
    return *this;
  }
  constexpr bool operator<(const ModInt rhs) const noexcept {
    return x < rhs.x;
  }
  constexpr bool operator==(const ModInt rhs) const noexcept {
    return this->x == rhs.x;
  }
  constexpr bool operator!=(const ModInt rhs) const noexcept {
    return !(*this == rhs);
  }
  friend istream &operator>>(istream &in, ModInt &m) {
    in >> m.x;
    if (m.x < 0)
      m.x += Modulas;
    m.x %= Modulas;
    return in;
  }
  friend ostream &operator<<(ostream &out, const ModInt &p) {
    out << p.x;
    return out;
  }
  constexpr ModInt pow(u64 p) const {
    ModInt ret(1);
    ModInt mul(x);
    while (p > 0) {
      if (p & 1ul)
        ret *= mul;
      mul *= mul;
      p >>= 1ul;
    }
    return ret;
  }
  constexpr ModInt operator~() const noexcept {
    u64 exp = Modulas - 2;
    return pow(exp);
  }

  constexpr static ModInt arith_sum(ModInt<Modulas> a, ModInt<Modulas> d,
                                    ModInt<Modulas> n) noexcept {
    return (a * ModInt<Modulas>(2) + (n - 1) * d) * n / ModInt<Modulas>(2);
  }
};

constexpr LL mod = 998244353;

template <typename T> struct LazySegmentTree {

private:
  int n;
  T init_v;
  vector<T> node;
  vector<T> lazy;

public:
  LazySegmentTree(vector<T> a, T _init_v) {

    n = 1;
    init_v = _init_v;

    int sz = a.size();
    while (n < sz)
      n *= 2;

    node.resize(2 * n, init_v);
    lazy.resize(2 * n, init_v);

    for (int i = 0; i < sz; i++)
      node[i + n - 1] = a[i];
    for (int i = n - 2; i >= 0; i--)
      node[i] = node[i * 2 + 1] + node[i * 2 + 2];
  }

  void eval(int k, int l, int r) {
    if (lazy[k] != 0) {
      node[k] += lazy[k];
      if (r - l > 1) {
        lazy[k * 2 + 1] += lazy[k] / 2;
        lazy[k * 2 + 2] += lazy[k] / 2;
      }
      lazy[k] = 0;
    }
  }

  void add(int a, int b, T x, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    eval(k, l, r);
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      ModInt<mod> w = (r - l);
      lazy[k] += w * x;
      eval(k, l, r);
    } else {
      add(a, b, x, k * 2 + 1, l, (l + r) / 2);
      add(a, b, x, k * 2 + 2, (l + r) / 2, r);
      node[k] = node[k * 2 + 1] + node[k * 2 + 2];
    }
  }

  T getsum(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    eval(k, l, r);
    if (r <= a || b <= l)
      return 0;
    if (a <= l && r <= b)
      return node[k];
    T lv = getsum(a, b, k * 2 + 1, l, (l + r) / 2);
    T rv = getsum(a, b, k * 2 + 2, (l + r) / 2, r);
    return lv + rv;
  }
};

int main() {

  LL N, K;
  scanf("%lld %lld", &N, &K);

  VLL L(K), R(K);
  REP(i, K) scanf("%lld %lld", &L[i], &R[i]), R[i]++;

  LazySegmentTree<ModInt<mod>> tree(vector<ModInt<mod>>(N), 0);

  tree.add(0, 1, 1);

  for (int i = 0; i < N - 1; i++) {
    auto now = tree.getsum(i, i + 1);
    for (int k = 0; k < K; k++) {
      LL l = i + L[k];
      if (l >= N)
        continue;
      LL r = min(i + R[k], N);
      tree.add(l, r, now);
    }
  }

  printf("%lld", tree.getsum(N - 1, N));

  //    cout << tree.getsum(N - 1, N) << endl;

  return 0;
}

// include
//------------------------------------------
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <locale>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

// typedef
//------------------------------------------
typedef long long LL;
typedef vector<int> VI;
typedef vector<bool> VB;
typedef vector<char> VC;
typedef vector<double> VD;
typedef vector<string> VS;
typedef vector<LL> VLL;
typedef vector<VI> VVI;
typedef vector<VB> VVB;
typedef vector<VS> VVS;
typedef vector<VLL> VVLL;
typedef vector<VVI> VVVI;
typedef vector<VVLL> VVVLL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<int, string> PIS;
typedef pair<string, int> PSI;
typedef pair<string, string> PSS;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<VPII> VVPII;
typedef vector<VPLL> VVPLL;
typedef vector<VS> VVS;
typedef map<int, int> MII;
typedef map<LL, LL> MLL;
typedef map<string, int> MSI;
typedef map<int, string> MIS;

// container util
//------------------------------------------

typedef int pInt[4];
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) int((a).size())
#define EACH(i, arr)                                                           \\
  for (typeof((arr).begin()) i = (arr).begin(); i != (arr).end(); ++i)
#define EXIST(str, e) ((str).find(e) != (str).end())
#define COUNT(arr, v) count((arr).begin(), (arr).end(), v)
#define SEARCH(v, w) search((v).begin(), (v).end(), (w).begin(), (w).end())
#define SORT(c) sort((c).begin(), (c).end())
#define RSORT(c) sort((c).rbegin(), (c).rend())
#define REVERSE(c) reverse((c).begin(), (c).end())
#define ROTATE_LEFT(arr, c)                                                    \\
  rotate((arr).begin(), (arr).begin() + (c), (arr).end())
#define ROTATE_RIGHT(arr, c)                                                   \\
  rotate((arr).rbegin(), (arr).rbegin() + (c), (arr).rend())
#define SUMI(arr) accumulate((arr).begin(), (arr).end(), 0)
#define SUMD(arr) accumulate((arr).begin(), (arr).end(), 0.)
#define SUMLL(arr) accumulate((arr).begin(), (arr).end(), 0LL)
#define MULD(arr)                                                              \\
  accumulate((arr).begin(), (arr).end(), 1., multiplies<double>())
#define UB(arr, n) upper_bound((arr).begin(), (arr).end(), n)
#define LB(arr, n) lower_bound((arr).begin(), (arr).end(), n)
#define PB push_back
#define MP make_pair
#define ft first
#define sd second

// input output
//------------------------------------------
#define GL(s) getline(cin, (s))
#define INIT()                                                                 \\
  std::ios::sync_with_stdio(false);                                            \\
  std::cin.tie(0)
#define OUT(d) std::cout << (d)
#define OUT_L(d) std::cout << (d) << endl
#define FOUT(n, data) std::cout << std::fixed << std::setprecision(n) << (data)
#define FOUT_L(n, data)                                                        \\
  std::cout << std::fixed << std::setprecision(n) << (data) << "\\n"
#define EL() printf("\\n")
#define SHOW_VECTOR(v)                                                         \\
  {                                                                            \\
    std::cerr << #v << "\\t:";                                                  \\
    for (const auto &xxx : v) {                                                \\
      std::cerr << xxx << " ";                                                 \\
    }                                                                          \\
    std::cerr << "\\n";                                                         \\
  }
#define SHOW_MAP(v)                                                            \\
  {                                                                            \\
    std::cerr << #v << endl;                                                   \\
    for (const auto &xxx : v) {                                                \\
      std::cerr << xxx.first << " " << xxx.second << "\\n";                     \\
    }                                                                          \\
  }
#define Yes() printf("Yes\\n")
#define No() printf("No\\n")
#define YES() printf("YES\\n")
#define NO() printf("NO\\n")
#define Yay() printf("Yay!\\n")
#define Nnn() printf(":(\\n")
#define CE(x, y) ((x + y - 1) / (y))

template <typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &p) {
  in >> p.first >> p.second;
  return in;
}

template <typename T> istream &operator>>(istream &in, vector<T> &v) {
  for (auto &x : v)
    in >> x;
  return in;
}

template <typename T1, typename T2>
ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
  out << "[" << p.first << ", " << p.second << "]"
      << "\\n";
  return out;
}

template <class T1, class T2> inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <class T1, class T2> inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

// repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define RFOR(i, a, b) for (int i = (b)-1; i >= (a); --i)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) for (int i = n - 1; i >= 0; i--)
#define FORLL(i, a, b) for (LL i = LL(a); i < LL(b); ++i)
#define RFORLL(i, a, b) for (LL i = LL(b) - 1; i >= LL(a); --i)
#define REPLL(i, n) for (LL i = 0; i < LL(n); ++i)
#define RREPLL(i, n) for (LL i = LL(n) - 1; i >= 0; --i)
#define FOREACH(x, arr) for (auto &(x) : (arr))

// Option + Control + K  Terminal
// Command + Control + K    Run
// Command + b   EOF
// #include "atcoder/all"

//------------------------------------------
//------------------------------------------

constexpr LL mod = 998244353;

template <int_fast64_t Modulas = 1000000007ul> class ModInt {
  using u64 = int_fast64_t;

public:
  u64 x;

  constexpr ModInt() : x(0) {}
  constexpr ModInt(int_fast64_t v) : x((v % Modulas + Modulas) % Modulas) {}
  constexpr ModInt operator+(const ModInt rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  constexpr ModInt operator-(const ModInt rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  constexpr ModInt operator*(const ModInt rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  constexpr ModInt operator/(const ModInt rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }
  constexpr ModInt operator/(const long long rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }
  constexpr ModInt operator+=(const ModInt rhs) noexcept {
    x += rhs.x;
    if (x >= Modulas)
      x -= Modulas;
    return *this;
  }
  constexpr ModInt operator+=(const long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) += hs;
    return *this;
  }
  constexpr ModInt operator-=(const ModInt rhs) noexcept {
    if (x < rhs.x)
      x += Modulas;
    x -= rhs.x;
    return *this;
  }
  constexpr ModInt operator-=(const long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) -= hs;
    return *this;
  }
  constexpr ModInt operator*=(const ModInt rhs) noexcept {
    x = x * rhs.x % Modulas;
    return *this;
  }
  constexpr ModInt operator*=(const long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) *= hs;
    return *this;
  }
  constexpr ModInt &operator/=(ModInt rhs) noexcept {
    u64 exp = Modulas - 2;
    while (exp > 0) {
      if (exp & 1ul)
        *this *= rhs;
      rhs *= rhs;
      exp >>= 1ul;
    }
    return *this;
  }
  constexpr ModInt &operator/=(long long rhs) noexcept {
    auto hs = ModInt<Modulas>(rhs);
    (*this) /= hs;
    return *this;
  }

  constexpr ModInt &operator++() noexcept {
    x++;
    if (x >= Modulas)
      x -= Modulas;
    return *this;
  }
  constexpr ModInt &operator--() noexcept {
    if (x == 0)
      x += Modulas;
    x--;
    return *this;
  }
  constexpr bool operator<(const ModInt rhs) const noexcept {
    return x < rhs.x;
  }
  constexpr bool operator==(const ModInt rhs) const noexcept {
    return this->x == rhs.x;
  }
  constexpr bool operator!=(const ModInt rhs) const noexcept {
    return !(*this == rhs);
  }
  friend istream &operator>>(istream &in, ModInt &m) {
    in >> m.x;
    if (m.x < 0)
      m.x += Modulas;
    m.x %= Modulas;
    return in;
  }
  friend ostream &operator<<(ostream &out, const ModInt &p) {
    out << p.x;
    return out;
  }
  constexpr ModInt pow(u64 p) const {
    ModInt ret(1);
    ModInt mul(x);
    while (p > 0) {
      if (p & 1ul)
        ret *= mul;
      mul *= mul;
      p >>= 1ul;
    }
    return ret;
  }
  constexpr ModInt operator~() const noexcept {
    u64 exp = Modulas - 2;
    return pow(exp);
  }

  constexpr static ModInt arith_sum(ModInt<Modulas> a, ModInt<Modulas> d,
                                    ModInt<Modulas> n) noexcept {
    return (a * ModInt<Modulas>(2) + (n - 1) * d) * n / ModInt<Modulas>(2);
  }
};

int main() {

  typedef ModInt<mod> MI;

  LL N, K;
  cin >> N >> K;

  VLL L(K), R(K);
  REP(i, K) cin >> L[i] >> R[i];

  vector<MI> dp(N, 0);
  vector<MI> sum(N, 0);
  dp[0] = 1;
  sum[0] = 1;

  for (int i = 1; i < N; i++) {
    REP(k, K) {
      // [l[i], r[i]]
      int l = i - R[k];
      int r = i - L[k];
      if (r < 0)
        continue;
      l = max(l, 0);
      r = max(r, 0);
      dp[i] += (sum[r] - ((l - 1 == -1) ? 0 : sum[l - 1]));
    }
    sum[i] += dp[i] + sum[i - 1];
  }

  cout << dp.back() << endl;

  return 0;
}


#include <iostream>
#include <vector>
using namespace std;
using ll = long long;
vector<pair<int, int>> D;

int main() {
  int N, K, i, j, k;
  ll mod = 998244353;
  cin >> N >> K;
  D = vector<pair<int, int>>(K);
  int l, r;
  for (i = 0; i < K; i++) {
    cin >> l >> r;
    D[i] = make_pair(l, r);
  }

  vector<ll> dp(N, 0);
  dp[0] = 1;
  for (i = 1; i < N; i++) {
    for (j = 0; j < D.size(); j++) {
      for (k = D[j].first; k <= D[j].second && k <= i; k++) {
        dp[i] += dp[i - k];
        dp[i] %= mod;
      }
    }
  }

  cout << dp[N - 1] << endl;
  return 0;
}

#include <iostream>
#include <vector>
using namespace std;
using ll = long long;

int main() {
  int N, K, i, j, MOD = 998244353;
  cin >> N >> K;
  vector<int> L(K), R(K);
  for (i = 0; i < K; i++) {
    cin >> L[i] >> R[i];
  }
  vector<ll> dp(N + 1, 0), dps(N + 1, 0);
  dp[0] = 0;
  dp[1] = 1;
  dps[0] = 0;
  dps[1] = 1;
  for (i = 2; i <= N; i++) {
    for (j = 0; j < K; j++) {
      int r = i - L[j];
      int l = max(i - R[j], 1);
      if (0 < r) {
        dp[i] += (dps[r] - dps[l - 1] + MOD) % MOD;
        dp[i] %= MOD;
      }
    }
    dps[i] = (dps[i - 1] + dp[i]) % MOD;
  }
  cout << dp[N] << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n, k;
pair<int, int> g[11];
inline int read() {
  register int x = 0;
  register char ch = getchar();
  while (ch < '0' || ch > '9') {
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + (ch ^ 48);
    ch = getchar();
  }
  return x;
}
int dp[400001];
int main() {
  n = read();
  k = read();
  register int i, j, p;
  for (i = 1; i <= k; ++i) {
    g[i].first = read();
    g[i].second = read();
  }
  dp[1] = 1;
  sort(g + 1, g + k + 1);
  for (i = 1; i <= n; ++i) {
    // cout<<"s:";
    for (j = 1; j <= k && i + g[j].first <= n; ++j) {
      for (p = g[j].first; p <= g[j].second && i + p <= n; p++) {
        dp[i + p] = (dp[i + p] + dp[i]) % 998244353;
        // cout<<p<<":"<<i+p<<" ";
      }
    }
    // cout<<endl;
    // cout<<dp[i]<<endl;
  }
  cout << dp[n];
}

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, k;
pair<int, int> g[11];
inline int read() {
  register int x = 0;
  register char ch = getchar();
  while (ch < '0' || ch > '9') {
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + (ch ^ 48);
    ch = getchar();
  }
  return x;
}
int c[200001];
int mod = 998244353;
inline int lowbit(int x) { return x & -x; }
inline void add(int p, int x) {
  while (p <= n) {
    c[p] = (c[p] + x) % mod;
    p += lowbit(p);
  }
}
inline int sum(int k) {
  int ans = 0;
  while (k) {
    ans = (ans + c[k]) % mod;
    k -= lowbit(k);
  };
  return ans;
}
inline int ask(int l, int r) { return (sum(r) - sum(l - 1) + mod) % mod; }
signed main() {
  n = read();
  k = read();
  register int i, j, p;
  for (i = 1; i <= k; ++i) {
    g[i].first = read();
    g[i].second = read();
  }
  add(1, 1);
  sort(g + 1, g + k + 1);
  for (i = 1; i <= n; ++i) {
    // cout<<"s:";
    for (j = 1; j <= k && ((i - g[j].first) > 0); ++j) {
      // cout<<i<<" "<<j<<" "<<max(1ll,i-g[j].second)<<" "<<i-g[j].first<<"
      // "<<ask(max(1ll,i-g[j].second),i-g[j].first)<<endl;
      add(i, ask(max(1ll, i - g[j].second), i - g[j].first));
    }
    // cout<<endl;
    // cout<<dp[i]<<endl;
  }
  cout << ask(n, n);
}


#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repi(i, a, b) for (int i = int(a); i < int(b); ++i)
#define all(x) (x).begin(), (x).end()
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> P;

ll MOD = 998244353;
ll dp[1000005];

int main() {

  int n, k;
  cin >> n >> k;
  vector<int> l(k);
  vector<int> r(k);
  rep(i, k) cin >> l[i] >> r[i];
  vector<int> S;
  rep(i, k) { repi(j, l[i], r[i] + 1) S.push_back(j); }
  sort(all(S));

  dp[0] = 1;
  rep(i, n) {
    rep(j, S.size()) {
      if ((i - S[j]) >= 0) {
        dp[i] += dp[i - S[j]];
        dp[i] = dp[i] % MOD;
      } else
        break;
    }
  }
  dp[n - 1] = dp[n - 1] % MOD;

  cout << dp[n - 1] << endl;

  return 0;
}

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repi(i, a, b) for (int i = int(a); i < int(b); ++i)
#define all(x) (x).begin(), (x).end()
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> P;

ll MOD = 998244353;
ll dp[1000005];

int main() {

  int n, k;
  cin >> n >> k;
  vector<int> l(k);
  vector<int> r(k);
  rep(i, k) cin >> l[i] >> r[i];
  vector<ll> wa(n + 1);

  dp[0] = 1;
  wa[0] = 0;
  rep(i, n) {
    rep(j, k) {
      if (i - r[j] >= 0) {
        dp[i] += (wa[i - l[j] + 1] - wa[i - r[j]]) % MOD;
      } else if (i - l[j] >= 0) {
        dp[i] += (wa[i - l[j] + 1] - wa[0]) % MOD;
      }
    }
    wa[i + 1] += (wa[i] + dp[i]) % MOD;
  }
  dp[n - 1] = dp[n - 1] % MOD;
  if (dp[n - 1] < 0)
    dp[n - 1] += MOD;

  cout << dp[n - 1] << endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
long long n, k, l, r, m = 998244353, dp[200005], sum[200005];
vector<int> v;
int main() {
  cin >> n >> k;
  for (int i = 1; i <= k; i++) {
    cin >> l >> r;
    sum[l]++;
    sum[r + 1]--;
  }
  for (int i = 1; i <= n; i++)
    sum[i] += sum[i - 1];
  for (int i = 1; i <= n; i++) {
    if (sum[i])
      v.push_back(i);
  }
  dp[1] = 1LL;
  for (int i = 2; i <= n; i++) {
    for (auto j : v) {
      if (j >= i)
        break;
      dp[i] += dp[i - j];
      dp[i] %= m;
    }
  }
  cout << dp[n];
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

#define rep(i, n) for (int i = 0; i < (n); i++)

// 自動でmodを取ってくれる整数型
// 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 { // ans=mint(a).pow(b); // a^b
    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, const mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }

mint f(int n) { // 2のn乗
  if (n == 0)
    return 1;
  mint x = f(n / 2);
  x *= x;
  if (n % 2 == 1)
    x *= 2;
  return x;
}

// a^n mod を計算する
long long modpow(long long a, long long n) {
  long long res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}

//////////////////////////
int main() {
  int N, K;
  cin >> N >> K;
  vector<int> L(K), R(K);
  rep(i, K) {
    cin >> L[i] >> R[i];
    //        for(int j=L[i];j<=R[i];j++) a.push_back(j);
  }
  //    sort(a.begin(),a.end());
  //    int n=a.size();
  vector<mint> dp(N);
  dp[0] = 1;
  for (int i = 1; i < N; i++) {
    rep(j, K) {
      for (int k = L[j]; k <= R[j]; k++) {
        if (i - k >= 0)
          dp[i] += dp[i - k];
        else
          break;
      }
    }
  }
  cout << dp[N - 1] << endl;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

#define rep(i, n) for (int i = 0; i < (n); i++)

// 自動でmodを取ってくれる整数型
// 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 { // ans=mint(a).pow(b); // a^b
    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, const mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }

mint f(int n) { // 2のn乗
  if (n == 0)
    return 1;
  mint x = f(n / 2);
  x *= x;
  if (n % 2 == 1)
    x *= 2;
  return x;
}

// a^n mod を計算する
long long modpow(long long a, long long n) {
  long long res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}

//////////////////////////
int main() {
  int N, K;
  cin >> N >> K;
  vector<int> L(K), R(K);
  rep(i, K) { cin >> L[i] >> R[i]; }
  vector<mint> dp(N + 1), cs(N + 1);
  dp[1] = 1;
  cs[1] = 1;
  for (int i = 2; i <= N; i++) {
    rep(j, K) { dp[i] += cs[max(i - L[j], 0)] - cs[max(i - R[j] - 1, 0)]; }
    cs[i] = cs[i - 1] + dp[i];
  }
  cout << dp[N] << endl;
}


#pragma GCC optimize("Ofast")

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

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pop_b pop_back
#define pf push_front
#define pop_f pop_front
#define mt make_tuple
#define eb emplace_back
#define sf(x) sizeof(x)
#define len(x) x.length()
#define sz(x) x.size()
#define fastio()                                                               \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0)

#define LB(x, v) (lower_bound(x.begin(), x.end(), v) - x.begin())
#define UB(x, v) (upper_bound(x.begin(), x.end(), v) - x.begin())
typedef long long ll;
typedef pair<ll, ll> ii;
typedef long double ld;
typedef vector<int> vi;
typedef vector<set<ll>> vset;
typedef vector<ll> vl;
typedef vector<ld> vd;
typedef deque<ll> dql;
typedef deque<int> dqi;
typedef unsigned long long ull;
typedef tuple<int, int, int> State;

#define error(args...)                                                         \\
  {                                                                            \\
    string _s = #args;                                                         \\
    replace(_s.begin(), _s.end(), ',', ' ');                                   \\
    stringstream _ss(_s);                                                      \\
    istream_iterator<string> _it(_ss);                                         \\
    err(_it, args);                                                            \\
  }
void err(istream_iterator<string> it) {}
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << ", ";
  err(++it, args...);
  cout << "\\n";
}

#define vmax(type) std::numeric_limits<type>::max()
#define vmin(type) std::numeric_limits<type>::min()
#define each(a, x) for (auto &a : (x))
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define repr(i, n) for (ll i = (n)-1; i >= 0; i--)
#define rep2(i, l, r) for (ll i = (l); i < (r); i++)
#define rep2r(i, l, r) for (ll i = (r)-1; i >= (l); i--)
#define range(a) a.begin(), a.end()
#define deb(x) cout << #x << " " << x << endl;
#define cinai(a, n)                                                            \\
  vi a(n);                                                                     \\
  rep(i, n) { cin >> a[i]; }
#define cinal(a, n)                                                            \\
  vl a(n);                                                                     \\
  rep(i, n) { cin >> a[i]; }
#define coutai(a, n)                                                           \\
  rep(i, n) { cout << a[i] << " "; }                                           \\
  ent;
#define coutal(a, n)                                                           \\
  rep(i, n) { cout << a[i] << " "; }                                           \\
  ent;
#define ent cout << endl;
#define resize_vec(a) a.resize(unique(a.begin(), a.end()) - a.begin());
#define ms(dp, x) memset(dp, x, sf(dp))
#define endl '\\n'

ll powm(ll a, ll b, ll mod) {
  ll res = 1;
  while (b) {
    if (b & 1)
      res = (res * a) % mod;
    a = (a * a) % mod;
    b >>= 1;
  }
  return res;
}

const ll mod = 998244353;
const ll N = 1000005;
const ll inf = 1e9;

void solve() {
  int n, k;
  cin >> n >> k;
  vector<int> seg;
  rep(i, k) {
    int x, y;
    cin >> x >> y;
    rep2(j, x, y + 1) seg.pb(j);
  }
  vl dp(n + 1, 0);
  sort(range(seg));
  dp[1] = 1;
  rep2(i, 1, n) {
    for (int j : seg) {
      if (i + j <= n) {
        dp[i + j] += dp[i];
        dp[i + j] %= mod;
      } else
        break;
    }
  }
  cout << dp[n] << endl;
}

// #define _DEBUG
// #define testCases
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);
  cout << fixed << setprecision(15);

  int tc = 1;
#ifdef testCases
  cin >> tc;
#endif
  while (tc--) {
#ifdef _DEBUG
    int tt = clock();
#endif
    solve();

#ifdef _DEBUG
    cerr << "TIME = " << clock() - tt << endl;
    tt = clock();
#endif
  }
  return 0;
}

#pragma GCC optimize("Ofast")

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

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pop_b pop_back
#define pf push_front
#define pop_f pop_front
#define mt make_tuple
#define eb emplace_back
#define sf(x) sizeof(x)
#define len(x) x.length()
#define sz(x) x.size()
#define fastio()                                                               \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0)

#define LB(x, v) (lower_bound(x.begin(), x.end(), v) - x.begin())
#define UB(x, v) (upper_bound(x.begin(), x.end(), v) - x.begin())
typedef long long ll;
typedef pair<ll, ll> ii;
typedef long double ld;
typedef vector<int> vi;
typedef vector<set<ll>> vset;
typedef vector<ll> vl;
typedef vector<ld> vd;
typedef deque<ll> dql;
typedef deque<int> dqi;
typedef unsigned long long ull;
typedef tuple<int, int, int> State;

#define error(args...)                                                         \\
  {                                                                            \\
    string _s = #args;                                                         \\
    replace(_s.begin(), _s.end(), ',', ' ');                                   \\
    stringstream _ss(_s);                                                      \\
    istream_iterator<string> _it(_ss);                                         \\
    err(_it, args);                                                            \\
  }
void err(istream_iterator<string> it) {}
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << ", ";
  err(++it, args...);
  cout << "\\n";
}

#define vmax(type) std::numeric_limits<type>::max()
#define vmin(type) std::numeric_limits<type>::min()
#define each(a, x) for (auto &a : (x))
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define repr(i, n) for (ll i = (n)-1; i >= 0; i--)
#define rep2(i, l, r) for (ll i = (l); i < (r); i++)
#define rep2r(i, l, r) for (ll i = (r)-1; i >= (l); i--)
#define range(a) a.begin(), a.end()
#define deb(x) cout << #x << " " << x << endl;
#define cinai(a, n)                                                            \\
  vi a(n);                                                                     \\
  rep(i, n) { cin >> a[i]; }
#define cinal(a, n)                                                            \\
  vl a(n);                                                                     \\
  rep(i, n) { cin >> a[i]; }
#define coutai(a, n)                                                           \\
  rep(i, n) { cout << a[i] << " "; }                                           \\
  ent;
#define coutal(a, n)                                                           \\
  rep(i, n) { cout << a[i] << " "; }                                           \\
  ent;
#define ent cout << endl;
#define resize_vec(a) a.resize(unique(a.begin(), a.end()) - a.begin());
#define ms(dp, x) memset(dp, x, sf(dp))
#define endl '\\n'

ll powm(ll a, ll b, ll mod) {
  ll res = 1;
  while (b) {
    if (b & 1)
      res = (res * a) % mod;
    a = (a * a) % mod;
    b >>= 1;
  }
  return res;
}

const ll mod = 998244353;
const ll N = 1000005;
const ll inf = 1e9;

ll n;
ll st[4 * N], ar[N], lazy[4 * N];

// si -> index of cell that we are at and we are going to fill
// ss -> start of current tree
// se -> end of our tree
//  [ss, se]
void build(int si, int ss, int se) {
  if (ss == se) {
    st[si] = ar[ss];
    return;
  }

  int mid = (ss + se) / 2;

  build(2 * si, ss, mid);
  build(2 * si + 1, mid + 1, se);

  st[si] = st[2 * si] + st[2 * si + 1];
}

int query(int si, int ss, int se, int qs, int qe) {
  if (lazy[si] != 0) {
    int dx = lazy[si] % mod;
    lazy[si] = 0;
    (st[si] += dx * (se - ss + 1)) % mod;

    if (ss != se) {
      (lazy[2 * si] += dx) % mod;
      (lazy[2 * si + 1] += dx) % mod;
    }
  }

  if (ss > qe || se < qs)
    return 0;

  if (ss >= qs && se <= qe)
    return st[si] % mod;

  int mid = (ss + se) / 2;
  return (query(2 * si, ss, mid, qs, qe) +
          query(2 * si + 1, mid + 1, se, qs, qe)) %
         mod;
}

void update(int si, int ss, int se, int qs, int qe, int val) {
  if (lazy[si] != 0) {
    int dx = lazy[si] % mod;
    lazy[si] = 0;
    (st[si] += dx * (se - ss + 1)) % mod;

    if (ss != se) {
      (lazy[2 * si] += dx) % mod;
      (lazy[2 * si + 1] += dx) % mod;
    }
  }

  if (ss > qe || se < qs)
    return;

  if (ss >= qs && se <= qe) {
    int dx = ((se - ss + 1) * val) % mod;
    (st[si] += dx) % mod;

    if (ss != se) {
      (lazy[2 * si] += val) % mod;
      (lazy[2 * si + 1] += val) % mod;
    }
    return;
  }

  int mid = (ss + se) / 2;
  update(2 * si, ss, mid, qs, qe, val);
  update(2 * si + 1, mid + 1, se, qs, qe, val);

  st[si] = (st[2 * si] + st[2 * si + 1]) % mod;
}

void solve() {
  ll k;
  cin >> n >> k;
  rep(i, 4 * n + 1) lazy[i] = 0;
  rep(i, 3 * n) ar[i + 1] = 0;
  ar[1] = 1;
  build(1, 1, 3 * n);
  vector<pair<int, int>> pr;
  rep(i, k) {
    int x, y;
    cin >> x >> y;
    pr.pb({x, y});
  }
  sort(range(pr));
  rep2(i, 1, n) {
    rep(j, k) {
      update(1, 1, n, i + pr[j].fi, i + pr[j].se, query(1, 1, n, i, i) % mod);
    }
  }
  cout << query(1, 1, n, n, n) % mod << endl;
}

// #define _DEBUG
// #define testCases
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);
  cout << fixed << setprecision(15);

  int tc = 1;
#ifdef testCases
  cin >> tc;
#endif
  while (tc--) {
#ifdef _DEBUG
    int tt = clock();
#endif
    solve();

#ifdef _DEBUG
    cerr << "TIME = " << clock() - tt << endl;
    tt = clock();
#endif
  }
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
using vint = vector<int>;
using vvint = vector<vint>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vchar = vector<char>;
using vvchar = vector<vchar>;
using vp = vector<P>;
using vpp = vector<pair<P, P>>;
using vvp = vector<vp>;

#define rep(i, n) for (int i = 0; i < n; ++i)
#pragma region Debug
istream &operator>>(istream &is, P &a) { return is >> a.first >> a.second; }
ostream &operator<<(ostream &os, const P &a) {
  return os << "(" << a.first << "," << a.second << ")";
}

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) {
  for (const auto &v : vv) {
    view(v);
  }
}
#pragma endregion

#pragma region mod
const int p = 998244353;
struct mint {
  ll x;
  mint(ll xx = 0) : x(xx % p) {}
  mint &operator+=(const mint a) {
    if ((x += a.x) >= p)
      x -= p;
    return *this;
  }
  mint &operator-=(const mint a) {
    if ((x += p - a.x) >= p)
      x -= p;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= p;
    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 {
    mint r = 1;
    mint a = *this;
    while (true) {
      if (t & 1) {
        r *= a;
      }
      t >>= 1;
      if (t == 0)
        break;
      a *= a;
    }

    return r;
  }

  mint inv() const { return pow(p - 2); }

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

struct comb {
  vector<mint> fact, invs;
  comb(int n) : fact(n + 1), invs(n + 1) {
    assert(n < p);

    fact[0] = 1;
    for (int i = 1; i <= n; ++i)
      fact[i] = fact[i - 1] * i;

    invs[n] = fact[n].inv();
    for (int i = n; i >= 1; --i)
      invs[i - 1] = invs[i] * i;
  }
  mint operator()(int n, int k) {
    if (k < 0 || k > n)
      return 0;
    return fact[n] * invs[n - k] * invs[k];
  }
};
#pragma endregion

using vmint = vector<mint>;
int main() {
  int n, k;
  cin >> n >> k;
  set<int> s;
  vp lr(k);
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    lr[i] = P(l, r);
  }

  vmint dp(n);
  dp[0] = 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < k; ++j) {
      P p = lr[j];
      int l = p.first, r = p.second;
      for (int m = l; m <= r; ++m) {
        if (i + m < n) {
          dp[i + m] += dp[i];
        }
      }
    }
  }

  cout << dp[n - 1] << endl;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
using vint = vector<int>;
using vvint = vector<vint>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vchar = vector<char>;
using vvchar = vector<vchar>;
using vp = vector<P>;
using vpp = vector<pair<P, P>>;
using vvp = vector<vp>;

#define rep(i, n) for (int i = 0; i < n; ++i)
#pragma region Debug
istream &operator>>(istream &is, P &a) { return is >> a.first >> a.second; }
ostream &operator<<(ostream &os, const P &a) {
  return os << "(" << a.first << "," << a.second << ")";
}

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) {
  for (const auto &v : vv) {
    view(v);
  }
}
#pragma endregion

#pragma region mod
const int p = 998244353;
struct mint {
  ll x;
  mint(ll xx = 0) : x(xx % p) {}
  mint &operator+=(const mint a) {
    if ((x += a.x) >= p)
      x -= p;
    return *this;
  }
  mint &operator-=(const mint a) {
    if ((x += p - a.x) >= p)
      x -= p;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= p;
    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 {
    mint r = 1;
    mint a = *this;
    while (true) {
      if (t & 1) {
        r *= a;
      }
      t >>= 1;
      if (t == 0)
        break;
      a *= a;
    }

    return r;
  }

  mint inv() const { return pow(p - 2); }

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

struct comb {
  vector<mint> fact, invs;
  comb(int n) : fact(n + 1), invs(n + 1) {
    assert(n < p);

    fact[0] = 1;
    for (int i = 1; i <= n; ++i)
      fact[i] = fact[i - 1] * i;

    invs[n] = fact[n].inv();
    for (int i = n; i >= 1; --i)
      invs[i - 1] = invs[i] * i;
  }
  mint operator()(int n, int k) {
    if (k < 0 || k > n)
      return 0;
    return fact[n] * invs[n - k] * invs[k];
  }
};
#pragma endregion

using vmint = vector<mint>;
int main() {
  int n, k;
  cin >> n >> k;
  set<int> s;
  vp lr(k);
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    lr[i] = P(l, r);
  }

  vmint dp(n + 1, 0), cs(n + 1);
  cs[0] = 1;
  dp[1] = -1;

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < k; ++j) {
      P p = lr[j];
      int l = p.first, r = p.second;
      if (i + l <= n) {
        dp[i + l] += cs[i];
      }
      if (i + r + 1 <= n) {
        dp[i + r + 1] -= cs[i];
      }
    }

    cs[i + 1] = cs[i] + dp[i + 1];
  }

  cout << cs[n - 1] << endl;
  return 0;
}


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

#define trav(a, A) for (auto &a : A)
#define f first
#define s second

typedef long long ll;

ll MOD = 998244353;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int INF = 0x3f3f3f3f;
const ll MAXN = 1e+5 + 7;

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  ll i, j, n, k;
  cin >> n >> k;
  vector<ll> dp(n), jp;
  dp[0] = 1;
  for (i = 0; i < k; ++i) {
    ll a, b;
    cin >> a >> b;
    for (j = a; j <= b; ++j)
      jp.push_back(j);
  }
  sort(jp.begin(), jp.end());
  for (i = 0; i < n; ++i)
    for (j = 0; j < jp.size() && i + jp[j] < n; ++j)
      dp[i + jp[j]] += dp[i], dp[i + jp[j]] %= MOD;
  // trav (a, dp) cout << a << '\\n';
  cout << dp[n - 1] << '\\n';

  return 0;
}

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

#define trav(a, A) for (auto &a : A)
#define f first
#define s second

typedef long long ll;

ll MOD = 998244353;
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
const int INF = 0x3f3f3f3f;
const ll MAXN = 1e+5 + 7;

ll rsq(vector<ll> &tree, ll l, ll r) {
  ll i, j, n = tree.size() / 2;
  l = max(0LL, l);
  r = max(0LL, r);
  ll ret = 0;
  for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
    if (l & 1)
      ret += tree[l++], ret %= MOD;
    if (r & 1)
      ret += tree[--r], ret %= MOD;
  }
  return ret;
}

void upd(vector<ll> &tree, ll p, ll v) {
  ll i, n = tree.size() / 2;
  tree[n + p] = v;
  for (i = (n + p) >> 1; i > 0; i >>= 1)
    tree[i] = tree[i << 1] + tree[i << 1 | 1], tree[i] %= MOD;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  ll i, j, n, k;
  cin >> n >> k;
  vector<ll> dp(n), tree(2 * n, 0);
  vector<pair<ll, ll>> qr(k);
  trav(p, qr) cin >> p.f >> p.s;
  sort(qr.begin(), qr.end());
  dp[0] = 1;
  tree[n] = 1;
  for (i = n; i > 0; i >>= 1)
    tree[i] = 1;
  for (i = 1; i < n; ++i) {
    for (j = 0; j < k; ++j)
      dp[i] += rsq(tree, i - qr[j].s, i - qr[j].f + 1), dp[i] %= MOD;
    upd(tree, i, dp[i]);
  }
  // trav (a, dp) cout << a << '\\n';
  cout << dp[n - 1] << '\\n';

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
/*******  All Required define Pre-Processors and typedef Constants *******/
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep2(i, a, b) for (int i = a; i <= (b); ++i)
#define rep3(i, a, b) for (int i = a; i >= (b); --i)
#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.rbegin(), cont.rend()
#define Dcout(a) cout << setprecision(20) << a << endl
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define fi first
#define se second
using Graph = vector<vector<ll>>;
const ll INF64 = (1LL << 60);
const ll INF = 1 << 29;
const double pi = acos(-1.0);
/******************* debug ********************/
#define debug(var)                                                             \\
  do {                                                                         \\
    std::cout << #var << " : ";                                                \\
    view(var);                                                                 \\
  } while (0)
#define deb cout << "line : " << __LINE__ << " debug" << endl
template <typename T> void view(T e) { cout << e << endl; }
template <typename T> void view(const vector<T> &v) {
  for (const auto &e : v)
    cout << e << " ";
  cout << endl;
}
template <typename T> void view(const vector<vector<T>> &vv) {
  for (const auto &v : vv) {
    view(v);
  }
}
/****** Template of some basic operations *****/
struct IoSetup {
  IoSetup() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
  }
} iosetup;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  os << p.first << " " << p.second;
  return os;
}

template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
  is >> p.first >> p.second;
  return is;
}

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < (int)v.size(); i++) {
    os << v[i] << (i + 1 != v.size() ? " " : "");
  }
  return os;
}

template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &in : v)
    is >> in;
  return is;
}

template <typename T1, typename T2> inline bool chmax(T1 &a, T2 b) {
  return a < b && (a = b, true);
}

template <typename T1, typename T2> inline bool chmin(T1 &a, T2 b) {
  return a > b && (a = b, true);
}

template <typename T = ll> vector<T> make_v(size_t a) { return vector<T>(a); }

template <typename T, typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}

template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T &t, const V &v) {
  t = v;
}

template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T &t, const V &v) {
  for (auto &e : t)
    fill_v(e, v);
}

template <typename F> struct FixPoint : F {
  FixPoint(F &&f) : F(forward<F>(f)) {}

  template <typename... Args> decltype(auto) operator()(Args &&...args) const {
    return F::operator()(*this, forward<Args>(args)...);
  }
};

template <typename F> inline decltype(auto) MFP(F &&f) {
  return FixPoint<F>{forward<F>(f)};
}
/*******************************************************/
//******************** Start coding! *******************/

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n, k;
  cin >> n >> k;
  vector<ll> l(k), r(k);
  vector<ll> a;
  rep(i, k) {
    cin >> l[i] >> r[i];
    for (ll j = l[i]; j <= r[i]; j++) {
      a.push_back(j);
    }
  }

  sort(all(a));
  // debug(a);

  vector<ll> masu(n, 0);
  ll mod = 998244353;
  masu[0] = 1;
  for (int i = 1; i < n; i++) {
    ll dist = i;
    int k = upper_bound(all(a), dist) - a.begin();
    // debug(i);
    // debug(k);
    vector<ll> tmp;
    ll sum = 0;
    rep(j, k) {
      int id = i - a[j];
      // debug(id);
      sum += masu[id];
    }
    // debug(sum);

    masu[i] += sum;
    masu[i] %= mod;
  }

  cout << masu[n - 1] << endl;
  // debug(masu);
}

#include <bits/stdc++.h>
using namespace std;
/*******  All Required define Pre-Processors and typedef Constants *******/
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep2(i, a, b) for (int i = a; i <= (b); ++i)
#define rep3(i, a, b) for (int i = a; i >= (b); --i)
#define all(cont) cont.begin(), cont.end()
#define rall(cont) cont.rbegin(), cont.rend()
#define Dcout(a) cout << setprecision(20) << a << endl
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define fi first
#define se second
using Graph = vector<vector<ll>>;
const ll INF64 = (1LL << 60);
const ll INF = 1 << 29;
const double pi = acos(-1.0);
/******************* debug ********************/
#define debug(var)                                                             \\
  do {                                                                         \\
    std::cout << #var << " : ";                                                \\
    view(var);                                                                 \\
  } while (0)
#define deb cout << "line : " << __LINE__ << " debug" << endl
template <typename T> void view(T e) { cout << e << endl; }
template <typename T> void view(const vector<T> &v) {
  for (const auto &e : v)
    cout << e << " ";
  cout << endl;
}
template <typename T> void view(const vector<vector<T>> &vv) {
  for (const auto &v : vv) {
    view(v);
  }
}
/****** Template of some basic operations *****/
struct IoSetup {
  IoSetup() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
  }
} iosetup;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  os << p.first << " " << p.second;
  return os;
}

template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
  is >> p.first >> p.second;
  return is;
}

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < (int)v.size(); i++) {
    os << v[i] << (i + 1 != v.size() ? " " : "");
  }
  return os;
}

template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &in : v)
    is >> in;
  return is;
}

template <typename T1, typename T2> inline bool chmax(T1 &a, T2 b) {
  return a < b && (a = b, true);
}

template <typename T1, typename T2> inline bool chmin(T1 &a, T2 b) {
  return a > b && (a = b, true);
}

template <typename T = ll> vector<T> make_v(size_t a) { return vector<T>(a); }

template <typename T, typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}

template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T &t, const V &v) {
  t = v;
}

template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T &t, const V &v) {
  for (auto &e : t)
    fill_v(e, v);
}

template <typename F> struct FixPoint : F {
  FixPoint(F &&f) : F(forward<F>(f)) {}

  template <typename... Args> decltype(auto) operator()(Args &&...args) const {
    return F::operator()(*this, forward<Args>(args)...);
  }
};

template <typename F> inline decltype(auto) MFP(F &&f) {
  return FixPoint<F>{forward<F>(f)};
}
/*******************************************************/
//******************** Start coding! *******************/
// 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 = 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() {
  int n, k;
  cin >> n >> k;
  vector<ll> l(k), r(k);
  rep(i, k) { cin >> l[i] >> r[i]; }

  vector<mint> dp(n + 1);
  vector<mint> dpsum(n + 1);
  dp[1] = 1;
  dpsum[1] = 1;
  for (int i = 2; i <= n; i++) {
    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;
}


#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
using ll = long long;
using namespace std;
const ll mod = 998244353;

int main() {
  int N, K;
  cin >> N >> K;
  vector<int> p(N + 2);
  rep(i, K) {
    int l, r;
    cin >> l >> r;
    p[l] += 1;
    p[r + 1] -= 1;
  }
  vector<int> S;
  for (int i = 1; i <= N; i++) {
    p[i] += p[i - 1];
    if (p[i] > 0)
      S.push_back(i);
  }
  vector<ll> dp(2 * N + 5);
  dp[0] = 1;
  rep(i, N) {
    for (int j : S) {
      dp[i + j] += dp[i];
      dp[i + j] %= mod;
    }
  }
  cout << dp[N - 1] << endl;

  return 0;
}

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
using ll = long long;
using namespace std;
const ll mod = 998244353;

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

  vector<ll> dp(2 * N + 5);
  dp[0] = 1;
  dp[1] = -1;
  rep(i, N) {
    rep(j, K) {
      dp[i + L[j]] += dp[i];
      dp[i + L[j]] = (dp[i + L[j]] + mod) % mod;
      dp[i + R[j] + 1] -= dp[i];
    }
    dp[i + 1] += dp[i];
    dp[i + 1] = (dp[i + 1] + mod) % mod;
  }
  cout << dp[N - 1] << endl;

  return 0;
}


#include <bits/stdc++.h>
#define rep(i, a, b) for (ll i = ll(a); i < ll(b); i++)
#define irep(i, a, b) for (ll i = ll(a); i >= ll(b); i--)
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;
}
#define pb push_back
#define mp make_pair
#define F .first
#define S .second
#define pll pair<ll, ll>
using ll = long long;
using ld = long double;
const ll INF = 1LL << 60;
const ll mod = 1e9 + 7;
const ll mod2 = 998244353;
using namespace std;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

ll l[20], r[20];
ll dp[220000];
map<ll, ll> x;
int main() {
  ll n, k, ans = 0;
  cin >> n >> k;

  rep(i, 0, k) {
    cin >> l[i] >> r[i];

    rep(j, l[i], r[i] + 1) {
      x[j] = 1;
      /*
      ll c=j;
      ll k=2;
      bool f=false;
      while (c>=k*k) {
          if(c%k==0){
           c/=k;
          if(c%k!=0)ans++;
            } else {
           k++;
       }*/
    }
  }
  dp[1] = 1;
  rep(i, 1, n + 1) {
    for (auto j : x) {
      ll p = i + j.first;
      if (p > n)
        break;
      if (p <= n)
        dp[p] = (dp[i] + dp[p]) % mod2;
    }
  }
  cout << (mod2 + dp[n]) % mod2;
}

#include <bits/stdc++.h>
#define rep(i, a, b) for (ll i = ll(a); i < ll(b); i++)
#define irep(i, a, b) for (ll i = ll(a); i >= ll(b); i--)
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;
}
#define pb push_back
#define mp make_pair
#define F .first
#define S .second
#define pll pair<ll, ll>
using ll = long long;
using ld = long double;
const ll INF = 1LL << 60;
const ll mod = 1e9 + 7;
const ll mod2 = 998244353;
using namespace std;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

ll l[20], r[20];
ll dp[220000], sdp[220000];
map<ll, ll> x;
int main() {
  ll n, k, ans = 0;
  cin >> n >> k;

  rep(i, 0, k) { cin >> l[i] >> r[i]; }
  dp[0] = 1, sdp[1] = 1;
  rep(i, 1, n + 1) {
    rep(j, 0, k) {
      ll L = max((ll)0, i - r[j]);
      ll R = max((ll)0, i - l[j] + 1);
      dp[i] = (dp[i] + sdp[R] - sdp[L]) % mod2;
    }
    sdp[i + 1] = sdp[i] + dp[i];
  }
  cout << (mod2 + dp[n - 1]) % mod2;
}


#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define RREP(i, n) for (int i = n - 1; i >= 0; i--)
#define FOR(i, k, n) for (int i = (k); i < (int)(n); i++)
#define all(i, n) (i), (i + n)

int dx4[4] = {1, 0, -1, 0};
int dy4[4] = {0, -1, 0, 1};
int dx8[8] = {1, 0, -1, 1, -1, 1, 0, -1};
int dy8[8] = {1, 1, 1, 0, 0, -1, -1, -1};
int dx9[9] = {0, 1, 0, -1, 1, -1, 1, 0, -1};
int dy9[9] = {0, 1, 1, 1, 0, 0, -1, -1, -1};

typedef pair<int, int> P;
typedef pair<string, int> SP;
typedef long long ll;
typedef pair<ll, ll> PLL;

const int INF = 1e9;
const ll LLINF = 1e18;
const int MAX_V = 1e6 + 1;
// << fixed << setprecision
// --------------------------------------
int n, k;
const int mod = 998244353;
#include <cassert>
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, const mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }

mint dp[20005];
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  cin >> n >> k;
  vector<PLL> vp;
  REP(i, k) {
    ll l, r;
    cin >> l >> r;

    vp.push_back(P(l, r));
  }

  dp[0] = 1;
  dp[1] = -1;
  mint sum = 0;
  REP(i, n) {
    sum += dp[i];
    dp[i] = sum;
    REP(j, k) {
      ll l = vp[j].first, r = vp[j].second;

      if (i + l <= n)
        dp[i + l] += dp[i];
      if (i + r + 1 <= n)
        dp[i + r + 1] -= dp[i];
    }
  }

  cout << dp[n - 1] << endl;
}

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define RREP(i, n) for (int i = n - 1; i >= 0; i--)
#define FOR(i, k, n) for (int i = (k); i < (int)(n); i++)
#define all(i, n) (i), (i + n)

int dx4[4] = {1, 0, -1, 0};
int dy4[4] = {0, -1, 0, 1};
int dx8[8] = {1, 0, -1, 1, -1, 1, 0, -1};
int dy8[8] = {1, 1, 1, 0, 0, -1, -1, -1};
int dx9[9] = {0, 1, 0, -1, 1, -1, 1, 0, -1};
int dy9[9] = {0, 1, 1, 1, 0, 0, -1, -1, -1};

typedef pair<int, int> P;
typedef pair<string, int> SP;
typedef long long ll;
typedef pair<ll, ll> PLL;

const int INF = 1e9;
const ll LLINF = 1e18;
const int MAX_V = 1e6 + 1;
// << fixed << setprecision
// --------------------------------------
int n, k;
const int mod = 998244353;
#include <cassert>
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, const mint &a) { return is >> a.x; }
ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }

mint dp[200005];
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  cin >> n >> k;
  vector<PLL> vp;
  REP(i, k) {
    ll l, r;
    cin >> l >> r;

    vp.push_back(P(l, r));
  }

  dp[0] = 1;
  dp[1] = -1;
  mint sum = 0;
  REP(i, n) {
    sum += dp[i];
    dp[i] = sum;
    REP(j, k) {
      ll l = vp[j].first, r = vp[j].second;

      if (i + l <= n)
        dp[i + l] += dp[i];
      if (i + r + 1 <= n)
        dp[i + r + 1] -= dp[i];
    }
  }

  cout << dp[n - 1] << endl;
}