/*
 * if you are interested in the reference code here,
 * see https://github.com/georeth/OJLIBS for more information
 *
 * Solution Author : Georeth Chow <georeth2010@gmail.com>
 */
#include <algorithm>
#include <cassert>   // assert
#include <cfloat>    // DBL_MIN DBL_MAX
#include <cinttypes> // PRId64 SCNd64
#include <climits>   // INT_MIN LLONG_MIN
#include <cmath>
#include <cstdint> // int64_t
#include <cstdio>
#include <cstdlib> // malloc
#include <cstring> // memset
#include <ctime>   // clock
#include <deque>
#include <iostream> // be careful.
#include <limits>   // numeric_limits
#include <map>
#include <set>
#include <sstream>
#include <tuple> // pair, tuple
#include <vector>
using namespace std; // use as solution header. name polution is fine.
#ifdef LOCAL_JUDGE
#define pr_debug(...) fprintf(stderr, __VA_ARGS__)
#define pr_line() fprintf(stderr, "%s: %d\\n", __FILE__, __LINE__)
#else
#define pr_debug(...)
#define pr_line()
#endif
template <typename T> bool chmax(T &m, const T &v) {
  if (v > m)
    return m = v, true;
  return false;
}
template <typename T> bool chmin(T &m, const T &v) {
  if (v < m)
    return m = v, true;
  return false;
}
template <typename T> bool chinc(T &v1, T &v2) {
  if (v1 > v2)
    return swap(v1, v2), true;
  return false;
}
template <typename T> bool chdec(T &v1, T &v2) {
  if (v1 < v2)
    return swap(v1, v2), true;
  return false;
}
#define ALL(x) begin(x), end(x)
#define FOR0(i, n) for (int i = 0, i##end = n; i < i##end; i++)
#define FOR1(i, n) for (int i = 1, i##end = n; i <= i##end; i++)
#define FOR(i, a, b) for (int i = a, i##end = b; i <= i##end; i++)
#define FOD0(i, n) for (int i = (n)-1; ~i; i--)
#define FOD1(i, n) for (int i = n; i; i--)
#define FOD(i, a, b) for (int i = a, i##end = b; i >= i##end; i--)
#define FORE(i, x) for (__typeof(x.end()) i = x.begin(); i != x.end(); ++i)
typedef int64_t ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pair<int, int>> vii;
typedef vector<vector<int>> vvi;
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#include <iostream>
namespace fio {
static const char eof = '\\xff';
#define LL long long
#define I inline
#define OP operator
#define RT return *this;
#define ALL_INT(mcr)                                                           \\
  mcr(int) mcr(long) mcr(LL) mcr(unsigned) mcr(unsigned long) mcr(unsigned LL)
#define ALL_FLT(mcr) mcr(float) mcr(double) mcr(long double)
#define S2D                                                                    \\
  x = 0;                                                                       \\
  int c = P();                                                                 \\
  while ((c < '0' || c > '9') && c != '-')                                     \\
    c = P();                                                                   \\
  bool h = false;                                                              \\
  if (c == '-')                                                                \\
  h = true, c = P()
#define R2D                                                                    \\
  for (; c >= '0' && c <= '9'; c = P())                                        \\
  x = x * 10 + c - '0'
#define R2F                                                                    \\
  if (c == '.') {                                                              \\
    double u = 0.1;                                                            \\
    for (c = P(); c >= '0' && c <= '9'; c = P(), u *= 0.1)                     \\
      x += u * (c - '0');                                                      \\
  }
#define RD_INT(Int)                                                            \\
  I Fr &OP, (Int & x) {                                                        \\
    S2D;                                                                       \\
    R2D;                                                                       \\
    if (h)                                                                     \\
      x = -x;                                                                  \\
    RT                                                                         \\
  }
#define RD_FLT(Flt)                                                            \\
  I Fr &OP, (Flt & x) {                                                        \\
    S2D;                                                                       \\
    R2D;                                                                       \\
    R2F;                                                                       \\
    if (h)                                                                     \\
      x = -x;                                                                  \\
    RT                                                                         \\
  }
struct Cg {
  I char OP()() {
    char c = (char)getchar();
    if (c == eof)
      valid = false;
    return c;
  };
  bool valid = true;
};
struct Cp {
  I void OP()(int x) { putchar(x); }
};
struct Ce {
  I void OP()(int x) { putc(x, stderr); }
};
I bool IS(char x) { return x == ' ' || x == '\\r' || x == '\\n' || x == '\\t'; }
template <class T> struct Fr {
  T P;
  ALL_INT(RD_INT) ALL_FLT(RD_FLT) I Fr &OP, (char &x) {
    for (x = P(); IS(x);)
      x = P();
    RT
  }
  I Fr &OP, (char *s) {
    for (*s = P(); IS(*s) && P.valid;)
      *s = P();
    for (; !IS(*s) && P.valid;)
      *++s = P();
    *s = 0;
    RT
  }
  I Fr &OP, (string & s) {
    s.clear();
    char c = P();
    for (; IS(c) && P.valid;)
      c = P();
    for (; !IS(c) && P.valid;)
      s.push_back(c), c = P();
    RT
  }
  I OP bool() { return P.valid; }
};
#define W4D                                                                    \\
  if (x) {                                                                     \\
    if (x < 0)                                                                 \\
      P('-'), x = -x;                                                          \\
    int p = 0;                                                                 \\
    while (x)                                                                  \\
      B[p++] = x % 10 + '0', x /= 10;                                          \\
    while (p--)                                                                \\
      P(B[p]);                                                                 \\
  } else                                                                       \\
    P('0')
#define WR_INT(Int)                                                            \\
  I Fw &OP, (Int x) {                                                          \\
    W4D;                                                                       \\
    RT                                                                         \\
  }
#define WR_FLT(Flt)                                                            \\
  I Fw &OP()(Flt g, int d) {                                                   \\
    if (d) {                                                                   \\
      double t = 0.5;                                                          \\
      for (int i = d; i--;)                                                    \\
        t *= 0.1;                                                              \\
      if (g < 0)                                                               \\
        P('-'), g = -g;                                                        \\
      g += t;                                                                  \\
      *this, (LL)(g);                                                          \\
      P('.');                                                                  \\
      g -= floor(g);                                                           \\
      while (d--) {                                                            \\
        g *= 10;                                                               \\
        int i = (int)floor(g);                                                 \\
        P(i + '0');                                                            \\
        g -= i;                                                                \\
      }                                                                        \\
    } else                                                                     \\
      *this, (g > 0 ? (LL)(g + 0.5) : (LL)(g - 0.5));                          \\
    RT                                                                         \\
  }
template <class T> struct Fw {
  T P;
  char B[32];
  ALL_INT(WR_INT) ALL_FLT(WR_FLT) I Fw &OP, (char x) {
    P(x);
    RT
  }
  typedef char_traits<char> CT;
  typedef basic_ostream<char, CT> &OS;
  typedef basic_istream<char, CT> &IS;
  I Fw &OP, (OS & (*func)(OS)) {
    if (func == static_cast<OS &(*)(OS)>(endl<char, CT>))
      P('\\n');
    RT
  }
  I Fw &OP, (IS & (*func)(IS)) {
    if (func == static_cast<IS &(*)(IS)>(ws<char, CT>))
      P(' ');
    RT
  }
  I Fw &OP, (const char *s) {
    for (; *s; ++s)
      P(*s);
    RT
  }
  I Fw &OP, (const string &s) {
    (*this), s.c_str();
    RT
  }
  template <class C> I Fw &all(const C &v, char sep = ' ', char nl = '\\n') {
    auto it = v.begin();
    for (int i = 0; i < (int)v.size(); ++i, ++it) {
      if (i && sep)
        P(sep);
      (*this), *it;
    }
    if (nl)
      P(nl);
    RT
  }
  template <class U> I Fw &print(U x) {
    (*this), x;
    P('\\n');
    RT
  }
  template <class U, class... Us> I Fw &print(U x, Us... args) {
    (*this), x;
    P(' ');
    print(args...);
    RT
  }
};
#undef LL
#undef I
#undef OP
#undef RT
#undef ALL_INT
#undef ALL_FLT
#undef S2D
#undef R2D
#undef R2F
#undef RD_INT
#undef RD_FLT
#undef W4D
#undef WR_INT
#undef WR_FLT
} // namespace fio
fio::Fr<fio::Cg> fin;
fio::Fw<fio::Cp> fout;
fio::Fw<fio::Ce> ferr;
#include <cstdint>
#include <utility>
static inline unsigned all_ones(unsigned x) {
  x |= (x >> 1);
  x |= (x >> 2);
  x |= (x >> 4);
  x |= (x >> 8);
  x |= (x >> 16);
  return x;
}
static inline int floor_log2(unsigned x) {
  int ans = 0;
  while (x >>= 1)
    ++ans;
  return ans;
}
static inline bool is_pow2(unsigned x) { return !(x & (x - 1)); }
static inline unsigned next_pow2(unsigned x) { return all_ones(x) + 1; }
static inline unsigned ceil_pow2(unsigned x) {
  if (is_pow2(x))
    return x;
  return next_pow2(x);
}
static inline int msb32(unsigned int x) {
  x = all_ones(x);
  return x & ~(x >> 1);
}
static inline int lsb32(unsigned int x) { return x & -x; }
#include <limits>
#include <type_traits>
#ifndef OJLIBS_USE_INT128
#define OJLIBS_USE_INT128 1
#endif
template <typename Int> Int gcd(Int a, Int b) {
  while (a != 0) {
    b %= a;
    if (b == 0)
      return a;
    a %= b;
  }
  return b;
}
template <typename Int, typename RInt = Int> Int lcm(Int a, Int b) {
  return a / gcd(a, b) * static_cast<RInt>(b);
}
template <typename Int, typename XInt>
Int extended_gcd(Int a, Int b, XInt &x, XInt &y) {
  static_assert(std::numeric_limits<XInt>::is_signed, "x, y must be signed");
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  /**
   * r = a - b * q
   * b * k1 + r * k2 = g
   * => a * k2 + b * (k1 - q * k2)
   *                 x = k2
   *                 y = k1 - q * k2 = k1 - q * x
   */
  Int g = extended_gcd(b, a % b, y, x);
  y -= (a / b) * x;
  return g;
}
template <typename Int> Int mul_mod(Int a, Int b, Int m) {
  typedef int64_t TInt;
  static_assert(2 * std::numeric_limits<Int>::digits <=
                    std::numeric_limits<TInt>::digits,
                "multiplication will overflow!");
  TInt p = a;
  p = (p * b) % m;
  return (Int)p;
}
#if defined(__SIZEOF_INT128__) && OJLIBS_USE_INT128
template <> int64_t mul_mod<int64_t>(int64_t a, int64_t b, int64_t m) {
  __int128_t p = __int128_t(a) * b;
  return (int64_t)(p % m);
}
#else
template <> int64_t mul_mod<int64_t>(int64_t a, int64_t b, int64_t m) {
  int64_t r = 0;
  for (int i = 63; i >= 0; --i) {
    r = (r + r) % m;
    if ((b >> i) & 1)
      r = (r + a) % m;
  }
  return r;
}
#endif
template <typename Int, typename PInt> Int pow_mod(Int a, PInt p, Int m) {
  Int r;
  a %= m;
  for (r = 1; p; p >>= 1) {
    if (p & 1)
      r = mul_mod(r, a, m);
    a = mul_mod(a, a, m);
  }
  return r;
}
template <typename Int, typename XInt = typename std::make_signed<Int>::type>
Int inv_mod(Int a, Int m) {
  XInt x, y;
  extended_gcd(a, m, x, y);
  if (x < 0)
    return x + m;
  return x;
}
template <typename Int> Int addx_mod(Int u, Int v, Int m) {
  Int r = u + v;
  if (r >= m)
    r -= m;
  return r;
}
template <typename Int> Int subx_mod(Int u, Int v, Int m) {
  Int r = u - v;
  if (r < 0)
    r += m;
  return r;
}
template <typename Int> Int div_mod(Int u, Int v, Int m) {
  Int g = gcd(v, m);
  assert(u % g == 0);
  Int mm = m / g;
  return mul_mod(u / g, inv_mod(v / g, mm), mm);
}
template <typename Int> Int div_pos_r(Int a, Int b, Int &r) {
  Int q = a / b;
  r = a % b;
  if (r < 0) {
    if (b < 0)
      q += 1, r -= b;
    else
      q -= 1, r += b;
  }
  return q;
}
template <typename Int> Int coprime_div(Int a, Int b) {
  while (b != 1) {
    while (a % b == 0)
      a /= b;
    b = gcd(a, b);
  }
  return a;
}
#define INV_MOD(x) inv_mod((x), MOD)
#define MUL_MOD(x, y) mul_mod((x), (y), MOD)
#define DIV_MOD(x, y) div_mod((x), (y), MOD)
#define MULM_MOD(x, y) (x) = mul_mod((x), (y), MOD)
#define DIVM_MOD(x, y) (x) = div_mod((x), (y), MOD)
#define POW_MOD(x, y) pow_mod((x), (y), MOD)
#define ADDX_MOD(x, y) addx_mod((x), (y), MOD)
#define ADDM_MOD(x, y) (x) = addx_mod((x), (y), MOD)
#define SUBX_MOD(x, y) subx_mod((x), (y), MOD)
#define SUBM_MOD(x, y) (x) = subx_mod((x), (y), MOD)
template <typename T> struct binary_plus {
  T identity() const { return T(); }
  T operator()(const T &t1, const T &t2) const { return t1 + t2; }
  T negate(const T &t) { return -t; }
};
template <typename T, T MOD> struct modular_plus {
  T identity() const { return T(); }
  T operator()(const T &t1, const T &t2) const { return (t1 + t2) % MOD; }
  T negate(const T &t) { return (MOD - t) % MOD; }
};
template <typename T, T MOD, typename TT = int64_t> struct modular_times {
  T identity() const { return 1; }
  T operator()(const T &t1, const T &t2) const { return mul_mod(t1, t2, MOD); }
  T negate(const T &t) { return inv_mod(t, MOD); }
};
template <typename T> struct binary_xor {
  T identity() const { return T(); }
  T operator()(const T &t1, const T &t2) const { return t1 ^ t2; }
  T negate(const T &t) { return t; }
};
template <typename T> struct binary_max {
  T identity() const { return std::numeric_limits<T>::min(); }
  T operator()(const T &t1, const T &t2) const { return std::max(t1, t2); }
};
template <typename T> struct binary_min {
  T identity() const { return std::numeric_limits<T>::max(); }
  T operator()(const T &t1, const T &t2) const { return std::min(t1, t2); }
};
#define COMMON_CODE                                                            \\
  Op op;                                                                       \\
  std::vector<T> vec;                                                          \\
  int size; /* size of last layer */                                           \\
  int offset;                                                                  \\
  segtree(int n) {                                                             \\
    size = n;                                                                  \\
    offset = ceil_pow2(n);                                                     \\
    vec.resize(size + offset + 1,                                              \\
               op.identity()); /* ensure every leaf has sibling */             \\
  }                                                                            \\
  T &operator[](int i) { return vec[offset + i]; }
template <typename T, typename Op = binary_plus<T>, bool flavour_one = true>
struct segtree;
template <typename T, typename Op> struct segtree<T, Op, true> {
  COMMON_CODE
  void rebuild() {
    for (int i = (offset + size - 1) / 2; i > 0; --i)
      vec[i] = op(vec[i + i], vec[i + i + 1]);
  }
  void increase_element(int p, const T &n) {
    for (p += offset; p; p >>= 1)
      vec[p] = op(n, vec[p]);
  }
  void update_element(int p, const T &n) {
    p += offset;
    vec[p] = n;
    while (p >>= 1)
      vec[p] = op(vec[p + p], vec[p + p + 1]);
  }
  T query_range(int s, int t) { return query_include(s, t - 1); }
  T query_include(int s, int t) {
    if (s > t)
      return op.identity();
    s += offset;
    t += offset;
    T left_acc = vec[s];
    if (s == t)
      return left_acc;
    T right_acc = vec[t];
    for (; s ^ t ^ 1; s >>= 1, t >>= 1) {
      if (~s & 1)
        left_acc = op(left_acc, vec[s ^ 1]);
      if (t & 1)
        right_acc = op(vec[t ^ 1], right_acc);
    }
    return op(left_acc, right_acc);
  }
};
template <typename T, typename Op> struct segtree<T, Op, false> {
  COMMON_CODE
  T query_element(int p) {
    T ret = op.identity();
    for (p += offset; p; p >>= 1)
      ret = op(vec[p], ret);
    return ret;
  }
  void increase_range(int s, int t, const T &inc) {
    return increase_include(s, t - 1, inc);
  }
  void increase_include(int s, int t, const T &inc) {
    if (s > t)
      return;
    s += offset;
    t += offset;
    vec[s] = op(inc, vec[s]);
    if (s == t)
      return;
    vec[t] = op(inc, vec[t]);
    for (; s ^ t ^ 1; s >>= 1, t >>= 1) {
      if (~s & 1)
        vec[s ^ 1] = op(inc, vec[s ^ 1]);
      if (t & 1)
        vec[t ^ 1] = op(inc, vec[t ^ 1]);
    }
    return;
  }
  void flatten() {
    for (int i = 1; i < offset; ++i) {
      if (i + i < offset + size) {
        vec[i + i] = op(vec[i], vec[i + i]);
        vec[i + i + 1] =
            op(vec[i], vec[i + i + 1]); // dummy sibling doesn't matter
      } else
        break;
      vec[i] = op.identity();
    }
  }
};
#undef COMMON_CODE
template <int32_t MOD> struct mod_int {
  mod_int() : v(0) {}
  mod_int(int32_t in) : v(in) { fixup(); }
  void fixup() {
    if (v < 0 || v >= MOD) {
      v = v % MOD;
      if (v < 0)
        v += MOD;
    }
  }
  explicit operator int() const { return v; }
#define MINT_OP_GEN(op_str, op_eq_str, op_arith, op_eq_arith)                  \\
  mod_int &operator op_eq_str(const mod_int &that) {                           \\
    op_eq_arith(v, that.v);                                                    \\
    return *this;                                                              \\
  }                                                                            \\
  mod_int operator op_str(const mod_int &that) const {                         \\
    return {op_arith(v, that.v)};                                              \\
  }
  MINT_OP_GEN(+, +=, ADDX_MOD, ADDM_MOD)
  MINT_OP_GEN(-, -=, SUBX_MOD, SUBM_MOD)
  MINT_OP_GEN(*, *=, MUL_MOD, MULM_MOD)
  MINT_OP_GEN(/, /=, DIV_MOD, DIVM_MOD)
#undef MINT_OP_GEN
  int32_t v;
};
/* =====  SOLUTION START  ===== */
constexpr int MOD = 998244353;
constexpr int maxn = 100005;
int dp[maxn];
int main() {
  int N, K;
  fin, N, K;
  vector<pii> intv;
  FOR0(i, K) {
    int L, R;
    fin, L, R;
    intv.push_back({L, R});
  }
  typedef mod_int<MOD> INT;
  segtree<INT> segtree(maxn);
  segtree.increase_element(1, 1);
  FOR(i, 2, N) {
    INT sum = 0;
    for (pii lr : intv) {
      int L = i - lr.second;
      int R = i - lr.first;
      if (R < 1)
        continue;
      chmax(L, 1);
      sum += segtree.query_include(L, R);
    }
    segtree.increase_element(i, sum);
  }
  fout, segtree.query_include(N, N).v, '\\n';
  return 0;
}

/*
 * if you are interested in the reference code here,
 * see https://github.com/georeth/OJLIBS for more information
 *
 * Solution Author : Georeth Chow <georeth2010@gmail.com>
 */
#include <algorithm>
#include <cassert>   // assert
#include <cfloat>    // DBL_MIN DBL_MAX
#include <cinttypes> // PRId64 SCNd64
#include <climits>   // INT_MIN LLONG_MIN
#include <cmath>
#include <cstdint> // int64_t
#include <cstdio>
#include <cstdlib> // malloc
#include <cstring> // memset
#include <ctime>   // clock
#include <deque>
#include <iostream> // be careful.
#include <limits>   // numeric_limits
#include <map>
#include <set>
#include <sstream>
#include <tuple> // pair, tuple
#include <vector>
using namespace std; // use as solution header. name polution is fine.
#ifdef LOCAL_JUDGE
#define pr_debug(...) fprintf(stderr, __VA_ARGS__)
#define pr_line() fprintf(stderr, "%s: %d\\n", __FILE__, __LINE__)
#else
#define pr_debug(...)
#define pr_line()
#endif
template <typename T> bool chmax(T &m, const T &v) {
  if (v > m)
    return m = v, true;
  return false;
}
template <typename T> bool chmin(T &m, const T &v) {
  if (v < m)
    return m = v, true;
  return false;
}
template <typename T> bool chinc(T &v1, T &v2) {
  if (v1 > v2)
    return swap(v1, v2), true;
  return false;
}
template <typename T> bool chdec(T &v1, T &v2) {
  if (v1 < v2)
    return swap(v1, v2), true;
  return false;
}
#define ALL(x) begin(x), end(x)
#define FOR0(i, n) for (int i = 0, i##end = n; i < i##end; i++)
#define FOR1(i, n) for (int i = 1, i##end = n; i <= i##end; i++)
#define FOR(i, a, b) for (int i = a, i##end = b; i <= i##end; i++)
#define FOD0(i, n) for (int i = (n)-1; ~i; i--)
#define FOD1(i, n) for (int i = n; i; i--)
#define FOD(i, a, b) for (int i = a, i##end = b; i >= i##end; i--)
#define FORE(i, x) for (__typeof(x.end()) i = x.begin(); i != x.end(); ++i)
typedef int64_t ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pair<int, int>> vii;
typedef vector<vector<int>> vvi;
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#include <iostream>
namespace fio {
static const char eof = '\\xff';
#define LL long long
#define I inline
#define OP operator
#define RT return *this;
#define ALL_INT(mcr)                                                           \\
  mcr(int) mcr(long) mcr(LL) mcr(unsigned) mcr(unsigned long) mcr(unsigned LL)
#define ALL_FLT(mcr) mcr(float) mcr(double) mcr(long double)
#define S2D                                                                    \\
  x = 0;                                                                       \\
  int c = P();                                                                 \\
  while ((c < '0' || c > '9') && c != '-')                                     \\
    c = P();                                                                   \\
  bool h = false;                                                              \\
  if (c == '-')                                                                \\
  h = true, c = P()
#define R2D                                                                    \\
  for (; c >= '0' && c <= '9'; c = P())                                        \\
  x = x * 10 + c - '0'
#define R2F                                                                    \\
  if (c == '.') {                                                              \\
    double u = 0.1;                                                            \\
    for (c = P(); c >= '0' && c <= '9'; c = P(), u *= 0.1)                     \\
      x += u * (c - '0');                                                      \\
  }
#define RD_INT(Int)                                                            \\
  I Fr &OP, (Int & x) {                                                        \\
    S2D;                                                                       \\
    R2D;                                                                       \\
    if (h)                                                                     \\
      x = -x;                                                                  \\
    RT                                                                         \\
  }
#define RD_FLT(Flt)                                                            \\
  I Fr &OP, (Flt & x) {                                                        \\
    S2D;                                                                       \\
    R2D;                                                                       \\
    R2F;                                                                       \\
    if (h)                                                                     \\
      x = -x;                                                                  \\
    RT                                                                         \\
  }
struct Cg {
  I char OP()() {
    char c = (char)getchar();
    if (c == eof)
      valid = false;
    return c;
  };
  bool valid = true;
};
struct Cp {
  I void OP()(int x) { putchar(x); }
};
struct Ce {
  I void OP()(int x) { putc(x, stderr); }
};
I bool IS(char x) { return x == ' ' || x == '\\r' || x == '\\n' || x == '\\t'; }
template <class T> struct Fr {
  T P;
  ALL_INT(RD_INT) ALL_FLT(RD_FLT) I Fr &OP, (char &x) {
    for (x = P(); IS(x);)
      x = P();
    RT
  }
  I Fr &OP, (char *s) {
    for (*s = P(); IS(*s) && P.valid;)
      *s = P();
    for (; !IS(*s) && P.valid;)
      *++s = P();
    *s = 0;
    RT
  }
  I Fr &OP, (string & s) {
    s.clear();
    char c = P();
    for (; IS(c) && P.valid;)
      c = P();
    for (; !IS(c) && P.valid;)
      s.push_back(c), c = P();
    RT
  }
  I OP bool() { return P.valid; }
};
#define W4D                                                                    \\
  if (x) {                                                                     \\
    if (x < 0)                                                                 \\
      P('-'), x = -x;                                                          \\
    int p = 0;                                                                 \\
    while (x)                                                                  \\
      B[p++] = x % 10 + '0', x /= 10;                                          \\
    while (p--)                                                                \\
      P(B[p]);                                                                 \\
  } else                                                                       \\
    P('0')
#define WR_INT(Int)                                                            \\
  I Fw &OP, (Int x) {                                                          \\
    W4D;                                                                       \\
    RT                                                                         \\
  }
#define WR_FLT(Flt)                                                            \\
  I Fw &OP()(Flt g, int d) {                                                   \\
    if (d) {                                                                   \\
      double t = 0.5;                                                          \\
      for (int i = d; i--;)                                                    \\
        t *= 0.1;                                                              \\
      if (g < 0)                                                               \\
        P('-'), g = -g;                                                        \\
      g += t;                                                                  \\
      *this, (LL)(g);                                                          \\
      P('.');                                                                  \\
      g -= floor(g);                                                           \\
      while (d--) {                                                            \\
        g *= 10;                                                               \\
        int i = (int)floor(g);                                                 \\
        P(i + '0');                                                            \\
        g -= i;                                                                \\
      }                                                                        \\
    } else                                                                     \\
      *this, (g > 0 ? (LL)(g + 0.5) : (LL)(g - 0.5));                          \\
    RT                                                                         \\
  }
template <class T> struct Fw {
  T P;
  char B[32];
  ALL_INT(WR_INT) ALL_FLT(WR_FLT) I Fw &OP, (char x) {
    P(x);
    RT
  }
  typedef char_traits<char> CT;
  typedef basic_ostream<char, CT> &OS;
  typedef basic_istream<char, CT> &IS;
  I Fw &OP, (OS & (*func)(OS)) {
    if (func == static_cast<OS &(*)(OS)>(endl<char, CT>))
      P('\\n');
    RT
  }
  I Fw &OP, (IS & (*func)(IS)) {
    if (func == static_cast<IS &(*)(IS)>(ws<char, CT>))
      P(' ');
    RT
  }
  I Fw &OP, (const char *s) {
    for (; *s; ++s)
      P(*s);
    RT
  }
  I Fw &OP, (const string &s) {
    (*this), s.c_str();
    RT
  }
  template <class C> I Fw &all(const C &v, char sep = ' ', char nl = '\\n') {
    auto it = v.begin();
    for (int i = 0; i < (int)v.size(); ++i, ++it) {
      if (i && sep)
        P(sep);
      (*this), *it;
    }
    if (nl)
      P(nl);
    RT
  }
  template <class U> I Fw &print(U x) {
    (*this), x;
    P('\\n');
    RT
  }
  template <class U, class... Us> I Fw &print(U x, Us... args) {
    (*this), x;
    P(' ');
    print(args...);
    RT
  }
};
#undef LL
#undef I
#undef OP
#undef RT
#undef ALL_INT
#undef ALL_FLT
#undef S2D
#undef R2D
#undef R2F
#undef RD_INT
#undef RD_FLT
#undef W4D
#undef WR_INT
#undef WR_FLT
} // namespace fio
fio::Fr<fio::Cg> fin;
fio::Fw<fio::Cp> fout;
fio::Fw<fio::Ce> ferr;
#include <cstdint>
#include <utility>
static inline unsigned all_ones(unsigned x) {
  x |= (x >> 1);
  x |= (x >> 2);
  x |= (x >> 4);
  x |= (x >> 8);
  x |= (x >> 16);
  return x;
}
static inline int floor_log2(unsigned x) {
  int ans = 0;
  while (x >>= 1)
    ++ans;
  return ans;
}
static inline bool is_pow2(unsigned x) { return !(x & (x - 1)); }
static inline unsigned next_pow2(unsigned x) { return all_ones(x) + 1; }
static inline unsigned ceil_pow2(unsigned x) {
  if (is_pow2(x))
    return x;
  return next_pow2(x);
}
static inline int msb32(unsigned int x) {
  x = all_ones(x);
  return x & ~(x >> 1);
}
static inline int lsb32(unsigned int x) { return x & -x; }
#include <limits>
#include <type_traits>
#ifndef OJLIBS_USE_INT128
#define OJLIBS_USE_INT128 1
#endif
template <typename Int> Int gcd(Int a, Int b) {
  while (a != 0) {
    b %= a;
    if (b == 0)
      return a;
    a %= b;
  }
  return b;
}
template <typename Int, typename RInt = Int> Int lcm(Int a, Int b) {
  return a / gcd(a, b) * static_cast<RInt>(b);
}
template <typename Int, typename XInt>
Int extended_gcd(Int a, Int b, XInt &x, XInt &y) {
  static_assert(std::numeric_limits<XInt>::is_signed, "x, y must be signed");
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  /**
   * r = a - b * q
   * b * k1 + r * k2 = g
   * => a * k2 + b * (k1 - q * k2)
   *                 x = k2
   *                 y = k1 - q * k2 = k1 - q * x
   */
  Int g = extended_gcd(b, a % b, y, x);
  y -= (a / b) * x;
  return g;
}
template <typename Int> Int mul_mod(Int a, Int b, Int m) {
  typedef int64_t TInt;
  static_assert(2 * std::numeric_limits<Int>::digits <=
                    std::numeric_limits<TInt>::digits,
                "multiplication will overflow!");
  TInt p = a;
  p = (p * b) % m;
  return (Int)p;
}
#if defined(__SIZEOF_INT128__) && OJLIBS_USE_INT128
template <> int64_t mul_mod<int64_t>(int64_t a, int64_t b, int64_t m) {
  __int128_t p = __int128_t(a) * b;
  return (int64_t)(p % m);
}
#else
template <> int64_t mul_mod<int64_t>(int64_t a, int64_t b, int64_t m) {
  int64_t r = 0;
  for (int i = 63; i >= 0; --i) {
    r = (r + r) % m;
    if ((b >> i) & 1)
      r = (r + a) % m;
  }
  return r;
}
#endif
template <typename Int, typename PInt> Int pow_mod(Int a, PInt p, Int m) {
  Int r;
  a %= m;
  for (r = 1; p; p >>= 1) {
    if (p & 1)
      r = mul_mod(r, a, m);
    a = mul_mod(a, a, m);
  }
  return r;
}
template <typename Int, typename XInt = typename std::make_signed<Int>::type>
Int inv_mod(Int a, Int m) {
  XInt x, y;
  extended_gcd(a, m, x, y);
  if (x < 0)
    return x + m;
  return x;
}
template <typename Int> Int addx_mod(Int u, Int v, Int m) {
  Int r = u + v;
  if (r >= m)
    r -= m;
  return r;
}
template <typename Int> Int subx_mod(Int u, Int v, Int m) {
  Int r = u - v;
  if (r < 0)
    r += m;
  return r;
}
template <typename Int> Int div_mod(Int u, Int v, Int m) {
  Int g = gcd(v, m);
  assert(u % g == 0);
  Int mm = m / g;
  return mul_mod(u / g, inv_mod(v / g, mm), mm);
}
template <typename Int> Int div_pos_r(Int a, Int b, Int &r) {
  Int q = a / b;
  r = a % b;
  if (r < 0) {
    if (b < 0)
      q += 1, r -= b;
    else
      q -= 1, r += b;
  }
  return q;
}
template <typename Int> Int coprime_div(Int a, Int b) {
  while (b != 1) {
    while (a % b == 0)
      a /= b;
    b = gcd(a, b);
  }
  return a;
}
#define INV_MOD(x) inv_mod((x), MOD)
#define MUL_MOD(x, y) mul_mod((x), (y), MOD)
#define DIV_MOD(x, y) div_mod((x), (y), MOD)
#define MULM_MOD(x, y) (x) = mul_mod((x), (y), MOD)
#define DIVM_MOD(x, y) (x) = div_mod((x), (y), MOD)
#define POW_MOD(x, y) pow_mod((x), (y), MOD)
#define ADDX_MOD(x, y) addx_mod((x), (y), MOD)
#define ADDM_MOD(x, y) (x) = addx_mod((x), (y), MOD)
#define SUBX_MOD(x, y) subx_mod((x), (y), MOD)
#define SUBM_MOD(x, y) (x) = subx_mod((x), (y), MOD)
template <typename T> struct binary_plus {
  T identity() const { return T(); }
  T operator()(const T &t1, const T &t2) const { return t1 + t2; }
  T negate(const T &t) { return -t; }
};
template <typename T, T MOD> struct modular_plus {
  T identity() const { return T(); }
  T operator()(const T &t1, const T &t2) const { return (t1 + t2) % MOD; }
  T negate(const T &t) { return (MOD - t) % MOD; }
};
template <typename T, T MOD, typename TT = int64_t> struct modular_times {
  T identity() const { return 1; }
  T operator()(const T &t1, const T &t2) const { return mul_mod(t1, t2, MOD); }
  T negate(const T &t) { return inv_mod(t, MOD); }
};
template <typename T> struct binary_xor {
  T identity() const { return T(); }
  T operator()(const T &t1, const T &t2) const { return t1 ^ t2; }
  T negate(const T &t) { return t; }
};
template <typename T> struct binary_max {
  T identity() const { return std::numeric_limits<T>::min(); }
  T operator()(const T &t1, const T &t2) const { return std::max(t1, t2); }
};
template <typename T> struct binary_min {
  T identity() const { return std::numeric_limits<T>::max(); }
  T operator()(const T &t1, const T &t2) const { return std::min(t1, t2); }
};
#define COMMON_CODE                                                            \\
  Op op;                                                                       \\
  std::vector<T> vec;                                                          \\
  int size; /* size of last layer */                                           \\
  int offset;                                                                  \\
  segtree(int n) {                                                             \\
    size = n;                                                                  \\
    offset = ceil_pow2(n);                                                     \\
    vec.resize(size + offset + 1,                                              \\
               op.identity()); /* ensure every leaf has sibling */             \\
  }                                                                            \\
  T &operator[](int i) { return vec[offset + i]; }
template <typename T, typename Op = binary_plus<T>, bool flavour_one = true>
struct segtree;
template <typename T, typename Op> struct segtree<T, Op, true> {
  COMMON_CODE
  void rebuild() {
    for (int i = (offset + size - 1) / 2; i > 0; --i)
      vec[i] = op(vec[i + i], vec[i + i + 1]);
  }
  void increase_element(int p, const T &n) {
    for (p += offset; p; p >>= 1)
      vec[p] = op(n, vec[p]);
  }
  void update_element(int p, const T &n) {
    p += offset;
    vec[p] = n;
    while (p >>= 1)
      vec[p] = op(vec[p + p], vec[p + p + 1]);
  }
  T query_range(int s, int t) { return query_include(s, t - 1); }
  T query_include(int s, int t) {
    if (s > t)
      return op.identity();
    s += offset;
    t += offset;
    T left_acc = vec[s];
    if (s == t)
      return left_acc;
    T right_acc = vec[t];
    for (; s ^ t ^ 1; s >>= 1, t >>= 1) {
      if (~s & 1)
        left_acc = op(left_acc, vec[s ^ 1]);
      if (t & 1)
        right_acc = op(vec[t ^ 1], right_acc);
    }
    return op(left_acc, right_acc);
  }
};
template <typename T, typename Op> struct segtree<T, Op, false> {
  COMMON_CODE
  T query_element(int p) {
    T ret = op.identity();
    for (p += offset; p; p >>= 1)
      ret = op(vec[p], ret);
    return ret;
  }
  void increase_range(int s, int t, const T &inc) {
    return increase_include(s, t - 1, inc);
  }
  void increase_include(int s, int t, const T &inc) {
    if (s > t)
      return;
    s += offset;
    t += offset;
    vec[s] = op(inc, vec[s]);
    if (s == t)
      return;
    vec[t] = op(inc, vec[t]);
    for (; s ^ t ^ 1; s >>= 1, t >>= 1) {
      if (~s & 1)
        vec[s ^ 1] = op(inc, vec[s ^ 1]);
      if (t & 1)
        vec[t ^ 1] = op(inc, vec[t ^ 1]);
    }
    return;
  }
  void flatten() {
    for (int i = 1; i < offset; ++i) {
      if (i + i < offset + size) {
        vec[i + i] = op(vec[i], vec[i + i]);
        vec[i + i + 1] =
            op(vec[i], vec[i + i + 1]); // dummy sibling doesn't matter
      } else
        break;
      vec[i] = op.identity();
    }
  }
};
#undef COMMON_CODE
template <int32_t MOD> struct mod_int {
  mod_int() : v(0) {}
  mod_int(int32_t in) : v(in) { fixup(); }
  void fixup() {
    if (v < 0 || v >= MOD) {
      v = v % MOD;
      if (v < 0)
        v += MOD;
    }
  }
  explicit operator int() const { return v; }
#define MINT_OP_GEN(op_str, op_eq_str, op_arith, op_eq_arith)                  \\
  mod_int &operator op_eq_str(const mod_int &that) {                           \\
    op_eq_arith(v, that.v);                                                    \\
    return *this;                                                              \\
  }                                                                            \\
  mod_int operator op_str(const mod_int &that) const {                         \\
    return {op_arith(v, that.v)};                                              \\
  }
  MINT_OP_GEN(+, +=, ADDX_MOD, ADDM_MOD)
  MINT_OP_GEN(-, -=, SUBX_MOD, SUBM_MOD)
  MINT_OP_GEN(*, *=, MUL_MOD, MULM_MOD)
  MINT_OP_GEN(/, /=, DIV_MOD, DIVM_MOD)
#undef MINT_OP_GEN
  int32_t v;
};
/* =====  SOLUTION START  ===== */
constexpr int MOD = 998244353;
constexpr int maxn = 200005;
int dp[maxn];
int main() {
  int N, K;
  fin, N, K;
  vector<pii> intv;
  FOR0(i, K) {
    int L, R;
    fin, L, R;
    intv.push_back({L, R});
  }
  typedef mod_int<MOD> INT;
  segtree<INT> segtree(maxn);
  segtree.increase_element(1, 1);
  FOR(i, 2, N) {
    INT sum = 0;
    for (pii lr : intv) {
      int L = i - lr.second;
      int R = i - lr.first;
      if (R < 1)
        continue;
      chmax(L, 1);
      sum += segtree.query_include(L, R);
    }
    segtree.increase_element(i, sum);
  }
  fout, segtree.query_include(N, N).v, '\\n';
  return 0;
}


#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

int main() {
  long long N, K;
  long long l, r;
  long long m = 998244353;
  std::cin >> N >> K;
  vector<long long> kumiawase(N, 0);
  kumiawase[0] = 1;

  vector<long long> list(0);
  for (int i = 0; i < K; i++) {
    std::cin >> l >> r;
    for (long long j = l; j <= r; j++) {
      list.push_back(j);
    }
  }
  // for(int i = 0; i < list.size(); i++){
  //     std::cout << list[i] << " ";
  // }
  // std::cout << "\\n";
  // 動的計画法で解く。最悪NNになりそうだけど..

  for (long long i = 1; i < N; i++) {
    //    std::cout << i << "\\n";
    for (long long j = 0; j < list.size(); j++) {
      if (i - list[j] >= 0) {
        kumiawase[i] = kumiawase[i] + kumiawase[i - list[j]];
        kumiawase[i] = kumiawase[i] % m;
      }
    }
    //        std::cout << kumiawase[i] << " ";
  }

  std::cout << kumiawase[N - 1];
}

#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

int main() {
  long long N, K;
  long long l, r;
  long long ans;
  long long m = 998244353;
  std::cin >> N >> K;
  vector<vector<long long>> kumiawase(K + 1, vector<long long>(N, 0));
  kumiawase[0][0] = 1;
  vector<long long> n_k_list(K, 0);

  vector<vector<long long>> list;
  for (int i = 0; i < K; i++) {
    std::cin >> l >> r;
    list.push_back({l, r});
    n_k_list[i] = r - l + 1; // 各連続区間の数
  }

  // for(int i = 0; i < list.size(); i++){
  //     std::cout << list[i] << " ";
  // }
  // std::cout << "\\n";
  // 動的計画法で解く。最悪NNになりそうだけど..
  // NNになった。。
  // Kこのグループごとに行を設ける。

  for (long long i = 1; i < N; i++) {
    //    std::cout << i << "\\n";
    for (long long j = 0; j < K; j++) {
      // Kごとにループを回す。
      // iよりうしろのn_kこの数の合計を出す。
      if (i <= n_k_list[j]) {
        kumiawase[j + 1][i] = kumiawase[0][i - 1] + kumiawase[j + 1][i - 1];
        kumiawase[j + 1][i] = kumiawase[j + 1][i] % m;
      } else {
        kumiawase[j + 1][i] = kumiawase[0][i - 1] + kumiawase[j + 1][i - 1] -
                              kumiawase[0][i - n_k_list[j] - 1];
        kumiawase[j + 1][i] = kumiawase[j + 1][i] % m;
      }
      // 列埋め完了
      // 最後に0行目を算出する。
      if (i - list[j][0] >= 0) {
        // レフト前のインデックスが欄外じゃなければそのいっこ右の値を足す。
        kumiawase[0][i] =
            kumiawase[0][i] + kumiawase[j + 1][i - list[j][0] + 1];
        kumiawase[0][i] = kumiawase[0][i] % m;
      } else {
      }
    }
    //        std::cout << kumiawase[i] << " ";
  }

  if (kumiawase[0][N - 1] < 0) {
    ans = kumiawase[0][N - 1] + m;
  } else {
    ans = kumiawase[0][N - 1];
  }

  std::cout << ans << "\\n";

  // for(int j = 0; j < K + 1; j++){
  //     for(int i = 0; i < 6; i++){
  //         std::cout << kumiawase[j][i] << " ";
  //     }
  //     std::cout << "\\n";
  // }
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
const ll INF = 1e9;
const ll MOD = 998244353;
#define rep1(i, n) for (ll i = 0; i < (n); i++)
#define rep2(i, k, n) for (ll i = k; i < (n); i++)
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;
}

int main() {
  ll n, k;
  cin >> n >> k;
  map<ll, ll> m;
  vector<ll> d;
  rep1(i, k) {
    ll l, r;
    cin >> l >> r;
    for (ll i = l; i < (r + 1); i++)
      m[i]++;
  }
  for (auto x : m)
    d.push_back(x.first);
  vector<ll> dp(3 * n, 0);
  dp[1] = 1;
  for (ll i = 1; i < (n); i++) {
    for (ll j = 0; j < (d.size()); j++) {
      dp[i + d[j]] += dp[i];
      dp[i + d[j]] %= MOD;
    }
  }
  cout << dp[n] << endl;
  // printf("%.12f", ans);
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
const ll INF = 1e9;
const ll MOD = 998244353;
#define rep1(i, n) for (ll i = 0; i < (n); i++)
#define rep2(i, k, n) for (ll i = k; i < (n); i++)
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;
}

int main() {
  ll n, k;
  cin >> n >> k;
  vector<ll> dp(n + 1, 0), sum(n + 1, 0), l(k), r(k);
  rep1(i, k) cin >> r[i] >> l[i];
  rep2(i, 1, n + 1) {
    if (i == 1) {
      sum[i] = 1;
      continue;
    }
    rep1(j, k) {
      if (i - r[j] > 0) {
        if (i - l[j] > 0)
          dp[i] += (sum[i - r[j]] - sum[i - l[j] - 1] % MOD + MOD) % MOD;
        else
          dp[i] += sum[i - r[j]];
      }
    }
    dp[i] %= MOD;
    sum[i] = (sum[i - 1] + dp[i]) % MOD;
  }
  cout << dp[n] << endl;
  // printf("%.12f", ans);
}


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

#define MOD 998244353LL

using namespace std;

int main() {
  int N, K;
  cin >> N >> K;

  vector<pair<long long, long long>> d(K);
  for (int i = 0; i < K; ++i) {
    cin >> d[i].first >> d[i].second;
  }

  vector<long long> dp(N, 0);
  dp[0] = 1;
  for (int i = 1; i < N; ++i) {
    for (int j = 0; j < K; ++j) {
      for (int k = d[j].first; k <= d[j].second && i - k >= 0; ++k) {
        dp[i] += dp[i - k];
        dp[i] %= MOD;
      }
    }
  }
  cout << dp[N - 1] << endl;
  return 0;
}

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

#define MOD 998244353LL

using namespace std;

int main() {
  int N, K;
  cin >> N >> K;

  vector<pair<long long, long long>> d(K);
  for (int i = 0; i < K; ++i) {
    cin >> d[i].first >> d[i].second;
  }

  vector<long long> dp(N, 0);
  vector<long long> dp_sum(N, 0);
  dp[0] = 1;
  dp_sum[0] = 1;
  for (int i = 1; i < N; ++i) {
    for (int j = 0; j < K; ++j) {
      if (i - d[j].second <= 0 && i - d[j].first >= 0) {
        dp[i] += dp_sum[i - d[j].first];
      } else if (i - d[j].second > 0) {
        dp[i] += (dp_sum[i - d[j].first] - dp_sum[i - d[j].second - 1]);
      }
      dp[i] %= MOD;
    }
    dp_sum[i] = dp_sum[i - 1] + dp[i];
  }
  cout << dp[N - 1] << endl;
  return 0;
}


#include <algorithm>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define FOR(i, a, b) for (int i = a; i < (b); i++)
#define range(a) a.begin(), a.end()
#define endl "\\n"
#define Yes() cout << "Yes" << endl
#define No() cout << "No" << endl
#define MP make_pair
using Graph = vector<vector<int>>;
const ll mod = 998244353;
const long long INF = 1LL << 60;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
void chmin(long long &a, long long b) {
  if (a > b)
    a = b;
}
void chmax(long long &a, long long b) {
  if (a < b)
    a = b;
}

// 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(void) {
  ios::sync_with_stdio(0);
  cin.tie(0);
  mint dp[200005] = {};
  dp[0] = 1;
  int N, K;
  cin >> N >> K;
  vector<pair<int, int>> data;
  while (K--) {
    int L, R;
    cin >> L >> R;
    data.push_back(MP(L, R));
  }

  FOR(i, 0, N) {
    FOR(j, 0, data.size()) {
      int f = data.at(j).first, s = data.at(j).second;
      FOR(k, f, s + 1) {
        if (i + k <= N) {
          dp[i + k] += dp[i];
        }
      }
    }
  }

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

  return 0;
}

#include <algorithm>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define FOR(i, a, b) for (int i = a; i < (b); i++)
#define range(a) a.begin(), a.end()
#define endl "\\n"
#define Yes() cout << "Yes" << endl
#define No() cout << "No" << endl
#define MP make_pair
using Graph = vector<vector<int>>;
const ll mod = 998244353;
const long long INF = 1LL << 60;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
void chmin(long long &a, long long b) {
  if (a > b)
    a = b;
}
void chmax(long long &a, long long b) {
  if (a < b)
    a = b;
}

// 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(void) {
  ios::sync_with_stdio(0);
  cin.tie(0);
  mint dp[200005] = {};
  mint dpsum[200005] = {};
  dp[0] = 1;
  dpsum[0] = 1;
  int N, K;
  cin >> N >> K;
  vector<pair<int, int>> data;
  while (K--) {
    int L, R;
    cin >> L >> R;
    data.push_back(MP(L, R));
  }

  FOR(i, 1, N) {
    FOR(j, 0, data.size()) {
      int r = i - data.at(j).first, l = i - data.at(j).second - 1;
      if (r < 0)
        continue;
      if (l < 0)
        dp[i] += dpsum[r];
      else
        dp[i] += dpsum[r] - dpsum[l];
    }
    dpsum[i] = dpsum[i - 1] + dp[i];
  }

  // FOR(i,0,N)	cout << i << " " << dp[i] << endl;
  cout << dp[N - 1] << endl;

  return 0;
}


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

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vvvi = vector<vector<vector<int>>>;
using vl = vector<ll>;
using vvl = vector<vector<ll>>;
using vvvl = vector<vector<vector<ll>>>;
using vs = vector<string>;
using vb = vector<bool>;
#define FOR(i, m, n) for (int i = (m); i < (n); i++)
#define FORR(i, m, n) for (int i = (m); i >= (n); i--)
#define REP(i, n) FOR(i, 0, (n))
#define REPR(i, n) FORR(i, (n)-1, 0)
#define REP1(i, n) FOR(i, 1, (n) + 1)
#define REPS(c, s) for (char c : s)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define REV(c) reverse(ALL(c))
#define sz(v) (int)v.size()
#define endl '\\n'
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;
}
template <class T> inline void prn(vector<T> &v) {
  int n = sz(v);
  REP(i, n) cout << v[i] << ' ';
}
template <class T> inline void printv(vector<T> &v) {
  int n = sz(v);
  REP(i, n) cout << v[i] << (i == n - 1 ? endl : ' ');
}
template <class T> inline void printvv(vector<vector<T>> &v) {
  for (auto u : v)
    printv(u);
}
template <class T> inline void printlnv(vector<T> &v) {
  int n = sz(v);
  REP(i, n) cout << v[i] << endl;
}
const int MOD = 1000000007;
const int INF = 1000000001;
const ll LINF = 1000000001000000001LL;

void solve();

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << fixed << setprecision(numeric_limits<double>::max_digits10);
  solve();
  return 0;
}

void solve() {
  int n, k;
  cin >> n >> k;
  set<int> x;
  REP(i, k) {
    int l, r;
    cin >> l >> r;
    for (int i = l; i <= r; i++) {
      x.emplace(i);
    }
  }
  vi dp(n + 1, 0);
  dp[1] = 1;
  for (int i = 2; i <= n; i++) {
    for (auto v : x) {
      if (i - v < 1)
        break;
      dp[i] += dp[i - v];
      dp[i] %= 998244353;
    }
  }
  cout << dp[n] << endl;
}

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

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vvvi = vector<vector<vector<int>>>;
using vl = vector<ll>;
using vvl = vector<vector<ll>>;
using vvvl = vector<vector<vector<ll>>>;
using vs = vector<string>;
using vb = vector<bool>;
#define FOR(i, m, n) for (int i = (m); i < (n); i++)
#define FORR(i, m, n) for (int i = (m); i >= (n); i--)
#define REP(i, n) FOR(i, 0, (n))
#define REPR(i, n) FORR(i, (n)-1, 0)
#define REP1(i, n) FOR(i, 1, (n) + 1)
#define REPS(c, s) for (char c : s)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define REV(c) reverse(ALL(c))
#define sz(v) (int)v.size()
#define endl '\\n'
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;
}
template <class T> inline void prn(vector<T> &v) {
  int n = sz(v);
  REP(i, n) cout << v[i] << ' ';
}
template <class T> inline void printv(vector<T> &v) {
  int n = sz(v);
  REP(i, n) cout << v[i] << (i == n - 1 ? endl : ' ');
}
template <class T> inline void printvv(vector<vector<T>> &v) {
  for (auto u : v)
    printv(u);
}
template <class T> inline void printlnv(vector<T> &v) {
  int n = sz(v);
  REP(i, n) cout << v[i] << endl;
}
const int MOD = 1000000007;
const int INF = 1000000001;
const ll LINF = 1000000001000000001LL;

void solve();

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << fixed << setprecision(numeric_limits<double>::max_digits10);
  solve();
  return 0;
}

void solve() {
  int n, k;
  cin >> n >> k;
  vi l(k);
  vi r(k);
  REP(i, k) cin >> l[i] >> r[i];
  vi dp(n + 1, 0);
  dp[1] = 1;
  dp[2] = -1;
  REP1(i, n) {
    dp[i] += dp[i - 1];
    dp[i] %= 998244353;
    REP(j, k) {
      if (i + l[j] <= n) {
        dp[i + l[j]] += dp[i];
        dp[i + l[j]] %= 998244353;
      }
      if (i + r[j] + 1 <= n) {
        dp[i + r[j] + 1] -= dp[i];
        dp[i + r[j] + 1] += 998244353;
        dp[i + r[j] + 1] %= 998244353;
      }
    }
  }
  cout << dp[n] << endl;
}


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

inline int read() {
  int s = 0, w = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      w = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    s = s * 10 + ch - '0', ch = getchar();
  return s * w;
}

inline bool read(int &a) {
  int s = 0, w = 1;
  char ch = getchar();
  if (ch == EOF) {
    return false;
  }
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      w = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    s = s * 10 + ch - '0', ch = getchar();
  a = s * w;
  return true;
}

inline void write(int x) {
  if (x < 0)
    putchar('-'), x = -x;
  if (x > 9)
    write(x / 10);
  putchar(x % 10 + '0');
}

inline void writeln(int x) {
  if (x < 0)
    putchar('-'), x = -x;
  if (x > 9)
    write(x / 10);
  putchar(x % 10 + '0');
  puts("");
}

const int mod = 998244353;

int l[20], r[20];
set<int> s;
int b[200010];

int dp[200010];

int a[200010];

signed main() {
  int n, k;
  read(n), read(k);

  for (int i = 1; i <= k; i++) {
    read(l[i]), read(r[i]);
    for (int j = l[i]; j <= r[i]; j++)
      b[j] = 1;
  }

  int cnt = 0;

  for (int i = 1; i <= n; i++)
    if (b[i] == 1)
      a[++cnt] = i;

  dp[1] = 1;

  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= cnt; j++) {
      if (dp[i - a[j]] > 0 && i - a[j] >= 0)
        dp[i] = (dp[i] + dp[i - a[j]]) % mod;
      if (i - a[j] < 0)
        break;
    }
  }

  writeln(dp[n]);
  return 0;
}


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

int main() {
  int N, K;
  cin >> N >> K;
  vector<int> L(K), R(K);
  rep(i, 0, K) cin >> L[i] >> R[i];
  vector<ll> dp(N + 1, 0);
  dp[0] = 1;
  dp[1] = -1;
  rep(i, 0, N) {
    dp[i] = ((dp[i] % MOD) + MOD) % MOD;
    dp[i + 1] = (dp[i + 1] + dp[i]) % MOD;
    rep(j, 0, K) {
      dp[i + L[j]] += dp[i];
      dp[i + R[j] + 1] -= dp[i];
    }
  }
  cout << dp[N - 1] << endl;
}

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

int main() {
  int N, K;
  cin >> N >> K;
  vector<int> L(K), R(K);
  rep(i, 0, K) cin >> L[i] >> R[i];
  vector<ll> dp(N + 1, 0);
  dp[0] = 1;
  dp[1] = -1;
  rep(i, 0, N) {
    dp[i] = ((dp[i] % MOD) + MOD) % MOD;
    dp[i + 1] = (dp[i + 1] + dp[i]) % MOD;
    rep(j, 0, K) {
      if (i + L[j] < N)
        dp[i + L[j]] += dp[i];
      if (i + R[j] + 1 < N)
        dp[i + R[j] + 1] -= dp[i];
    }
  }
  cout << dp[N - 1] << endl;
}


#include <bits/stdc++.h>
#define ff first
#define ss second
#define ll long long
#define ld long double
#define pb push_back
#define eb emplace_back
#define pii pair<int, int>
#define vi vector<int>
#define vl vector<ll>
#define vii vector<pii>
#define sws                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define endl '\\n'
#define teto(a, b) (((a) + (b)-1) / (b))
#define all(x) x.begin(), x.end()
#define forn(i, n) for (int i = 0; i < (int)n; i++)
#define forne(i, a, b) for (int i = a; i <= b; i++)
#define dbg(msg, var) cerr << msg << " " << var << endl;

using namespace std;

const int MAX = 100010;
const ll MOD = 998244353;
const int INF = 0x3f3f3f3f;
const ll LLINF = 0x3f3f3f3f3f3f3f3f;
const ld EPS = 1e-7;

const int LOG = ceil(log2(MAX));

// End Template //

namespace seg {
ll seg[2 * MAX], lazy[2 * MAX];
int n;

ll junta(ll a, ll b) { return (a + b) % MOD; }

// soma x na posicao p de tamanho tam
void poe(int p, ll x, int tam, bool prop = 1) {
  seg[p] += x * tam;
  seg[p] %= MOD;
  if (prop and p < n)
    lazy[p] += x;
}

// atualiza todos os pais da folha p
void sobe(int p) {
  for (int tam = 2; p /= 2; tam *= 2) {
    seg[p] = junta(seg[2 * p], seg[2 * p + 1]);
    poe(p, lazy[p], tam, 0);
  }
}

// propaga o caminho da raiz ate a folha p
void prop(int p) {
  int tam = 1 << (LOG - 1);
  for (int s = LOG; s; s--, tam /= 2) {
    int i = p >> s;
    if (lazy[i]) {
      poe(2 * i, lazy[i], tam);
      poe(2 * i + 1, lazy[i], tam);
      lazy[i] = 0;
    }
  }
}

void build(int n2) {
  n = n2;
  for (int i = n - 1; i; i--)
    seg[i] = junta(seg[2 * i], seg[2 * i + 1]);
  for (int i = 0; i < 2 * n; i++)
    lazy[i] = 0;
}

ll query(int a, int b) {
  ll ret = 0;
  for (prop(a += n), prop(b += n); a <= b; ++a /= 2, --b /= 2) {
    if (a % 2 == 1)
      ret = junta(ret, seg[a]);
    if (b % 2 == 0)
      ret = junta(ret, seg[b]);
  }
  return ret;
}

void update(int a, int b, int x) {
  int a2 = a += n, b2 = b += n, tam = 1;
  for (; a <= b; ++a /= 2, --b /= 2, tam *= 2) {
    if (a % 2 == 1)
      poe(a, x, tam);
    if (b % 2 == 0)
      poe(b, x, tam);
  }
  sobe(a2), sobe(b2);
}
}; // namespace seg

int main() {
  sws;

  int n, k, l, r;
  cin >> n >> k;
  vii S;

  seg::build(n + 10);
  seg::update(1, 1, 1);
  for (int i = 0; i < k; i++) {
    cin >> l >> r;
    S.pb({l, r});
  }

  for (int i = 1; i <= n; i++) {
    ll val = seg::query(i, i);
    // cout << "i, val = " << i << " " << val << endl;
    for (auto s : S)
      seg::update(min(i + s.ff, n + 1), min(i + s.ss, n + 1), val);
  }

  cout << seg::query(n, n) << endl;

  return 0;
}

#include <bits/stdc++.h>
#define ff first
#define ss second
#define ll long long
#define ld long double
#define pb push_back
#define eb emplace_back
#define pii pair<int, int>
#define vi vector<int>
#define vl vector<ll>
#define vii vector<pii>
#define sws                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define endl '\\n'
#define teto(a, b) (((a) + (b)-1) / (b))
#define all(x) x.begin(), x.end()
#define forn(i, n) for (int i = 0; i < (int)n; i++)
#define forne(i, a, b) for (int i = a; i <= b; i++)
#define dbg(msg, var) cerr << msg << " " << var << endl;

using namespace std;

const int MAX = 200010;
const ll MOD = 998244353;
const int INF = 0x3f3f3f3f;
const ll LLINF = 0x3f3f3f3f3f3f3f3f;
const ld EPS = 1e-7;

const int LOG = ceil(log2(MAX));

// End Template //

namespace seg {
ll seg[2 * MAX], lazy[2 * MAX];
int n;

ll junta(ll a, ll b) { return (a + b) % MOD; }

// soma x na posicao p de tamanho tam
void poe(int p, ll x, int tam, bool prop = 1) {
  seg[p] += x * tam;
  seg[p] %= MOD;
  if (prop and p < n)
    lazy[p] += x;
}

// atualiza todos os pais da folha p
void sobe(int p) {
  for (int tam = 2; p /= 2; tam *= 2) {
    seg[p] = junta(seg[2 * p], seg[2 * p + 1]);
    poe(p, lazy[p], tam, 0);
  }
}

// propaga o caminho da raiz ate a folha p
void prop(int p) {
  int tam = 1 << (LOG - 1);
  for (int s = LOG; s; s--, tam /= 2) {
    int i = p >> s;
    if (lazy[i]) {
      poe(2 * i, lazy[i], tam);
      poe(2 * i + 1, lazy[i], tam);
      lazy[i] = 0;
    }
  }
}

void build(int n2) {
  n = n2;
  for (int i = n - 1; i; i--)
    seg[i] = junta(seg[2 * i], seg[2 * i + 1]);
  for (int i = 0; i < 2 * n; i++)
    lazy[i] = 0;
}

ll query(int a, int b) {
  ll ret = 0;
  for (prop(a += n), prop(b += n); a <= b; ++a /= 2, --b /= 2) {
    if (a % 2 == 1)
      ret = junta(ret, seg[a]);
    if (b % 2 == 0)
      ret = junta(ret, seg[b]);
  }
  return ret;
}

void update(int a, int b, int x) {
  int a2 = a += n, b2 = b += n, tam = 1;
  for (; a <= b; ++a /= 2, --b /= 2, tam *= 2) {
    if (a % 2 == 1)
      poe(a, x, tam);
    if (b % 2 == 0)
      poe(b, x, tam);
  }
  sobe(a2), sobe(b2);
}
}; // namespace seg

int main() {
  sws;

  int n, k, l, r;
  cin >> n >> k;
  vii S;

  seg::build(n + 10);
  seg::update(1, 1, 1);
  for (int i = 0; i < k; i++) {
    cin >> l >> r;
    S.pb({l, r});
  }

  for (int i = 1; i <= n; i++) {
    ll val = seg::query(i, i);
    // cout << "i, val = " << i << " " << val << endl;
    for (auto s : S)
      seg::update(min(i + s.ff, n + 1), min(i + s.ss, n + 1), val);
  }

  cout << seg::query(n, n) << endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef std::pair<int, int> pair2;
typedef std::pair<int, pair2> pair3;
const ll INF = 1LL << 60;
const ll NUM = 10e8 + 7;

int main() {
  ll N, K;
  cin >> N >> K;
  ll L[K], R[K];
  for (ll i = 0; i < K; i++) {
    cin >> L[i] >> R[i];
  }

  vector<ll> dp(N + 1, 0);
  dp[1] = 1;

  for (ll i = 1; i < N; i++) {            // dpの数
    for (ll j = 0; j < K; j++) {          // L[j],K[j]を使用
      for (ll m = L[j]; m <= R[j]; m++) { // lが飛べる数
        if (i + m <= N) {
          dp[i + m] = dp[i + m] + dp[i];
          dp[i + m] = dp[i + m] % 998244353;
        }
      }
    }
  }

  cout << dp[N] << endl;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef std::pair<int, int> pair2;
typedef std::pair<int, pair2> pair3;
const ll INF = 1LL << 60;
const ll NUM = 10e8 + 7;

int main() {
  ll N, K;
  cin >> N >> K;
  ll L[K], R[K];
  for (ll i = 0; i < K; i++) {
    cin >> L[i] >> R[i];
  }
  vector<ll> dp(N + 2, 0);
  vector<ll> sumdp(N + 2, 0);
  dp[0] = 0;
  dp[1] = 1;
  sumdp[0] = 0;
  sumdp[1] = 1;
  for (ll i = 1; i < N + 1; i++) {

    for (ll j = 0; j < K; j++) {
      dp[i] = dp[i] % 998244353;
      // cout<<i<<endl;
      if (i - L[j] <= 0) {
        continue;
      }
      if (i - R[j] - 1 <= 0) {
        dp[i] = dp[i] + (sumdp[i - L[j]] - sumdp[0]);
        // cout<<i<<" "<<dp[i]<<endl;
        continue;
      }
      dp[i] = dp[i] + (sumdp[i - L[j]] - sumdp[i - R[j] - 1]);
      //      if(i+L[i]<=N)dp[i+L[j]]=dp[i+L[j]]+dp[i];
      //      if(i+R[i]<=N)dp[i+R[j]+1]=dp[i+R[j]+1]-dp[i];
    }
    dp[i] = dp[i] % 998244353;
    if (dp[i] < 0)
      dp[i] = dp[i] + 998244353;
    sumdp[i] = sumdp[i - 1] + dp[i];
    sumdp[i] = sumdp[i] % 998244353;
  }

  // for(ll i=1;i<N+1;i++)
  // cout<<dp[i]<<" "<<sumdp[i]<<endl;
  cout << dp[N] << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define _GLIBCXX_DEBUG
#define rep(i, from, to) for (ll i = from; i < (to); ++i)
#define mp(x, y) make_pair(x, y)
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
#define pb push_back
using ll = long long;
using ld = long double;
using vin = vector<int>;
using vvin = vector<vin>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vst = vector<string>;
using P = pair<ll, ll>;
const int inf = 998244353;
const ll INF = 9e18;
const long double PI = acos(-1.0);
template <typename T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline void Yes(T condition) {
  if (condition)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
}
template <class T> inline void YES(T condition) {
  if (condition)
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
}
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

ll dp[220000];

int main() {
  cout << fixed << setprecision(20);
  ll n, k;
  cin >> n >> k;
  vll l(k), r(k);
  rep(i, 0, k) cin >> l[i] >> r[i];
  // dp,imos
  dp[1] = 1;
  dp[2] = -1;
  rep(i, 1, n + 1) {
    dp[i] = (dp[i] + dp[i - 1]) % inf;
    rep(j, 0, k) {
      dp[i + l[j]] = (dp[i + l[j]] + dp[i]) % inf;
      dp[i + r[j] + 1] = (dp[i + r[j] + 1] - dp[i]) % inf;
    }
  }
  if (dp[n] < 0)
    dp[n] += inf;
  cout << dp[n] << endl;
}

#include <bits/stdc++.h>
using namespace std;
#define _GLIBCXX_DEBUG
#define rep(i, from, to) for (ll i = from; i < (to); ++i)
#define mp(x, y) make_pair(x, y)
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
#define pb push_back
using ll = long long;
using ld = long double;
using vin = vector<int>;
using vvin = vector<vin>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vst = vector<string>;
using P = pair<ll, ll>;
const int inf = 998244353;
const ll INF = 9e18;
const long double PI = acos(-1.0);
template <typename T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline void Yes(T condition) {
  if (condition)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
}
template <class T> inline void YES(T condition) {
  if (condition)
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
}
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

ll dp[220000];

int main() {
  cout << fixed << setprecision(20);
  ll n, k;
  cin >> n >> k;
  vll l(k), r(k);
  rep(i, 0, k) cin >> l[i] >> r[i];
  // dp,imos
  dp[1] = 1;
  dp[2] = -1;
  rep(i, 1, n + 1) {
    dp[i] = (dp[i] + dp[i - 1]) % inf;
    rep(j, 0, k) {
      if (i + l[j] < n + 2)
        dp[i + l[j]] = (dp[i + l[j]] + dp[i]) % inf;
      if (i + r[j] + 1 < n + 2)
        dp[i + r[j] + 1] = (dp[i + r[j] + 1] - dp[i]) % inf;
    }
  }
  if (dp[n] < 0)
    dp[n] += inf;
  cout << dp[n] << endl;
}


// بساملہ ہیر رحمن نیر رحیم
//---------------------------//
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include <algorithm>
#include <bitset>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// #define PBDS tree<long long int,null_type,less<long long int>,
// rb_tree_tag,tree_order_statistics_node_update> using namespace __gnu_pbds;
#define arrsize 100001
#define dpsize 1001
#define vpp vector<PP>
#define vll vector<ll>
#define vcc vector<char>
#define endl "\\n"
#define vbb vector<bool>
#define w(t) while (t--)
#define PP pair<ll, ll>
#define test(x)                                                                \\
  ll t;                                                                        \\
  cin >> t;                                                                    \\
  w(t) x()
#define __lb lower_bound
#define __ub upper_bound
#define szs(x) x.length()
#define szv(x) x.size()
#define INF 1999999996000000010
#define ll long long int
#define takeINP(arr, n)                                                        \\
  for (long long int i = 0; i < n; i++)                                        \\
    cin >> arr[i];
#define f(i, s, e) for (long long int i = s; i < e; i++)
#define cf(i, s, e) for (long long int i = s; i <= e; i++)
#define rf(i, e, s) for (long long int i = e - 1; i >= s; i--)
#define mem(arr) memset(arr, 0, sizeof(arr));
#define MOD 998244353
#define rsz(x, n) x.resize(n)
#define rsr(x, n) x.reserve(n)
#define mp(a, b) make_pair(a, b)
#define pb push_back
#define print(arr, s, e)                                                       \\
  f(i, s, e) cout << arr[i] << " ";                                            \\
  cout << endl;
#define all(v) v.begin(), v.end()
#define ff first
#define ss second
#define vll vector<ll>
#define triplet pair<ll, pair<ll, ll>>
#define MITR(a, b) map<a, b>::reverse_iterator
using namespace std;
using namespace chrono;

///---------------Functions---------------------///
ll advceil(ll num, ll den) {
  return (num % den == 0 ? num / den : num / den + 1);
}
ll lstbt(ll val) {
  ll msk = val & (val - 1);
  return log2(val ^ msk);
}
ll modexpo(ll a, ll b) {
  ll res = 1;
  while (b > 0) {
    if (b & 1)
      res = (res % MOD * a % MOD) % MOD;
    a = (a % MOD * a % MOD);
    b /= 2;
  }
  return res;
}
ll expo(ll a, ll b) {
  ll res = 1;
  while (b > 0) {
    if (b & 1)
      res = (res * a);
    a = (a * a);
    b /= 2;
  }
  return res;
}
ll gcd(ll a, ll b) { return a == 0 ? b : gcd(b % a, a); }
vll CALCfactor(ll n) {
  vll factor(n + 2, 0);
  for (ll i = 4; i <= n; i += 2)
    factor[i] = 2;
  for (ll j = 3; j <= n; j += 2) {
    if (factor[j])
      continue;
    for (ll i = 2 * j; i <= n; i += j)
      factor[i] = j;
  }
  return factor;
}
vll CALCprimeNUM(ll n) {
  vll factor = CALCfactor(n);
  vll primeNUM;
  primeNUM.reserve(n + 2);
  cf(i, 2, n) if (!factor[i]) primeNUM.pb(i);
  return primeNUM;
}
vll CALCprimeFACTOR(ll n) {
  vll factor = CALCfactor(n);
  vll ans;
  while (factor[n] != 0) {
    ans.pb(factor[n]);
    n /= factor[n];
  }
  ans.pb(n);
  return ans;
}
vll unique(vll x) {
  sort(all(x));
  set<ll> s;
  vll ans;
  ans.reserve(szv(x));
  for (auto elem : x)
    s.insert(elem);
  for (auto elem : s)
    ans.pb(elem);
  return ans;
}
vll ZALGO(string s, string pat) {
  ll lens = szs(pat);
  pat += char(36);
  pat += s;
  s = pat;
  vll pref(szs(s) + 1, 0);
  pref[0] = szs(s);
  ll spt = -1;
  ll ept = -1;
  ll processCnt = 0;
  for (ll i = 1; i < szs(s); i++) {
    bool isdone = false;
    if (i <= ept and i >= spt) {
      if (pref[i - spt] + i <= ept)
        pref[i] = pref[i - spt], isdone = true;
      processCnt++;
    }
    if (!isdone) {
      ll ptr = i;
      ll lo = 0;
      while (s[lo] == s[ptr])
        ptr++, lo++, processCnt++;
      if (ept < ptr - 1) {
        spt = i;
        ept = ptr - 1;
      }
      pref[i] = lo;
    }
  }
  vll ans;
  ans.reserve(szs(s) - lens);
  for (ll i = lens + 1; i < szs(s); i++)
    ans.pb(pref[i]);
  return ans;
}
void spclSort(vector<pair<pair<ll, ll>, ll>> &v) {
  ll n = szv(v);
  {
    vll cnt(n);
    for (auto elem : v) {
      cnt[elem.ff.ss]++;
    }
    vector<pair<pair<ll, ll>, ll>> a_new(n);
    vll pos(szv(cnt));
    pos[0] = 0;
    for (ll i = 1; i < szv(cnt); i++) {
      pos[i] = cnt[i - 1] + pos[i - 1];
    }
    for (auto elem : v) {
      a_new[pos[elem.ff.ss]] = elem;
      pos[elem.ff.ss]++;
    }
    v = a_new;
  }
  {
    vll cnt(n, 0);
    for (auto elem : v) {
      cnt[elem.ff.ff]++;
    }
    vector<pair<pair<ll, ll>, ll>> a_new(n);
    vll pos(szv(cnt));
    pos[0] = 0;
    for (ll i = 1; i < szv(cnt); i++) {
      pos[i] = cnt[i - 1] + pos[i - 1];
    }
    for (auto elem : v) {
      a_new[pos[elem.ff.ff]] = elem;
      pos[elem.ff.ff]++;
    }
    v = a_new;
  }
}
pair<vector<vll>, vector<vll>> getOrdering(string s) {
  s += char(36);
  vector<vll> dp;
  dp.reserve(log2(szs(s)) + 3);
  vector<vll> dp2;
  dp2.reserve(log2(szs(s)) + 3);
  vll ordering(szs(s)), eqClass(szs(s));
  {
    vector<pair<char, ll>> temp(szs(s));
    f(i, 0, szs(s)) temp[i] = {s[i], i};
    sort(all(temp));
    f(i, 0, szv(temp)) ordering[temp[i].ss] = i;
    eqClass[temp[0].ss] = 0;
    f(i, 1, szv(temp)) {
      if (temp[i].ff != temp[i - 1].ff)
        eqClass[temp[i].ss] = eqClass[temp[i - 1].ss] + 1;
      else
        eqClass[temp[i].ss] = eqClass[temp[i - 1].ss];
    }
    dp.pb(ordering);
    dp2.pb(eqClass);
  }
  ll k = 1;
  while ((1 << (k - 1)) < szs(s)) {
    vector<pair<pair<ll, ll>, ll>> arr(szs(s));
    for (ll i = 0; i < szs(s); i++) {
      arr[i] = {{eqClass[i], eqClass[(i + (1 << (k - 1))) % szs(s)]}, i};
    }
    spclSort(arr);
    f(i, 0, szs(s)) ordering[arr[i].ss] = i;
    eqClass[arr[0].ss] = 0;
    f(i, 1, szv(s)) {
      if (arr[i].ff != arr[i - 1].ff)
        eqClass[arr[i].ss] = eqClass[arr[i - 1].ss] + 1;
      else
        eqClass[arr[i].ss] = eqClass[arr[i - 1].ss];
    }
    dp.pb(ordering);
    dp2.pb(eqClass);
    k++;
  }
  return {dp, dp2};
}
vll sortOrdering(vector<vll> dp) {
  vll arr = dp[szv(dp) - 1];
  vll ans(szv(arr));
  ll cnt = 0;
  for (auto elem : arr) {
    ans[elem] = cnt;
    cnt++;
  }
  return ans;
}
vll getLps(string pat) {
  ll i = 1;
  ll j = 0;
  vll lps(szs(pat), 0);
  lps[0] = 0;
  while (i < szs(pat)) {
    if (pat[i] == pat[j])
      lps[i] = j + 1, i++, j++;
    else if (j == 0)
      lps[i] = 0, i++;
    else
      j = lps[j - 1];
  }
  return lps;
}
///---------x------------x----------x-----------///
ll BIT[arrsize] = {};
ll n;
void update(ll idx, ll val) {
  for (ll i = idx; i <= n; i += (i & (-i)))
    BIT[i] += val, BIT[i] %= MOD;
}
ll query(ll idx) {
  ll sum = 0;
  for (ll i = idx; i > 0; i -= (i & (-i)))
    sum += BIT[i], sum %= MOD;
  return sum;
}
ll get(ll l, ll r) {
  if (l > r or l < 1 or r > n)
    return 0;
  return (query(r) - query(l - 1) + MOD) % MOD;
}

void solve() {
  ll k;
  cin >> n >> k;
  vpp arr(k);
  f(i, 0, k) cin >> arr[i].ff >> arr[i].ss;

  update(1, 1);
  cf(i, 2, n) {
    ll cnt = 0;
    f(j, 0, k) {
      ll lo = i - arr[j].ff;
      ll hi = i - arr[j].ss;
      if (lo < 1)
        continue;
      if (hi < 1)
        hi = i - min(arr[j].ss, i - 1);
      cnt += (get(hi, lo));
      cnt %= MOD;
    }
    update(i, cnt);
    // cout<<"#"<<i<<" "<<cnt<<endl;
  }

  cout << get(n, n) << endl;
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  auto start1 = high_resolution_clock::now();
  solve();
  // test(solve);
  auto stop1 = high_resolution_clock::now();
  auto duration = duration_cast<microseconds>(stop1 - start1);
#ifndef ONLINE_JUDGE
  cerr << "Time: " << duration.count() / 1000.0 << endl;
  cout << duration.count() / 1000.0 << endl;
#endif
}

// بساملہ ہیر رحمن نیر رحیم
//---------------------------//
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization("unroll-loops")
#include <algorithm>
#include <bitset>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// #define PBDS tree<long long int,null_type,less<long long int>,
// rb_tree_tag,tree_order_statistics_node_update> using namespace __gnu_pbds;
#define arrsize 2000001
#define dpsize 1001
#define vpp vector<PP>
#define vll vector<ll>
#define vcc vector<char>
#define endl "\\n"
#define vbb vector<bool>
#define w(t) while (t--)
#define PP pair<ll, ll>
#define test(x)                                                                \\
  ll t;                                                                        \\
  cin >> t;                                                                    \\
  w(t) x()
#define __lb lower_bound
#define __ub upper_bound
#define szs(x) x.length()
#define szv(x) x.size()
#define INF 1999999996000000010
#define ll long long int
#define takeINP(arr, n)                                                        \\
  for (long long int i = 0; i < n; i++)                                        \\
    cin >> arr[i];
#define f(i, s, e) for (long long int i = s; i < e; i++)
#define cf(i, s, e) for (long long int i = s; i <= e; i++)
#define rf(i, e, s) for (long long int i = e - 1; i >= s; i--)
#define mem(arr) memset(arr, 0, sizeof(arr));
#define MOD 998244353
#define rsz(x, n) x.resize(n)
#define rsr(x, n) x.reserve(n)
#define mp(a, b) make_pair(a, b)
#define pb push_back
#define print(arr, s, e)                                                       \\
  f(i, s, e) cout << arr[i] << " ";                                            \\
  cout << endl;
#define all(v) v.begin(), v.end()
#define ff first
#define ss second
#define vll vector<ll>
#define triplet pair<ll, pair<ll, ll>>
#define MITR(a, b) map<a, b>::reverse_iterator
using namespace std;
using namespace chrono;

///---------------Functions---------------------///
ll advceil(ll num, ll den) {
  return (num % den == 0 ? num / den : num / den + 1);
}
ll lstbt(ll val) {
  ll msk = val & (val - 1);
  return log2(val ^ msk);
}
ll modexpo(ll a, ll b) {
  ll res = 1;
  while (b > 0) {
    if (b & 1)
      res = (res % MOD * a % MOD) % MOD;
    a = (a % MOD * a % MOD);
    b /= 2;
  }
  return res;
}
ll expo(ll a, ll b) {
  ll res = 1;
  while (b > 0) {
    if (b & 1)
      res = (res * a);
    a = (a * a);
    b /= 2;
  }
  return res;
}
ll gcd(ll a, ll b) { return a == 0 ? b : gcd(b % a, a); }
vll CALCfactor(ll n) {
  vll factor(n + 2, 0);
  for (ll i = 4; i <= n; i += 2)
    factor[i] = 2;
  for (ll j = 3; j <= n; j += 2) {
    if (factor[j])
      continue;
    for (ll i = 2 * j; i <= n; i += j)
      factor[i] = j;
  }
  return factor;
}
vll CALCprimeNUM(ll n) {
  vll factor = CALCfactor(n);
  vll primeNUM;
  primeNUM.reserve(n + 2);
  cf(i, 2, n) if (!factor[i]) primeNUM.pb(i);
  return primeNUM;
}
vll CALCprimeFACTOR(ll n) {
  vll factor = CALCfactor(n);
  vll ans;
  while (factor[n] != 0) {
    ans.pb(factor[n]);
    n /= factor[n];
  }
  ans.pb(n);
  return ans;
}
vll unique(vll x) {
  sort(all(x));
  set<ll> s;
  vll ans;
  ans.reserve(szv(x));
  for (auto elem : x)
    s.insert(elem);
  for (auto elem : s)
    ans.pb(elem);
  return ans;
}
vll ZALGO(string s, string pat) {
  ll lens = szs(pat);
  pat += char(36);
  pat += s;
  s = pat;
  vll pref(szs(s) + 1, 0);
  pref[0] = szs(s);
  ll spt = -1;
  ll ept = -1;
  ll processCnt = 0;
  for (ll i = 1; i < szs(s); i++) {
    bool isdone = false;
    if (i <= ept and i >= spt) {
      if (pref[i - spt] + i <= ept)
        pref[i] = pref[i - spt], isdone = true;
      processCnt++;
    }
    if (!isdone) {
      ll ptr = i;
      ll lo = 0;
      while (s[lo] == s[ptr])
        ptr++, lo++, processCnt++;
      if (ept < ptr - 1) {
        spt = i;
        ept = ptr - 1;
      }
      pref[i] = lo;
    }
  }
  vll ans;
  ans.reserve(szs(s) - lens);
  for (ll i = lens + 1; i < szs(s); i++)
    ans.pb(pref[i]);
  return ans;
}
void spclSort(vector<pair<pair<ll, ll>, ll>> &v) {
  ll n = szv(v);
  {
    vll cnt(n);
    for (auto elem : v) {
      cnt[elem.ff.ss]++;
    }
    vector<pair<pair<ll, ll>, ll>> a_new(n);
    vll pos(szv(cnt));
    pos[0] = 0;
    for (ll i = 1; i < szv(cnt); i++) {
      pos[i] = cnt[i - 1] + pos[i - 1];
    }
    for (auto elem : v) {
      a_new[pos[elem.ff.ss]] = elem;
      pos[elem.ff.ss]++;
    }
    v = a_new;
  }
  {
    vll cnt(n, 0);
    for (auto elem : v) {
      cnt[elem.ff.ff]++;
    }
    vector<pair<pair<ll, ll>, ll>> a_new(n);
    vll pos(szv(cnt));
    pos[0] = 0;
    for (ll i = 1; i < szv(cnt); i++) {
      pos[i] = cnt[i - 1] + pos[i - 1];
    }
    for (auto elem : v) {
      a_new[pos[elem.ff.ff]] = elem;
      pos[elem.ff.ff]++;
    }
    v = a_new;
  }
}
pair<vector<vll>, vector<vll>> getOrdering(string s) {
  s += char(36);
  vector<vll> dp;
  dp.reserve(log2(szs(s)) + 3);
  vector<vll> dp2;
  dp2.reserve(log2(szs(s)) + 3);
  vll ordering(szs(s)), eqClass(szs(s));
  {
    vector<pair<char, ll>> temp(szs(s));
    f(i, 0, szs(s)) temp[i] = {s[i], i};
    sort(all(temp));
    f(i, 0, szv(temp)) ordering[temp[i].ss] = i;
    eqClass[temp[0].ss] = 0;
    f(i, 1, szv(temp)) {
      if (temp[i].ff != temp[i - 1].ff)
        eqClass[temp[i].ss] = eqClass[temp[i - 1].ss] + 1;
      else
        eqClass[temp[i].ss] = eqClass[temp[i - 1].ss];
    }
    dp.pb(ordering);
    dp2.pb(eqClass);
  }
  ll k = 1;
  while ((1 << (k - 1)) < szs(s)) {
    vector<pair<pair<ll, ll>, ll>> arr(szs(s));
    for (ll i = 0; i < szs(s); i++) {
      arr[i] = {{eqClass[i], eqClass[(i + (1 << (k - 1))) % szs(s)]}, i};
    }
    spclSort(arr);
    f(i, 0, szs(s)) ordering[arr[i].ss] = i;
    eqClass[arr[0].ss] = 0;
    f(i, 1, szv(s)) {
      if (arr[i].ff != arr[i - 1].ff)
        eqClass[arr[i].ss] = eqClass[arr[i - 1].ss] + 1;
      else
        eqClass[arr[i].ss] = eqClass[arr[i - 1].ss];
    }
    dp.pb(ordering);
    dp2.pb(eqClass);
    k++;
  }
  return {dp, dp2};
}
vll sortOrdering(vector<vll> dp) {
  vll arr = dp[szv(dp) - 1];
  vll ans(szv(arr));
  ll cnt = 0;
  for (auto elem : arr) {
    ans[elem] = cnt;
    cnt++;
  }
  return ans;
}
vll getLps(string pat) {
  ll i = 1;
  ll j = 0;
  vll lps(szs(pat), 0);
  lps[0] = 0;
  while (i < szs(pat)) {
    if (pat[i] == pat[j])
      lps[i] = j + 1, i++, j++;
    else if (j == 0)
      lps[i] = 0, i++;
    else
      j = lps[j - 1];
  }
  return lps;
}
///---------x------------x----------x-----------///
ll BIT[arrsize] = {};
ll n;
void update(ll idx, ll val) {
  for (ll i = idx; i <= n; i += (i & (-i)))
    BIT[i] += val, BIT[i] %= MOD;
}
ll query(ll idx) {
  ll sum = 0;
  for (ll i = idx; i > 0; i -= (i & (-i)))
    sum += BIT[i], sum %= MOD;
  return sum;
}
ll get(ll l, ll r) {
  if (l > r or l < 1 or r > n)
    return 0;
  return (query(r) - query(l - 1) + MOD) % MOD;
}

void solve() {
  ll k;
  cin >> n >> k;
  vpp arr(k);
  f(i, 0, k) cin >> arr[i].ff >> arr[i].ss;

  update(1, 1);
  cf(i, 2, n) {
    ll cnt = 0;
    f(j, 0, k) {
      ll lo = i - arr[j].ff;
      ll hi = i - arr[j].ss;
      if (lo < 1)
        continue;
      if (hi < 1)
        hi = i - min(arr[j].ss, i - 1);
      cnt += (get(hi, lo));
      cnt %= MOD;
    }
    update(i, cnt);
    // cout<<"#"<<i<<" "<<cnt<<endl;
  }

  cout << get(n, n) << endl;
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  auto start1 = high_resolution_clock::now();
  solve();
  // test(solve);
  auto stop1 = high_resolution_clock::now();
  auto duration = duration_cast<microseconds>(stop1 - start1);
#ifndef ONLINE_JUDGE
  cerr << "Time: " << duration.count() / 1000.0 << endl;
  cout << duration.count() / 1000.0 << endl;
#endif
}

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc


// 差分dp
//  #include<iostream>
//  #include<algorithm>
//  #include<vector>
//  #include<utility>
//  using namespace std;
//  constexpr auto mod=998244353;
//  vector<pair<int,int>> p;
//  bool sieve[200000+5];
//  vector<int> step;
//  int dp[200000+5];
//  int main(){
//      int n,k;
//      cin>>n>>k;
//      for(int i=1;i<=k;i++){
//          int a,b;
//          cin>>a>>b;
//          for(int j=a;j<=b;j++){
//              if(!sieve[j]){
//                  step.push_back(j);
//                  sieve[j]=true;
//              }
//          }
//      }
//      dp[1]=1;
//      for(int i=1;i<=n;i++){
//          for(int j=0;j<step.size();j++){
//              if(i-step[j]>0){
//                  dp[i]=(dp[i]+dp[i-step[j]])%mod;
//              }
//          }
//      }
//      cout<<dp[n]<<endl;
//      getchar();
//      getchar();
//      return 0;
//  }
#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
#define ll long long
using namespace std;
constexpr auto mod = 998244353;
ll dp[200000 + 5];
vector<pair<ll, ll>> v;
int main() {
  int n, k;
  cin >> n >> k;
  for (int i = 1; i <= k; i++) {
    int a, b;
    cin >> a >> b;
    v.emplace_back(make_pair(a, b));
  }
  dp[1] = 1;
  dp[2] = -1;
  for (int i = 1; i <= n; i++) {
    dp[i] = ((dp[i] % mod + dp[i - 1]) % mod + mod) % mod;
    for (int j = 0; j < k; j++) {
      dp[i + v[j].first] = dp[i + v[j].first] + dp[i];
      dp[i + v[j].second + 1] = dp[i + v[j].second + 1] - dp[i];
    }
  }
  cout << dp[n] << endl;
  getchar();
  getchar();
  return 0;
}

#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
#define ll long long
using namespace std;
constexpr auto mod = 998244353;
ll dp[200000 * 2 + 5];
vector<pair<ll, ll>> v;
int main() {
  int n, k;
  cin >> n >> k;
  for (int i = 1; i <= k; i++) {
    int a, b;
    cin >> a >> b;
    v.emplace_back(make_pair(a, b));
  }
  dp[1] = 1;
  dp[2] = -1;
  for (int i = 1; i <= n; i++) {
    dp[i] = ((dp[i] + dp[i - 1]) % mod + mod) % mod;
    for (int j = 0; j < k; j++) {
      dp[i + v[j].first] = dp[i + v[j].first] + dp[i];
      dp[i + v[j].second + 1] = dp[i + v[j].second + 1] - dp[i];
    }
  }
  cout << dp[n] << endl;
  // getchar();
  // getchar();
  return 0;
}


// #define _GLIBCXX_DEBUG
// #pragma GCC optimize "trapv"
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
// #pragma optimization_level 3
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define pb push_back
#define f first
#define s second
#define min3(a, b, c) min(min(a, b), c)
#define max3(a, b, c) max(max(a, b), c)
#define all(v) v.begin(), v.end()

typedef long long ll;
typedef double ld;
typedef long double lld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

template <class T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

const int INF = 1e9;
// const ll INF = 1e18;
// const ll mod = 1000000007;
const ll mod = 998244353;

void solve(int tc) {
  int n, k;
  cin >> n >> k;
  vi s;

  for (int i = 0; i < k; i++) {
    int l, r;
    cin >> l >> r;
    for (int i = l; i <= r; i++)
      s.pb(i);
  }
  sort(all(s));
  vi dp(n + 1);
  dp[0] = 0;
  dp[1] = 1;

  for (int i = 2; i <= n; i++) {
    for (int j = 0; j < s.size() && s[j] < i; j++)
      (dp[i] += dp[i - s[j]]) %= mod;
  }

  cout << dp[n] << "\\n";
}

int main() {
  ios_base::sync_with_stdio(NULL);
  cin.tie(NULL);

  int tc = 1;
  // cin >> tc;
  for (int t = 0; t < tc; t++)
    solve(t);

  return 0;
}

// #define _GLIBCXX_DEBUG
// #pragma GCC optimize "trapv"
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
// #pragma optimization_level 3
// #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#define pb push_back
#define f first
#define s second
#define min3(a, b, c) min(min(a, b), c)
#define max3(a, b, c) max(max(a, b), c)
#define all(v) v.begin(), v.end()

typedef long long ll;
typedef double ld;
typedef long double lld;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<pii> vpi;
typedef vector<pll> vpl;

template <class T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

const int INF = 1e9;
// const ll INF = 1e18;
// const ll mod = 1000000007;
const ll mod = 998244353;

void solve(int tc) {
  int n, k;
  cin >> n >> k;
  vpi s(k);

  for (int i = 0; i < k; i++) {
    cin >> s[i].f >> s[i].s;
  }

  vl pref_sum(n + 1, 0), dp(n + 1, 0);
  dp[0] = 0;
  dp[1] = 1;
  pref_sum[0] = 0;
  pref_sum[1] = 1;

  for (int i = 2; i <= n; i++) {
    for (pii x : s) {
      if (i - x.s > 0)
        (dp[i] += pref_sum[i - x.f] - pref_sum[i - x.s - 1] + mod) %= mod;
      else if (i - x.f > 0)
        (dp[i] += pref_sum[i - x.f]) %= mod;
    }
    (pref_sum[i] = pref_sum[i - 1] + dp[i]) %= mod;
  }

  cout << dp[n] << "\\n";
}

int main() {
  ios_base::sync_with_stdio(NULL);
  cin.tie(NULL);

  int tc = 1;
  // cin >> tc;
  for (int t = 0; t < tc; t++)
    solve(t);

  return 0;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <ctime>
#include <deque>
using namespace std;

#define fr first
#define se second
#define int long long
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define vi vector<int>
#define vvi vector<vector<int>>
#define mi map<int, int>
#define pq priority_queue<int>
#define set_bits(x) __builtin_popcountll(x)
#define mod 1000000007
#define inf 1e18 // Defining infinity the overflow of int
#define ps(x, y)                                                               \\
  fixed << setprecision(y)                                                     \\
        << x // for defining the precision of the decimal upto y places.
#define zrosetbits(x)                                                          \\
  __builtin_ctzll(x) // it will give no of 0's before the first 1 from the
                     // right.
#define mk(a, n, type) type *a = new type[n];
#define test(t)                                                                \\
  int t;                                                                       \\
  cin >> t;                                                                    \\
  while (t--)
#define no cout << "No\\n";
#define yes cout << "Yes\\n";
#define NO cout << "NO\\n";
#define YES cout << "YES\\n";
// #define for(i,n)          for(int i=0;i<n;i++)
// #define for(j,n)          for(int j=0;j<n;j++)
//  #define forn(i,n)               for(int i=0;i<n;i--)

//**********************************************************************************************************
struct custom_hash {
  static uint64_t splitmix64(uint64_t x) {
    // http://xorshift.di.unimi.it/splitmix64.c
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }

  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }
};

#define safemap unordered_map<int, int, custom_hash>

//*********************************************************************************************************

void io() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin.tie(0);
}

int helper(int cell, vector<int> &v, vi &dp, int n) {
  // Base Case
  if (cell == n)
    return 1;

  if (dp[cell] != -1)
    return dp[cell];

  // recursive Case
  int res = 0;

  for (int i = 0; i < v.size(); i++) {
    if (cell + v[i] <= n)
      res = (res % 998244353 + helper(cell + v[i], v, dp, n) % 998244353) %
            998244353;

    else
      break;
  }

  dp[cell] = res;

  return res;
}

int32_t main() {

  io();
  clock_t begin = clock();

  int te = 1;

  int n, k, m, p, q, x, y;
  int small = INT_MIN;

  cin >> n >> k;

  map<int, int> mp;

  for (int i = 0; i < k; i++) {
    cin >> p >> q;

    for (int j = p; j <= q; j++)
      mp[j]++;
  }

  vi v;

  for (auto x : mp)
    v.pb(x.first);

  sort(v.begin(), v.end());

  vi dp(n + 1, -1);

  cout << helper(1, v, dp, n) % 998244353 << "\\n";

  return 0;
}

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <ctime>
#include <deque>
using namespace std;

#define fr first
#define se second
#define int long long
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define vi vector<int>
#define vvi vector<vector<int>>
#define mi map<int, int>
#define pq priority_queue<int>
#define set_bits(x) __builtin_popcountll(x)
#define mod 1000000007
#define inf 1e18 // Defining infinity the overflow of int
#define ps(x, y)                                                               \\
  fixed << setprecision(y)                                                     \\
        << x // for defining the precision of the decimal upto y places.
#define zrosetbits(x)                                                          \\
  __builtin_ctzll(x) // it will give no of 0's before the first 1 from the
                     // right.
#define mk(a, n, type) type *a = new type[n];
#define test(t)                                                                \\
  int t;                                                                       \\
  cin >> t;                                                                    \\
  while (t--)
#define no cout << "No\\n";
#define yes cout << "Yes\\n";
#define NO cout << "NO\\n";
#define YES cout << "YES\\n";
// #define for(i,n)          for(int i=0;i<n;i++)
// #define for(j,n)          for(int j=0;j<n;j++)
//  #define forn(i,n)               for(int i=0;i<n;i--)

//**********************************************************************************************************
struct custom_hash {
  static uint64_t splitmix64(uint64_t x) {
    // http://xorshift.di.unimi.it/splitmix64.c
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }

  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }
};

#define safemap unordered_map<int, int, custom_hash>

//*********************************************************************************************************

void io() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin.tie(0);
}

int32_t main() {
  int n, k, m, p, q, x, y;
  int small = INT_MIN;

  cin >> n >> k;

  int l[k] = {0};
  int r[k] = {0};

  for (int i = 0; i < k; i++)
    cin >> l[i] >> r[i];

  // Now creating DP
  //  Now creating prefix array for storing the sum of all possible combinations
  //  to reach the cell ith

  vi dp(n + 1, 0);
  vi psum(n + 1, 0);

  dp[1] = 1;
  psum[1] = 1;

  int mood = 998244353;

  for (int i = 2; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      if (i <= l[j])
        continue;

      int start = l[j];
      int end = min(i - 1, r[j]);

      int val = (psum[i - start] - psum[i - end - 1] + mood) % mood;
      dp[i] = (val + dp[i]) % mood;
    }
    psum[i] = (dp[i] % mood + psum[i - 1] % mood) % mood;
  }

  cout << dp[n] << "\\n";

  return 0;
}