#include <bits/stdc++.h>
using namespace std;
#define fio                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL)
#define watch(x) cout << (#x) << " is " << (x) << endl
#define f(t) for (ll i = 0; i < t; i++)
#define ll long long int
#define ld long double
#define umpl unordered_map<ll, ll>
#define vl vector<ll>
#define vld vector<ld>
#define vvl vector<vl>
#define pb push_back
#define pll pair<ll, ll>
#define inf 1e18
#define pcout(x, p) cout << fixed << setprecision(p) << x
#define all(a) a.begin(), a.end()
#define endl "\\n"
const ll mod = 998244353;
inline ll mul(ll a, ll b) { return (a * 1ll * b) % mod; }
inline ll sub(ll a, ll b) {
  ll c = a - b;
  if (c < 0)
    c += mod;
  return c;
}
inline ll add(ll a, ll b) {
  ll c = a + b;
  if (c >= mod)
    c -= mod;
  return c;
}
inline ll max(ll a, ll b) { return a > b ? a : b; }
inline ll min(ll a, ll b) { return a < b ? a : b; }
inline ll ceil(ll a, ll b) { return (a % b == 0) ? (a / b) : (a / b + 1); }
template <class T> ostream &operator<<(ostream &os, vector<T> V) {
  for (auto v : V)
    os << v << "  ";
  return os;
}
template <class T> ostream &operator<<(ostream &os, set<T> S) {
  os << "{ ";
  for (auto s : S)
    os << s << " ";
  return os << "}";
}
template <class L, class R> ostream &operator<<(ostream &os, pair<L, R> P) {
  return os << "(" << P.first << "," << P.second << ")";
}
template <class L, class R> ostream &operator<<(ostream &os, map<L, R> M) {
  os << "{ ";
  for (auto m : M)
    os << "(" << m.first << ":" << m.second << ") ";
  return os << "}";
}
struct comp {
  template <class T1, class T2, class T3, class T4>
  bool operator()(const pair<T1, T2> &p1, const pair<T3, T4> &p2) {
    return p1.first < p2.first;
  }
};

int main() {
  fio;
  ll n, k;
  cin >> n >> k;
  set<ll> s;
  for (ll i = 0; i < k; i++) {
    ll l, r;
    cin >> l >> r;
    for (ll j = l; j <= r; j++) {
      s.insert(j);
    }
  }
  vl dp(n + 1, 0);
  dp[1] = 1;
  for (ll i = 2; i <= n; i++) {
    for (auto j : s) {
      if ((i - j) >= 0) {
        dp[i] = add(dp[i], dp[i - j]);
      }
    }
  }
  cout << dp[n] << endl;
}

#include <bits/stdc++.h>
using namespace std;
#define fio                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL)
#define watch(x) cout << (#x) << " is " << (x) << endl
#define f(t) for (ll i = 0; i < t; i++)
#define ll long long int
#define ld long double
#define umpl unordered_map<ll, ll>
#define vl vector<ll>
#define vld vector<ld>
#define vvl vector<vl>
#define pb push_back
#define pll pair<ll, ll>
#define inf 1e18
#define pcout(x, p) cout << fixed << setprecision(p) << x
#define all(a) a.begin(), a.end()
#define endl "\\n"
const ll mod = 998244353;
inline ll mul(ll a, ll b) { return (a * 1ll * b) % mod; }
inline ll sub(ll a, ll b) {
  ll c = a - b;
  if (c < 0)
    c += mod;
  return c;
}
inline ll add(ll a, ll b) {
  ll c = a + b;
  if (c >= mod)
    c -= mod;
  return c;
}
inline ll max(ll a, ll b) { return a > b ? a : b; }
inline ll min(ll a, ll b) { return a < b ? a : b; }
inline ll ceil(ll a, ll b) { return (a % b == 0) ? (a / b) : (a / b + 1); }
template <class T> ostream &operator<<(ostream &os, vector<T> V) {
  for (auto v : V)
    os << v << "  ";
  return os;
}
template <class T> ostream &operator<<(ostream &os, set<T> S) {
  os << "{ ";
  for (auto s : S)
    os << s << " ";
  return os << "}";
}
template <class L, class R> ostream &operator<<(ostream &os, pair<L, R> P) {
  return os << "(" << P.first << "," << P.second << ")";
}
template <class L, class R> ostream &operator<<(ostream &os, map<L, R> M) {
  os << "{ ";
  for (auto m : M)
    os << "(" << m.first << ":" << m.second << ") ";
  return os << "}";
}
struct comp {
  template <class T1, class T2, class T3, class T4>
  bool operator()(const pair<T1, T2> &p1, const pair<T3, T4> &p2) {
    return p1.first < p2.first;
  }
};

int main() {
  fio;
  ll n, k;
  cin >> n >> k;
  set<ll> s;
  vector<pll> a(k);
  for (ll i = 0; i < k; i++) {
    ll l, r;
    cin >> l >> r;
    a[i] = {l, r};
  }
  sort(all(a));
  vl dp(n + 1, 0);
  dp[0] = 1;
  dp[1] = 1;
  map<ll, ll> pre;
  pre[1] = 1;
  for (ll i = 2; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      if (a[j].first >= i) {
        break;
      } else {
        ll temp = sub(pre[i - a[j].first], pre[i - a[j].second - 1]);
        dp[i] = add(dp[i], temp);
      }
    }
    pre[i] = add(pre[i - 1], dp[i]);
  }
  cout << dp[n] << endl;
}


#include <algorithm>
#include <bitset>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <queue>
#include <sstream>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#define rep(i, n) for (int i = 0; i < n; ++i)
#define debug(s, param) std::cerr << s << param << std::endl;

using namespace std;
using ll = long long;

const ll MOD = 998244353;

int main() {
  ll n, k;
  cin >> n >> k;
  vector<ll> nums;
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    for (int i = l; i <= r; ++i) {
      nums.emplace_back(i);
    }
  }
  // sort(nums.begin(), nums.end());
  vector<int> dp(n + 1, 0);
  dp[1] = 1;
  for (int i = 2; i <= n; ++i) {
    for (auto num : nums) {
      if (i >= num) {
        dp[i] += (dp[i - num] % MOD);
        dp[i] = (dp[i] % MOD);
      }
      // if (i < num) break;
      // dp[i] += (dp[i-num] % MOD);
      // dp[i] = (dp[i] % MOD);
    }
  }
  cout << dp[n] << endl;
  return 0;
}

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <queue>
#include <sstream>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#define rep(i, n) for (int i = 0; i < n; ++i)
#define debug(s, param) std::cerr << s << param << std::endl;

using namespace std;
using ll = long long;

const ll MOD = 998244353;

int main() {
  ll n, k;
  cin >> n >> k;
  vector<int> left(k), right(k);
  rep(i, k) cin >> left[i] >> right[i];
  vector<ll> dp(n + 1);
  vector<ll> dpSum(n + 1);
  dp[1] = 1;
  dpSum[1] = 1;
  for (int i = 2; i <= n; ++i) {
    rep(j, k) {
      int l = i - right[j], r = i - left[j];
      if (r < 1)
        continue;
      l = max(l, 1);
      ll sum = (dpSum[r] + MOD - dpSum[l - 1]) % MOD;
      dp[i] += sum;
      dp[i] = dp[i] % MOD;
    }
    dpSum[i] = (dpSum[i - 1] + dp[i]) % MOD;
  }
  cout << dp[n] << endl;
  return 0;
}


/**
 *	created: 19.09.2020 21:38:53
 **/
#include <bits/stdc++.h>
// #include <boost/multiprecision/cpp_int.hpp>
// using bint = boost::multiprecision::cpp_int;
using namespace std;
// #define endl '\\n'
#define int long long
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n - 1); i >= 0; i--)
#define rep2(i, s, n) for (int i = (s); i < (int)(n); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define pcnt(bit) __builtin_popcountll(bit)
using ll = long long;
using P = pair<int, int>;
const long double pi = acos(-1.0);
const int MAX = 1000010;
const int INF = 1ll << 60;
// const int MOD = 1000000007;
const int MOD = 998244353;
template <typename T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
inline void print(P a) { cout << a.first << " " << a.second << endl; }
template <typename T> T pow(T a, ll n) {
  T r(1);
  while (n) {
    if (n & 1)
      r *= a;
    a *= a;
    n >>= 1;
  }
  return r;
}
struct faster_io {
  faster_io() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);
  }
} faster_io_;

// ModInt
template <int mod> struct ModInt {
  int x;
  ModInt() : x(0) {}
  ModInt(long long x_) {
    if ((x = x_ % mod + mod) >= mod)
      x -= mod;
  }
  ModInt inv() const { return pow(*this, mod - 2); }
  ModInt &operator+=(ModInt rhs) {
    if ((x += rhs.x) >= mod)
      x -= mod;
    return *this;
  }
  ModInt &operator-=(ModInt rhs) {
    if ((x -= rhs.x) < 0)
      x += mod;
    return *this;
  }
  ModInt &operator*=(ModInt rhs) {
    x = (unsigned long long)x * rhs.x % mod;
    return *this;
  }
  ModInt &operator/=(ModInt rhs) {
    x = (unsigned long long)x * rhs.inv().x % mod;
    return *this;
  }
  ModInt operator-() const { return -x < 0 ? mod - x : -x; }
  ModInt operator+(ModInt rhs) const { return ModInt(*this) += rhs; }
  ModInt operator-(ModInt rhs) const { return ModInt(*this) -= rhs; }
  ModInt operator*(ModInt rhs) const { return ModInt(*this) *= rhs; }
  ModInt operator/(ModInt rhs) const { return ModInt(*this) /= rhs; }
  bool operator==(ModInt rhs) const { return x == rhs.x; }
  bool operator!=(ModInt rhs) const { return x != rhs.x; }
  friend ostream &operator<<(ostream &s, ModInt<mod> a) {
    s << a.x;
    return s;
  }
  friend istream &operator>>(istream &s, ModInt<mod> &a) {
    s >> a.x;
    return s;
  }
};

using mint = ModInt<MOD>;

int ms[MAX];
mint dp[MAX];

signed main() {
  int n, k;
  cin >> n >> k;

  vector<int> v;

  rep(i, k) {
    int l, r;
    cin >> l >> r;
    rep2(j, l, r + 1) v.push_back(j);
  }

  sort(all(v));

  dp[1] = 1;

  rep2(i, 1, n + 1) {
    for (auto j : v) {
      if (i + j > n)
        break;
      else
        dp[i + j] += dp[i];
    }
  }

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

/**
 *	created: 20.09.2020 02:28:09
 **/
#include <bits/stdc++.h>
// #include <boost/multiprecision/cpp_int.hpp>
// using bint = boost::multiprecision::cpp_int;
using namespace std;
// #define endl '\\n'
#define int long long
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n - 1); i >= 0; i--)
#define rep2(i, s, n) for (int i = (s); i < (int)(n); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define pcnt(bit) __builtin_popcountll(bit)
using ll = long long;
using P = pair<int, int>;
const long double pi = acos(-1.0);
const int MAX = 1000010;
const int INF = 1ll << 60;
// const int MOD = 1000000007;
const int MOD = 998244353;
template <typename T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
inline void print(P a) { cout << a.first << " " << a.second << endl; }
template <typename T> T pow(T a, ll n) {
  T r(1);
  while (n) {
    if (n & 1)
      r *= a;
    a *= a;
    n >>= 1;
  }
  return r;
}
struct faster_io {
  faster_io() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);
  }
} faster_io_;

// ModInt
template <int mod> struct ModInt {
  int x;
  ModInt() : x(0) {}
  ModInt(long long x_) {
    if ((x = x_ % mod + mod) >= mod)
      x -= mod;
  }
  ModInt inv() const { return pow(*this, mod - 2); }
  ModInt &operator+=(ModInt rhs) {
    if ((x += rhs.x) >= mod)
      x -= mod;
    return *this;
  }
  ModInt &operator-=(ModInt rhs) {
    if ((x -= rhs.x) < 0)
      x += mod;
    return *this;
  }
  ModInt &operator*=(ModInt rhs) {
    x = (unsigned long long)x * rhs.x % mod;
    return *this;
  }
  ModInt &operator/=(ModInt rhs) {
    x = (unsigned long long)x * rhs.inv().x % mod;
    return *this;
  }
  ModInt operator-() const { return -x < 0 ? mod - x : -x; }
  ModInt operator+(ModInt rhs) const { return ModInt(*this) += rhs; }
  ModInt operator-(ModInt rhs) const { return ModInt(*this) -= rhs; }
  ModInt operator*(ModInt rhs) const { return ModInt(*this) *= rhs; }
  ModInt operator/(ModInt rhs) const { return ModInt(*this) /= rhs; }
  bool operator==(ModInt rhs) const { return x == rhs.x; }
  bool operator!=(ModInt rhs) const { return x != rhs.x; }
  friend ostream &operator<<(ostream &s, ModInt<mod> a) {
    s << a.x;
    return s;
  }
  friend istream &operator>>(istream &s, ModInt<mod> &a) {
    s >> a.x;
    return s;
  }
};

using mint = ModInt<MOD>;

mint dp[MAX], dpsum[MAX];

signed main() {
  int n, k;
  cin >> n >> k;
  vector<P> v;
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    v.push_back(P(l, r));
  }

  dp[1] = 1;
  dpsum[1] = 1;

  rep2(i, 2, n + 2) {
    rep(j, k) {
      int l = v[j].first, r = v[j].second;
      int li = i - r, ri = i - l;
      if (ri < 0)
        continue;
      chmax(li, 1ll);
      dp[i] += dpsum[ri] - dpsum[li - 1];
    }
    dpsum[i] = dpsum[i - 1] + dp[i];
  }
  cout << dp[n] << endl;
  return 0;
}


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

#define timesaver                                                              \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);

typedef long long ll;
typedef long double ldb;

#define mp make_pair
#define pb push_back
#define F first
#define S second
#define nl '\\n'

#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
#define mem(a, val) memset(a, val, sizeof(a))
#define deci(x) cout << fixed << setprecision(x);
#define bitcount(x) __builtin_popcountll(x)

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

const int MAX = 2 * 1000 * 100 + 10;
const ll INF = 1e18;
const int MOD = 998244353;

vector<ll> jumps;
ll ar[MAX], dp[MAX], n, k;

ll sol(ll pos) {
  if (!pos)
    return 1;
  ll &ans = dp[pos];
  if (ans != -1)
    return ans;
  ans = 0;
  for (ll i : jumps) {
    if (i > pos)
      break;
    ans += sol(pos - i);
    if (ans >= MOD)
      ans %= MOD;
  }
  return ans;
}

void sol() {
  cin >> n >> k;
  for (ll i = 0; i < k; i++) {
    ll l, r;
    cin >> l >> r;
    ar[l]++, ar[r + 1]--;
  }
  for (ll i = 1; i < MAX; i++)
    ar[i] += ar[i - 1];
  for (ll i = 0; i < MAX; i++)
    if (ar[i])
      jumps.pb(i);
  dp[0] = 1;
  for (int i = 0; i < n; i++) {
    if (!dp[i])
      continue;
    for (int j : jumps) {
      dp[i + j] += dp[i];
      if (dp[i + j] >= MOD)
        dp[i + j] %= MOD;
    }
  }
  cout << dp[n - 1] << nl;
}

signed main() {
  timesaver;
  //  int t = 1 ; cin >> t ; while(t--)
  { sol(); }
}

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

#define timesaver                                                              \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);

typedef long long ll;
typedef long double ldb;

#define mp make_pair
#define pb push_back
#define F first
#define S second
#define nl '\\n'

#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
#define mem(a, val) memset(a, val, sizeof(a))
#define deci(x) cout << fixed << setprecision(x);
#define bitcount(x) __builtin_popcountll(x)

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

const int MAX = 2 * 1000 * 100 + 10;
const ll INF = 1e18;
const int MOD = 998244353;

vector<ll> jumps;
ll ar[MAX], dp[MAX], n, k;

ll BIT[MAX];

void update(ll pos, ll val) {
  while (pos > 0 and pos < MAX) {
    BIT[pos] += val;
    if (BIT[pos] >= MOD)
      BIT[pos] %= MOD;
    pos += (pos & -pos);
  }
}

ll get(ll pos) {
  ll ans = 0;
  while (pos > 0) {
    ans += BIT[pos];
    if (ans >= MOD)
      ans %= MOD;
    pos -= (pos & -pos);
  }
  return ans;
}

void sol() {
  cin >> n >> k;
  vector<pair<ll, ll>> v(k);
  for (auto &i : v)
    cin >> i.F >> i.S;
  update(1, 1);
  for (ll i = 2; i <= n; i++) {
    ll tmp = 0;
    for (auto k : v) {
      ll r = i - k.F, l = i - k.S;
      ll ans = (get(r) - get(l - 1) + MOD) % MOD;
      tmp += ans;
      if (tmp >= MOD)
        tmp %= MOD;
    }
    update(i, tmp);
  }
  cout << (get(n) - get(n - 1) + MOD) % MOD << nl;
}

signed main() {
  timesaver;
  //  int t = 1 ; cin >> t ; while(t--)
  { sol(); }
}


#include <bits/stdc++.h>
#include <unordered_map>
#define for_int(i, a, b) for (int i = (a); i <= (b); ++i)
#define rep_int(i, a, b) for (int i = (a); i >= (b); --i)
#define for_ll(i, a, b) for (ll i = (a); i <= (b); ++i)
#define rep_ll(i, a, b) for (ll i = (a); i >= (b); --i)
#define IOS ios::sync_with_stdio(false);
#define ull unsigned long long
#define ll long long
#define db double
#define HPMAX 1005
#define KMP_MAX 1005
#define prime_MAX 1000005
#define quick_pow_mod 1000000007
#define PII pair<int, int>
const int factor_N = 10000005;
const int tree_arr_N = 1000005;
using namespace std;
/*
        1.注意边界情况
        2.优先考虑时间复杂度
!!! 3.求最大值时，答案应至多初始化为INT_MIN；求最小值时，答案应至少初始化为INT_MAX
        4.遇事不决先暴力
        5.代码要写简洁
*/
// 快读
int read() {
  char c = getchar();
  int x = 0, f = 1;
  for (; !isdigit(c); c = getchar())
    if (c == '-')
      f = -1;
  for (; isdigit(c); c = getchar())
    x = x * 10 + c - 48;
  return x * f;
}
const int mod = 998244353;
int n, k, l, r;
unordered_map<int, bool> mp;
int main() {
  n = read();
  k = read();
  vector<int> dp(n + 1, 0), a;
  while (k--) {
    l = read();
    r = read();
    while (l <= r) {
      if (mp[l] != true)
        a.push_back(l), mp[l] = true;
      l++;
    }
  }
  sort(a.begin(), a.end());
  dp[1] = 1;
  for (int i = 2; i <= n; ++i) {
    for (auto step : a) {
      if (step >= i)
        break;
      dp[i] = (dp[i] + dp[i - step]) % mod;
    }
  }
  cout << dp[n] << endl;
  return 0;
}

#include <bits/stdc++.h>
#define for_int(i, a, b) for (int i = (a); i <= (b); ++i)
#define rep_int(i, a, b) for (int i = (a); i >= (b); --i)
#define for_ll(i, a, b) for (ll i = (a); i <= (b); ++i)
#define rep_ll(i, a, b) for (ll i = (a); i >= (b); --i)
#define IOS ios::sync_with_stdio(false);
#define ull unsigned long long
#define ll long long
#define db double
#define HPMAX 1005
#define KMP_MAX 1005
#define prime_MAX 1000005
#define quick_pow_mod 1000000007
#define PII pair<int, int>
const int factor_N = 10000005;
const int tree_arr_N = 1000005;
using namespace std;
/*
        1.注意边界情况
        2.优先考虑时间复杂度
!!! 3.求最大值时，答案应至多初始化为INT_MIN；求最小值时，答案应至少初始化为INT_MAX
        4.遇事不决先暴力
        5.代码要写简洁
*/
// 快读
int read() {
  char c = getchar();
  int x = 0, f = 1;
  for (; !isdigit(c); c = getchar())
    if (c == '-')
      f = -1;
  for (; isdigit(c); c = getchar())
    x = x * 10 + c - 48;
  return x * f;
}
const int mod = 998244353;
int n, k;
int main() {
  n = read();
  k = read();
  vector<ll> dp(n, 0), l(k + 1, 0), r(n + 1, 0), sum(n + 1, 0);
  for_int(i, 1, k) l[i] = read(), r[i] = read();
  dp[0] = 1;
  for_ll(i, 0, n - 1) {
    if (i == 0)
      continue;
    sum[i] = sum[i - 1] + dp[i - 1];
    for_ll(j, 1, k) {
      if (l[j] > i)
        continue;
      int t = min(r[j], i) + 1;
      dp[i] += sum[i - l[j] + 1] - sum[i - t + 1];
    }
    dp[i] %= mod;
  }
  cout << dp[n - 1] << endl;
  return 0;
}


#include <iostream>
using namespace std;
#define int long long
#define mod 998244353
int L[11], R[11];
int dp[100005];
int sum[100005];

signed main() {
  std::ios::sync_with_stdio(false);
  cin.tie(0);
  int N, K;
  cin >> N >> K;
  for (int i = 1; i <= K; i++) {
    cin >> L[i] >> R[i];
  }
  sum[1] = dp[1] = 1;
  for (int i = 2; i <= N; i++) {
    for (int j = 1; j <= K; j++) {
      if (i - L[j] < 1)
        continue;
      else if (i - R[j] < 1) {
        dp[i] = (dp[i] + sum[i - L[j]]) % mod;
      } else {
        dp[i] = (dp[i] + sum[i - L[j]]) % mod;
        dp[i] = (dp[i] - sum[i - R[j] - 1] + mod) % mod;
      }
    }
    sum[i] = (sum[i - 1] + dp[i]) % mod;
  }
  cout << dp[N] << endl;
}

#include <iostream>
using namespace std;
#define int long long
#define mod 998244353
int L[11], R[11];
int dp[200005];
int sum[200005];

signed main() {
  std::ios::sync_with_stdio(false);
  cin.tie(0);
  int N, K;
  cin >> N >> K;
  for (int i = 1; i <= K; i++) {
    cin >> L[i] >> R[i];
  }
  sum[1] = dp[1] = 1;
  for (int i = 2; i <= N; i++) {
    for (int j = 1; j <= K; j++) {
      if (i - L[j] < 1)
        continue;
      else if (i - R[j] < 1) {
        dp[i] = (dp[i] + sum[i - L[j]]) % mod;
      } else {
        dp[i] = (dp[i] + sum[i - L[j]]) % mod;
        dp[i] = (dp[i] - sum[i - R[j] - 1] + mod) % mod;
      }
    }
    sum[i] = (sum[i - 1] + dp[i]) % mod;
  }
  cout << dp[N] << endl;
}


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

const long long MOD = 998244353;
using ll = long long;

template <typename T> class LazySegmentTree {
  //[l, r)半開区間を扱う
private:
  std::vector<T> node, lazy;
  std::function<T(T, T)> f; // 取得の演算
  std::function<T(T, T)> g; // 更新の演算
  std::function<T(T, int)> pow; // 更新の演算をk回作用させたときの結果

  T f_ide; // 演算fの単位元
  T g_ide; // 演算gの単位元

  int size;

public:
  LazySegmentTree(int n, std::function<T(T, T)> f, std::function<T(T, T)> g,
                  T f_ide, T g_ide)
      : f(f), g(g), f_ide(f_ide), g_ide(g_ide) {
    init(n);
    pow = [=](T a, int k) {
      T ans = g_ide;
      while (k > 0) {
        if (k & 1)
          ans = g(ans, a);
        a = g(a, a);
        k >>= 1;
      }
      return ans;
    };
  }
  LazySegmentTree(int n, std::function<T(T, T)> f, std::function<T(T, T)> g,
                  std::function<T(T, int)> pow, T f_ide, T g_ide)
      : f(f), g(g), pow(pow), f_ide(f_ide), g_ide(g_ide) {
    init(n);
  }
  void init(int n) {
    size = 1;
    while (size < n)
      size *= 2;
    node = std::vector<T>(2 * size - 1, f_ide);
    lazy = std::vector<T>(2 * size - 1, g_ide);
  }
  void eval(int k, int l, int r) {
    node[k] = g(node[k], pow(lazy[k], r - l));

    if (r - l >= 2) {
      lazy[2 * k + 1] = g(lazy[2 * k + 1], lazy[k]);
      lazy[2 * k + 2] = g(lazy[2 * k + 2], lazy[k]);
    }

    lazy[k] = g_ide;
  }
  void update(int a, int b, T x, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = size;
    if (r <= a || b <= l)
      return;

    if (a <= l && r <= b) {
      lazy[k] = g(lazy[k], x);
      eval(k, l, r);
    } else {
      update(a, b, x, 2 * k + 1, l, (l + r) / 2);
      update(a, b, x, 2 * k + 2, (l + r) / 2, r);
      eval(2 * k + 1, l, (l + r) / 2);
      eval(2 * k + 2, (l + r) / 2, r);

      node[k] = f(node[2 * k + 1], node[2 * k + 2]);
    }
  }
  T get(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = size;
    if (r <= a || b <= l)
      return f_ide;

    eval(k, l, r);

    if (a <= l && r <= b) {
      return node[k];
    } else {
      T result_left = get(a, b, 2 * k + 1, l, (l + r) / 2);
      T result_right = get(a, b, 2 * k + 2, (l + r) / 2, r);
      return f(result_left, result_right);
    }
  }
};
/*
int main(){
    int n,q;std::cin >> n >> q;
    std::function<long long(long long, long long)> f = [](long long a, long long
b){ return a + b;
    };
    auto g = f;
    LazySegmentTree<long long> Seg(n, f, g, 0, 0);
    while(q--){
        int a;std::cin >> a;
        if(a == 0){
            int s,t,x;
            std::cin >> s >> t >> x;
            Seg.update(s - 1, t, x);
        }else{
            int s,t;
            std::cin >> s >> t;
            std::cout<<Seg.get(s - 1, t)<<std::endl;
        }
    }
}
*/

void solve(long long N, long long K, std::vector<long long> L,
           std::vector<long long> R) {
  std::function<long long(long long, long long)> f =
      [](long long a, long long b) { return (a + b) % MOD; };
  std::function<long long(long long, int)> pow = [](long long a, int b) {
    return (a * b) % MOD;
  };
  auto g = f;
  LazySegmentTree<long long> Seg(N, f, g, pow, 0, 0);
  Seg.update(0, 1, 1);
  for (int i = 0; i < N; i++) {
    for (int k = 0; k < K; k++) {
      ll l = i + L[k];
      ll r = i + R[k] + 1;
      ll x = Seg.get(i, i + 1);
      if (l >= N) {
        continue;
      }
      Seg.update(l, min(r, N), x);
    }
  }
  cout << Seg.get(N - 1, N) << endl;
}

int main() {
  long long N;
  scanf("%lld", &N);
  long long K;
  scanf("%lld", &K);
  std::vector<long long> L(K);
  std::vector<long long> R(K);
  for (int i = 0; i < K; i++) {
    scanf("%lld", &L[i]);
    scanf("%lld", &R[i]);
  }
  solve(N, K, std::move(L), std::move(R));
  return 0;
}

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

const long long MOD = 998244353;
using ll = long long;

template <typename T> class LazySegmentTree {
  //[l, r)半開区間を扱う
private:
  std::vector<T> node, lazy;

  T f_ide; // 演算fの単位元
  T g_ide; // 演算gの単位元

  int size;

public:
  LazySegmentTree(int n, T f_ide, T g_ide) : f_ide(f_ide), g_ide(g_ide) {
    init(n);
  }
  void init(int n) {
    size = 1;
    while (size < n)
      size *= 2;
    node = std::vector<T>(2 * size - 1, f_ide);
    lazy = std::vector<T>(2 * size - 1, g_ide);
  }
  void eval(int k, int l, int r) {
    node[k] = g(node[k], pow(lazy[k], r - l));

    if (r - l >= 2) {
      lazy[2 * k + 1] = g(lazy[2 * k + 1], lazy[k]);
      lazy[2 * k + 2] = g(lazy[2 * k + 2], lazy[k]);
    }

    lazy[k] = g_ide;
  }
  ll f(ll l, ll r) { return (l + r) % MOD; }
  ll g(ll l, ll r) { return (l + r) % MOD; }
  ll pow(ll x, ll y) { return (x * y) % MOD; }
  void update(int a, int b, T x, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = size;
    if (r <= a || b <= l)
      return;

    if (a <= l && r <= b) {
      lazy[k] = g(lazy[k], x);
      eval(k, l, r);
    } else {
      update(a, b, x, 2 * k + 1, l, (l + r) / 2);
      update(a, b, x, 2 * k + 2, (l + r) / 2, r);
      eval(2 * k + 1, l, (l + r) / 2);
      eval(2 * k + 2, (l + r) / 2, r);

      node[k] = f(node[2 * k + 1], node[2 * k + 2]);
    }
  }
  T get(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = size;
    if (r <= a || b <= l)
      return f_ide;

    eval(k, l, r);

    if (a <= l && r <= b) {
      return node[k];
    } else {
      T result_left = get(a, b, 2 * k + 1, l, (l + r) / 2);
      T result_right = get(a, b, 2 * k + 2, (l + r) / 2, r);
      return f(result_left, result_right);
    }
  }
};
/*
int main(){
    int n,q;std::cin >> n >> q;
    std::function<long long(long long, long long)> f = [](long long a, long long
b){ return a + b;
    };
    auto g = f;
    LazySegmentTree<long long> Seg(n, f, g, 0, 0);
    while(q--){
        int a;std::cin >> a;
        if(a == 0){
            int s,t,x;
            std::cin >> s >> t >> x;
            Seg.update(s - 1, t, x);
        }else{
            int s,t;
            std::cin >> s >> t;
            std::cout<<Seg.get(s - 1, t)<<std::endl;
        }
    }
}
*/

void solve(long long N, long long K, std::vector<long long> L,
           std::vector<long long> R) {

  LazySegmentTree<long long> Seg(N, 0LL, 0LL);
  Seg.update(0, 1, 1);
  for (int i = 0; i < N; i++) {
    for (int k = 0; k < K; k++) {
      ll l = i + L[k];
      ll r = i + R[k] + 1;
      ll x = Seg.get(i, i + 1);
      if (l >= N) {
        continue;
      }
      Seg.update(l, min(r, N), x);
    }
  }
  cout << Seg.get(N - 1, N) << endl;
}

int main() {
  long long N;
  scanf("%lld", &N);
  long long K;
  scanf("%lld", &K);
  std::vector<long long> L(K);
  std::vector<long long> R(K);
  for (int i = 0; i < K; i++) {
    scanf("%lld", &L[i]);
    scanf("%lld", &R[i]);
  }
  solve(N, K, std::move(L), std::move(R));
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define reps(i, s, n) for (int i = (s); i < (n); i++)
#define rrep(i, n) for (int i = (n)-1; i >= 0; i--)
#define rreps(i, s, n) for (int i = (n)-1; i >= (s); i--)
#define INF ~(1 << 31)
#define INFL ~(1LL << 63)
#define mod 998244353LL

int main() {
  int n, k;
  cin >> n >> k;
  vector<pair<int, int>> d(k);
  rep(i, k) { cin >> d[i].first >> d[i].second; }

  vector<ll> dp(n + 1);
  dp[1] = 1;
  reps(i, 2, n + 1) {
    rep(j, k) {
      reps(l, d[j].first, d[j].second + 1) {
        if (i - l < 1)
          continue;
        dp[i] = (dp[i] + dp[i - l]) % mod;
      }
    }
  }
  cout << dp[n] << endl;
}

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define reps(i, s, n) for (int i = (s); i < (n); i++)
#define rrep(i, n) for (int i = (n)-1; i >= 0; i--)
#define rreps(i, s, n) for (int i = (n)-1; i >= (s); i--)
#define INF ~(1 << 31)
#define INFL ~(1LL << 63)
#define mod 998244353LL

int main() {
  int n, k;
  cin >> n >> k;
  vector<pair<int, int>> d(k);
  rep(i, k) { cin >> d[i].first >> d[i].second; }

  vector<ll> dp(n + 1);
  dp[1] = 1;
  reps(i, 2, n + 1) {
    rep(j, k) {
      int f = i - d[j].first, s = max(i - d[j].second, 1);
      if (f < 1)
        continue;
      else if (s == 1)
        dp[i] = (dp[i] + dp[f]) % mod;
      else
        dp[i] = (dp[i] - dp[s - 1] + dp[f]) % mod;
    }
    dp[i] = (dp[i] + dp[i - 1]) % mod;
  }
  if (dp[n] < dp[n - 1])
    dp[n] += mod;
  cout << dp[n] - dp[n - 1] << endl;
}


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

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

  vector<pair<int, int>> D(K);
  rep(i, K) cin >> D.at(i).first >> D.at(i).second;

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

  ll mod = 998244353;

  vector<ll> dp(N + 1, 0);
  dp.at(1) = 1;
  for (int i = 1; i < N; i++) {
    for (int j = 0; j < K; j++) {
      pair<int, int> d = D.at(j);

      ll k_min = max(1, d.first);
      ll k_max = min(i, d.second);
      for (int k = k_min; k <= k_max; k++) {
        dp.at(i + 1) += dp.at(i + 1 - k);
        dp.at(i + 1) %= mod;
      }
    }
  }

  cout << dp.at(N) << endl;
  return 0;
}

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

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

  vector<pair<int, int>> D(K);
  rep(i, K) cin >> D.at(i).first >> D.at(i).second;

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

  ll mod = 998244353;

  vector<ll> dp(N + 1, 0);
  vector<ll> dp2(K, 0);
  dp.at(1) = 1;
  for (int i = 1; i < N; i++) {
    for (int j = 0; j < K; j++) {
      pair<int, int> d = D.at(j);

      if (i - d.second >= 0) {
        dp2.at(j) -= dp.at(i - d.second);
      }

      if (i + 1 - d.first >= 0) {
        dp2.at(j) += dp.at(i + 1 - d.first);
      }

      while (dp2.at(j) < 0) {
        dp2.at(j) += mod;
      }
      dp2.at(j) %= mod;
      dp.at(i + 1) += dp2.at(j);
      dp.at(i + 1) %= mod;
    }
  }

  cout << dp.at(N) << endl;
  return 0;
}


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

int main() {
  int N, K;
  cin >> N >> K;
  vector<ll> dp(N, 0);
  dp.at(0) = 1;
  vector<int> S;
  int x, y;
  const int mod = 998244353;

  rep(i, K) {
    cin >> x >> y;
    for (int i = x; i <= y; i++)
      S.push_back(i);
  }
  sort(S.begin(), S.end());
  rep(i, N) {
    for (auto e : S) {
      if (i + e < N) {
        dp.at(i + e) += dp.at(i);
        dp.at(i + e) %= mod;
      } else
        break;
    }
  }
  cout << dp.at(N - 1) << endl;
  return 0;
}

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

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

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

int main() {
  int N, K;
  cin >> N >> K;
  vector<mint> wa(N + 1, 0);
  wa.at(1) = 1;
  vector<P> p(K);
  int x, y;

  rep(i, K) {
    cin >> x >> y;
    p.at(i) = make_pair(x, y);
  }

  for (int i = 1; i < N; i++) {
    mint sum = 0;
    rep(j, K) {
      int r = max(i - (p.at(j).first) + 1, 0);
      int l = max(i - (p.at(j).second), 0);

      sum += wa.at(r) - wa.at(l);
    }
    wa.at(i + 1) = wa.at(i) + sum;
  }

  cout << wa.at(N) - wa.at(N - 1) << endl;
  return 0;
}


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

const int mod = 998244353;
int dp[200010];

int main() {
  int n, k;
  cin >> n >> k;

  vector<P> act;
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    act.emplace_back(l, r);
  }

  dp[0] = 1;
  rep(i, n) {
    for (auto a : act) {
      int l = a.first;
      int r = a.second;
      for (int j = l; j < r + 1; ++j) {
        int nx = i + j;
        if (nx >= n)
          continue;
        dp[nx] = (dp[nx] + dp[i]) % mod;
      }
    }
  }

  int ans = dp[n - 1];
  cout << ans << endl;

  return 0;
}

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

const int mod = 998244353;
int dp[200010];
int main() {

  int n, k;
  cin >> n >> k;
  vector<P> act;
  vector<int> sum(n + 1, 0);
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    act.emplace_back(l, r);
  }

  dp[0] = 0;
  dp[1] = 1;
  sum[0] = 0;
  sum[1] = 1;
  for (int i = 2; i < n + 1; ++i) {
    for (auto a : act) {
      int l = a.first;
      int r = a.second;

      l = max(0, i - l);
      r = max(0, i - r - 1);
      int p = (sum[l] - sum[r]) % mod;
      if (p < 0)
        p += mod;
      dp[i] = (dp[i] + p) % mod;
    }
    sum[i] = (sum[i - 1] + dp[i]) % mod;
  }
  cout << dp[n] << endl;
  return 0;
}


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

int main() {
  long long l, r, n, mod = 998244353, k;
  cin >> n >> k;
  vector<long long> a;
  for (int i = 0; i < k; i++) {
    cin >> l >> r;
    for (int j = l; j <= r; j++)
      a.push_back(j);
  }
  sort(a.begin(), a.end());
  vector<long long> dp(n + 1, 0);
  dp[1] = 1;
  for (int i = 2; i < n + 1; i++) {
    for (int j = 0; j < a.size(); j++) {
      if (i - a[j] > 0)
        dp[i] = (dp[i] + dp[i - a[j]]) % mod;
    }
  }
  cout << dp[n] << endl;

  return 0;
}

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

int main() {
  long long l, r, n, mod = 998244353, k, maxi1, maxi2;
  cin >> n >> k;
  vector<long long> a;
  vector<pair<long long, long long>> pr(k);
  for (int i = 0; i < k; i++) {
    cin >> pr[i].first >> pr[i].second;
    // for(int j=l;j<=r;j++) a.push_back(j);
  }
  // sort(a.begin(), a.end());
  vector<long long> dp(n + 1, 0);
  vector<long long> cumdp(n + 1, 0);
  dp[1] = 1;
  cumdp[1] = 1;
  for (int i = 2; i < n + 1; i++) {
    for (int j = 0; j < k; j++) {
      maxi1 = i - pr[j].second - 1;
      if (maxi1 < 0)
        maxi1 = 0;
      maxi2 = i - pr[j].first;
      if (maxi2 < 0)
        maxi2 = 0;
      dp[i] = ((dp[i] + cumdp[maxi2]) % mod - cumdp[maxi1] + mod) % mod;
    }
    //    cout<<dp[i]<<endl;
    cumdp[i] = (cumdp[i - 1] + dp[i]) % mod;
  }
  cout << dp[n] << endl;

  return 0;
}


#include <algorithm>
#include <iostream>
#include <set>
#include <string>
#include <vector>

using namespace std;
typedef long long ll;

int main(void) {
  ll N, K;
  cin >> N >> K;
  vector<pair<ll, ll>> ranges(K);
  vector<ll> diffs(N + 1, 0);
  vector<ll> paths(N + 1, 0);
  paths[1] = 1;
  ll cur = 0;
  for (ll i = 0; i < K; i++) {
    int l, r;
    cin >> l >> r;
    ranges[i] = make_pair(l, r);
  }
  for (ll i = 1; i <= N; i++) {
    cur += diffs[i];
    paths[i] += cur;
    paths[i] = paths[i] % 998244353;
    if (paths[i] > 0) {
      for (ll j = 0; j < K; j++) {
        if (i + ranges[j].first <= N) {
          diffs[i + ranges[j].first] += paths[i];
          diffs[min(N + 1, i + ranges[j].second + 1)] -= paths[i];
        }
      }
    }
  }
  cout << paths[N] << endl;
  return 0;
}

#include <algorithm>
#include <iostream>
#include <set>
#include <string>
#include <vector>

using namespace std;
typedef long long ll;

int main(void) {
  ll N, K;
  cin >> N >> K;
  vector<pair<ll, ll>> ranges(K);
  vector<ll> diffs(N + 2, 0);
  vector<ll> paths(N + 2, 0);
  paths[1] = 1;
  ll cur = 0;
  for (ll i = 0; i < K; i++) {
    int l, r;
    cin >> l >> r;
    ranges[i] = make_pair(l, r);
  }
  for (ll i = 1; i <= N; i++) {
    cur += diffs[i];
    paths[i] += cur;
    paths[i] = paths[i] % 998244353;
    if (paths[i] > 0) {
      for (ll j = 0; j < K; j++) {
        if (i + ranges[j].first <= N) {
          diffs[i + ranges[j].first] += paths[i];
          diffs[min(N + 1, i + ranges[j].second + 1)] -= paths[i];
        }
      }
    }
  }
  cout << paths[N] << endl;
  return 0;
}


#include <algorithm>
#include <bits/stdc++.h>
#include <iostream>
#include <math.h>
#include <numeric>
#include <string>
#include <vector>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;
#define chmax(x, y) x = max(x, y)
int INF = 1e9;
ll LINF = 1e18;

// int main(){
// 	ll n;
// 	int x,m;cin >> n >> x >> m;
// 	vector<int> res(100005);
// 	ll temp = x;
// 	ll len = 1;
// 	bool flag = false;
// 	while(true){
// 		temp %= m;
// 		cout << temp << endl;
// 		if(temp == 0) flag = true;
// 		if(res[temp]!=0) break;
// 		res[temp]++;
// 		temp *= temp;
// 		len++;
// 	}
// 	len--;
// 	ll ans = 0;
// 	if(flag){
// 		rep(i,m) if(res[i]!=0) ans += i;
// 		cout << ans << endl;
// 		return 0;
// 	}
// 	rep(i,m) if(res[i]!=0) ans += i;
// 	cout << ans << endl;
// 	ans += (n-len)*temp;
// 	//rep(i,20) if(res[i]!=0) cout << len << endl;
// 	// temp = x;
// 	// rep(i,n%len){
// 	// 	temp %= m;
// 	// 	ans += temp;
// 	// 	temp *= temp;
// 	// }
// 	cout << ans << endl;

// }

int main() {
  int mod = 998244353;
  int n, k;
  cin >> n >> k;
  vector<int> width;
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    for (int j = l; j <= r; j++)
      width.push_back(j);
  }
  sort(width.begin(), width.end());

  vector<int> dp(200050, 0);
  dp[1] = 1;
  for (int i = 1; i <= n; i++) {
    for (int v : width) {
      if (v + i > n || dp[i] == 0)
        break;
      dp[i + v] += dp[i];
      dp[i + v] %= mod;
    }
  }
  cout << dp[n] << endl;
}

#include <algorithm>
#include <bits/stdc++.h>
#include <iostream>
#include <math.h>
#include <numeric>
#include <string>
#include <vector>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;
#define chmax(x, y) x = max(x, y)
int INF = 1e9;
ll LINF = 1e18;

// int main(){
// 	ll n;
// 	int x,m;cin >> n >> x >> m;
// 	vector<int> res(100005);
// 	ll temp = x;
// 	ll len = 1;
// 	bool flag = false;
// 	while(true){
// 		temp %= m;
// 		cout << temp << endl;
// 		if(temp == 0) flag = true;
// 		if(res[temp]!=0) break;
// 		res[temp]++;
// 		temp *= temp;
// 		len++;
// 	}
// 	len--;
// 	ll ans = 0;
// 	if(flag){
// 		rep(i,m) if(res[i]!=0) ans += i;
// 		cout << ans << endl;
// 		return 0;
// 	}
// 	rep(i,m) if(res[i]!=0) ans += i;
// 	cout << ans << endl;
// 	ans += (n-len)*temp;
// 	//rep(i,20) if(res[i]!=0) cout << len << endl;
// 	// temp = x;
// 	// rep(i,n%len){
// 	// 	temp %= m;
// 	// 	ans += temp;
// 	// 	temp *= temp;
// 	// }
// 	cout << ans << endl;

// }

int main() {
  int mod = 998244353;
  int n, k;
  cin >> n >> k;
  vector<P> step(k);
  vector<ll> ans(200050), cum(200050);
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    step[i] = make_pair(l, r);
  }
  cum[1] = 1;
  ans[1] = 1;
  for (int i = 2; i <= n; i++) {
    for (P p : step) {
      if (i - p.first < 0)
        continue;
      int li = i - p.second;
      int ri = i - p.first;
      li = max(li, 1);
      ans[i] += cum[ri] - cum[li - 1];
      ans[i] %= mod;
      if (ans[i] < 0)
        ans[i] += mod;
    }
    cum[i] = (cum[i - 1] + ans[i]) % mod;
  }
  // rep(i,n+1)cout << ans[i] << endl;
  cout << ans[n] << endl;
}


#include <bits/stdc++.h>
using namespace std;
int n, k;
vector<pair<int, int>> pos;
vector<int> dp;
const int M = 998244353;
int solve(int cpos) {
  if (cpos == n)
    return 1;
  if (cpos > n)
    return 0;
  if (dp[cpos] != -1)
    return dp[cpos];
  int ans = 0;
  for (auto &i : pos) {
    for (int j = i.first; j <= i.second; j++) {
      if (cpos + j > n)
        break;
      else
        ans = (ans + solve(cpos + j)) % M;
    }
  }
  return dp[cpos] = ans;
}

int main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  cin >> n >> k;
  pos.resize(k);
  for (auto &i : pos)
    cin >> i.first >> i.second;
  sort(pos.begin(), pos.end());
  dp.resize(n + 1, -1);
  cout << solve(1) << "\\n";
}

#include <bits/stdc++.h>
using namespace std;
int n, k;
vector<pair<int, int>> pos;
vector<int> dp;
const int M = 998244353;

int main() {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  cin >> n >> k;
  pos.resize(k);
  for (auto &i : pos)
    cin >> i.first >> i.second;
  sort(pos.begin(), pos.end());
  dp.resize(n + 2);
  dp[n] = 1;
  for (int i = n - 1; i >= 1; i--) {
    for (auto &j : pos) {
      if (i + j.first > n)
        break;
      int l = i + j.first, h = min(n, i + j.second);
      dp[i] = (dp[i] + (dp[l] - dp[h + 1])) % M;
      while (dp[i] < 0)
        dp[i] += M;
    }
    if (i == 1)
      break;
    dp[i] = (dp[i] + dp[i + 1]) % M;
  }
  cout << dp[1] << "\\n";
}


#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int Mod = 998244353, N = 1e5 + 5;
const int INF = 0x3f3f3f3f;
LL f[N], a[N], b[N], c[20];
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    cin >> a[i] >> b[i];
  }
  f[1] = 1;
  for (int i = 2; i <= n; ++i) {
    for (int j = 0; j < m; ++j) {
      c[j] += (i - a[j] >= 1 ? f[i - a[j]] : 0) -
              (i - b[j] - 1 >= 1 ? f[i - b[j] - 1] : 0);
      f[i] = (f[i] + c[j]) % Mod;
    }
  }
  cout << (f[n] + Mod) % Mod << endl;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int Mod = 998244353, N = 2e5 + 5;
const int INF = 0x3f3f3f3f;
LL f[N], a[20], b[20], c[20];
int main() {
#ifndef ONLINE_JUDGE
  freopen("in.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    cin >> a[i] >> b[i];
  }
  f[1] = 1;
  for (int i = 2; i <= n; ++i) {
    for (int j = 0; j < m; ++j) {
      c[j] += (i - a[j] >= 1 ? f[i - a[j]] : 0) -
              (i - b[j] - 1 >= 1 ? f[i - b[j] - 1] : 0);
      f[i] = (f[i] + c[j]) % Mod;
    }
  }
  cout << f[n] << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair

void solve(int test) {

  long long n;
  cin >> n;
  long long hell = 998244353;

  long long i, j;

  vector<long long> dp(n + 1, 0LL);

  long long k;
  cin >> k;

  vector<pair<long long, long long>> v(k);

  vector<long long> moves;

  for (i = 0; i < k; i++) {
    cin >> v[i].first;
    cin >> v[i].second;

    for (j = v[i].first; j <= v[i].second; j++)
      moves.pb(j);
  }

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

  dp[1] = 1;

  for (i = 2; i <= n; i++) {
    int lb = lower_bound(moves.begin(), moves.end(), i) - moves.begin();

    if (lb == 0)
      continue;
    for (j = 0; j < lb; j++) {
      dp[i] = (dp[i] + dp[i - moves[j]]) % hell;
    }
  }

  cout << dp[n] << endl;

  return;
}

int main() {

  int t = 1;
  // cin>>t;

  for (int x = 1; x <= t; x++) {
    solve(x);
  }
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair

void solve(int test) {

  long long n;
  cin >> n;
  long long hell = 998244353;

  long long i, j;

  vector<long long> dp(n + 1, 0LL);

  long long k;
  cin >> k;

  vector<pair<long long, long long>> v(k);

  for (i = 0; i < k; i++) {
    cin >> v[i].first;
    cin >> v[i].second;
  }
  sort(v.begin(), v.end());

  dp[1] = 1;
  vector<long long> prefix(n + 2, 0LL);
  prefix[1] = 1LL;

  for (i = 2; i <= n; i++) {
    for (j = 0; j < v.size(); j++) {
      if (v[j].first >= i)
        break;
      long long l = max(1LL, i - v[j].first);
      long long r = max(1LL, i - v[j].second);

      // cout<<l<<" "<<r<<endl;

      dp[i] = (dp[i] + prefix[l] - prefix[r - 1]) % hell;
    }

    dp[i] = dp[i] % hell;
    if (dp[i] < 0)
      dp[i] = dp[i] + hell;
    dp[i] = dp[i] % hell;

    prefix[i] = (prefix[i - 1] + dp[i]) % hell;
  }

  cout << dp[n] << endl;

  return;
}

int main() {

  int t = 1;
  // cin>>t;

  for (int x = 1; x <= t; x++) {
    solve(x);
  }
  return 0;
}


#include <algorithm> //sort(a.begin(), a.end());reverse(a.begin(), a.end());
#include <bits/stdc++.h>
#include <iostream>
#include <math.h> //pow(x,y)=x^y 99999とかの場合+1するif文
#define ll long long
#define rep(init, i, n) for (ll i = init; i < (n); i++)
#define rev(s) reverse(s.begin(), s.end())
#define sor(v) sort(v.begin(), v.end())
#define PI 3.14159265358979323846264338327950L
// コード自動整形 Shift + Option + F @vscode
using namespace std;
using vec = vector<ll>;

ll facctorialMethod(ll k); // 階乗を出力する
/////main/////
int main() {
  ll mod = 998244353;
  ll N, K;
  cin >> N >> K;
  vec L(K), R(K);
  vec dp(N, 0);

  rep(0, i, K) { cin >> L.at(i) >> R.at(i); }

  dp.at(0) = 1;

  rep(0, x, N) rep(0, i, K) rep(L.at(i), j, R.at(i) + 1) {
    if (x + j < N) {
      dp.at(x + j) += dp.at(x);
      dp.at(x + j) %= mod;
    }
  }
  cout << dp.at(N - 1) << endl;
}
/////main/////

/////function/////
ll facctorialMethod(ll k) {
  ll sum = 1;
  for (ll i = 1; i <= k; ++i) {
    sum *= i;
  }
  return sum;
}

#include <algorithm> //sort(a.begin(), a.end());reverse(a.begin(), a.end());
#include <bits/stdc++.h>
#include <iostream>
#include <math.h> //pow(x,y)=x^y 99999とかの場合+1するif文
#define ll long long
#define rep(init, i, n) for (ll i = init; i < (n); i++)
#define rev(s) reverse(s.begin(), s.end())
#define sor(v) sort(v.begin(), v.end())
#define PI 3.14159265358979323846264338327950L
// コード自動整形 Shift + Option + F @vscode
using namespace std;
using vec = vector<ll>;

ll facctorialMethod(ll k); // 階乗を出力する
/////main/////
int main() {
  ll mod = 998244353;
  ll N, K, li, ri;
  cin >> N >> K;
  vec L(K), R(K);
  vec dp(N + 1, 0), dpsum(N + 1, 0);

  rep(0, i, K) { cin >> L.at(i) >> R.at(i); }

  dp.at(1) = 1;
  dpsum.at(1) = 1;
  rep(2, x, N + 1) {
    rep(0, i, K) {
      li = x - R.at(i);
      ri = x - L.at(i);
      /*
      cout << "li=" << li << endl;
      cout << "ri=" << ri << endl;
      */
      if (ri < 0)
        continue;
      li = max(li, (ll)1);

      //
      /*
      cout << "i=" << i << endl;
      cout << "R.at(" << i << ")=" << R.at(i) << endl;
      cout << "L.at(" << i << ")=" << L.at(i) << endl;
      cout << "li=" << li << endl;
      cout << "dp.at(" << x << ")=" << dp.at(x) << endl;
      */
      dp.at(x) += dpsum.at(ri);
      dp.at(x) -= dpsum.at(li - 1);
      dp.at(x) += mod;
      dp.at(x) %= mod;
      /*
      cout << "dpsum.at(" << ri << ")=" << dpsum.at(ri) << endl;
      cout << "dpsum.at(" << li - 1 << ")=" << dpsum.at(li - 1) << endl;
      cout << "dp.at(" << x << ")=" << dp.at(x) << endl;
      */
    }
    // cout << dp.at(x) << endl;
    dpsum.at(x) = dpsum.at(x - 1) + dp.at(x);
    /*
    cout << "dpsum.at(" << x << ")=" << dpsum.at(x) << endl;
    */
    dpsum.at(x) %= mod;
  }

  /*rep(0, x, N) rep(0, i, K) rep(L.at(i), j, R.at(i) + 1)
  {
      if (x + j < N)
      {
          dp.at(x + j) += dp.at(x);
          dp.at(x + j) %= mod;
      }
  }*/
  /*rep(0,i,N){cout<<dpsum.at(i)<<endl;
  }*/
  cout << dp.at(N) << endl;
}
/////main/////

/////function/////
ll facctorialMethod(ll k) {
  ll sum = 1;
  for (ll i = 1; i <= k; ++i) {
    sum *= i;
  }
  return sum;
}


/*~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
*$* WRITER:kakitamasziru/OxOmisosiru *$*
~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=*/
#ifdef LOCAL_JUDGE
#define _GLIBCXX_DEBUG
#endif
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <bitset>    // bitset
#include <cmath>     //abs,,,
#include <cstdint>   // int64_t, int*_t
#include <deque>     // deque
#include <iomanip>
#include <iostream> // cout, endl, cin
#include <limits>   //setprecision
#include <map>      // map
#include <math.h>   //pow,,,
#include <numeric>  //accumulate,,,
#include <queue>    // queue, priority_queue
#include <set>      // set,multiset
#include <stack>    // stack
#include <string>   // string, to_string, stoi
#include <tuple>    // tuple, make_tuple
#include <utility>  // pair, make_pair
#include <vector>   // vector
// #define endl "\\n";
using namespace std;

const long long INF = 4000000000000000001;
const int inf = 1001001001;
long long MOD = 998244353;

void chmax(long long &a, long long b) {
  if (a < b)
    a = b;
}
void chmin(long long &a, long long b) {
  if (a > b)
    a = b;
}

// Solve N^M. This, mod_pow use Iterative Square Method.
long long mod_pow(long long N, long long M) {
  if (M == 0)
    return 1;
  long long res = mod_pow((N * N) % MOD, M / 2);
  // When end-of-a bit is 1, times simple N.
  if (M & 1)
    res = (res * N) % MOD;
  return res %= MOD;
}
long long gcd(long long a, long long b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }

// dp[i]:そのマスへの来方の総和
long long dp[200005];

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

  long long N;
  int K;
  cin >> N >> K;
  vector<long long> move;
  for (int i = 0; i < K; i++) {
    int f, t;
    cin >> f >> t;
    for (int j = f; j <= t; j++) {
      move.push_back(j);
    }
  }
  sort(move.begin(), move.end());
  for (int i = 0; i < 200005; i++)
    dp[i] = 0;
  dp[N] = 1;
  for (long long i = N; i >= 1; i--) {
    for (int j = 0; j < move.size(); j++) {
      if (i - move.at(j) < 1)
        break;
      dp[i - move.at(j)] += dp[i];
      dp[i - move.at(j)] %= MOD;
    }
  }
  cout << dp[1] << endl;
}

/*~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
*$* WRITER:kakitamasziru/OxOmisosiru *$*
~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=*/
#ifdef LOCAL_JUDGE
#define _GLIBCXX_DEBUG
#endif
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <bitset>    // bitset
#include <cmath>     //abs,,,
#include <cstdint>   // int64_t, int*_t
#include <deque>     // deque
#include <iomanip>
#include <iostream> // cout, endl, cin
#include <limits>   //setprecision
#include <map>      // map
#include <math.h>   //pow,,,
#include <numeric>  //accumulate,,,
#include <queue>    // queue, priority_queue
#include <set>      // set,multiset
#include <stack>    // stack
#include <string>   // string, to_string, stoi
#include <tuple>    // tuple, make_tuple
#include <utility>  // pair, make_pair
#include <vector>   // vector
// #define endl "\\n";
using namespace std;

const long long INF = 4000000000000000001;
const int inf = 1001001001;
long long MOD = 998244353;

void chmax(long long &a, long long b) {
  if (a < b)
    a = b;
}
void chmin(long long &a, long long b) {
  if (a > b)
    a = b;
}

// Solve N^M. This, mod_pow use Iterative Square Method.
long long mod_pow(long long N, long long M) {
  if (M == 0)
    return 1;
  long long res = mod_pow((N * N) % MOD, M / 2);
  // When end-of-a bit is 1, times simple N.
  if (M & 1)
    res = (res * N) % MOD;
  return res %= MOD;
}
long long gcd(long long a, long long b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }

// dp[i]:そのマスへの来方の総和
long long dp[200005];
long long rui[200005];

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

  long long N;
  int K;
  cin >> N >> K;
  vector<pair<int, int>> move(K);
  for (int i = 0; i < K; i++)
    cin >> move.at(i).first >> move.at(i).second;
  for (int i = 0; i < 200005; i++)
    dp[i] = 0, rui[i] = 0;
  dp[0] = 1;
  rui[1] = 1;
  for (int i = 0; i < N; i++) {
    for (pair<int, int> P : move) {
      int left = max(i - P.second, 0), right = max(i - P.first + 1, 0);
      dp[i] += rui[right] - rui[left];
      dp[i] %= MOD;
      if (dp[i] < 0)
        dp[i] += MOD;
    }
    // cout << dp[i] << " ";
    rui[i + 1] = rui[i] + dp[i];
    rui[i + 1] %= MOD;
    if (rui[i + 1] < 0)
      rui[i + 1] += MOD;
  }
  // for(int i = 0;i<=N;i++) cout << dp[i] << " ";
  // cout << endl;
  cout << dp[N - 1] << endl;
}


#include <algorithm>
#include <cassert>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using ll = long long;
const int mod = 998244353;

#define read_int(X)                                                            \\
  ll X;                                                                        \\
  scanf("%lld\\n", &X);

#define read_two_int(X, Y)                                                     \\
  ll X, Y;                                                                     \\
  scanf("%lld %lld\\n", &X, &Y);

#define read_three_int(X, Y, Z)                                                \\
  ll X, Y, Z;                                                                  \\
  scanf("%lld %lld %lld\\n", &X, &Y, &Z);

#define read_four_int(X, Y, Z, W)                                              \\
  ll X, Y, Z, W;                                                               \\
  scanf("%lld %lld %lld %lld\\n", &X, &Y, &Z, &W);

vector<ll> dp(2 * 10e5, -1);
ll calc(ll n, vector<pair<ll, ll>> *lr) {
  if (dp[n] != -1)
    return dp[n];

  ll sum = 0;
  for (ll i = 0; i < (*lr).size(); i++) {
    for (ll j = (*lr)[i].first; j <= (*lr)[i].second; j++) {
      if (n - j > 0) {
        sum += calc(n - j, lr) % mod;
        continue;
      }

      if (n == j) {
        sum += 1;
      }

      break;
    }
  }

  dp[n] = sum % mod;
  return dp[n];
}

int main() {
  read_two_int(N, K);
  vector<pair<ll, ll>> lr(K);
  for (ll i = 0; i < K; i++) {
    scanf("%lld", &(lr[i].first));
    scanf("%lld", &(lr[i].second));
  }

  // ll ans = calc(N - 1, &lr);

  vector<ll> dp(N, 0);
  dp[0] = 1;
  for (ll i = 1; i < N; i++) {
    ll sum = 0;
    for (ll k = 0; k < K; k++)
      for (ll j = lr[k].first; j <= lr[k].second; j++) {
        if (i - j >= 0) {
          sum += dp[i - j];
          sum %= mod;
        } else {
          break;
        }
      }
    dp[i] = sum;
  }
  ll ans = dp[N - 1];

  printf("%lld\\n", ans);
}

#include <algorithm>
#include <cassert>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using ll = long long;
const int mod = 998244353;

#define read_int(X)                                                            \\
  ll X;                                                                        \\
  scanf("%lld\\n", &X);

#define read_two_int(X, Y)                                                     \\
  ll X, Y;                                                                     \\
  scanf("%lld %lld\\n", &X, &Y);

#define read_three_int(X, Y, Z)                                                \\
  ll X, Y, Z;                                                                  \\
  scanf("%lld %lld %lld\\n", &X, &Y, &Z);

#define read_four_int(X, Y, Z, W)                                              \\
  ll X, Y, Z, W;                                                               \\
  scanf("%lld %lld %lld %lld\\n", &X, &Y, &Z, &W);

int main() {
  read_two_int(N, K);
  vector<pair<ll, ll>> lr(K);
  for (ll i = 0; i < K; i++) {
    scanf("%lld", &(lr[i].first));
    scanf("%lld", &(lr[i].second));
  }

  vector<ll> dp(N, 0);
  dp[0] = 1;
  for (ll i = 1; i < N; i++) {
    ll sum = 0;
    for (ll k = 0; k < K; k++) {
      ll diff = 0;
      if (i - lr[k].first >= 0)
        diff = dp[i - lr[k].first];
      if (i - lr[k].second - 1 >= 0)
        diff -= dp[i - lr[k].second - 1];
      sum += diff;
      sum %= mod;
    }

    dp[i] = sum + dp[i - 1];
  }
  ll ans = dp[N - 1] - dp[N - 2];

  printf("%lld\\n", ans);
}


#include <bits/stdc++.h>
// #include <atcoder/all>

using namespace std;
// using namespace atcoder;

#ifdef DEBUG
#include "debug.h"
#define dump(...)                                                              \\
  DUMPOUT << "  " << string(#__VA_ARGS__) << ": "                              \\
          << "[" << to_string(__LINE__) << ":" << __FUNCTION__ << "]" << endl  \\
          << "    ",                                                           \\
      dump_func(__VA_ARGS__)
#else
#define dump(...)
#endif

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

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

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

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

#define int long long
#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define YES puts("YES")
#define Yes puts("Yes")
#define NO puts("NO")
#define No puts("No")
#define ALL(v) (v).begin(), (v).end()
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

/*
#define mod 1000000007 /*/
#define mod 998244353 //*/

typedef pair<int, int> P;
#define INF (1LL << 60)

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

using mint = Fp<mod>;

struct LazySegmentTree {
public:
  int n;
  vector<mint> node, lazy;

public:
  LazySegmentTree(vector<mint> v) {
    int sz = (int)v.size();
    n = 1;
    while (n < sz)
      n *= 2;
    node.resize(2 * n - 1);
    lazy.resize(2 * n - 1, 0);

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

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

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

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

void solve() {
  int N, K;
  cin >> N >> K;
  vector<int> L(K), R(K);
  rep(i, K) { cin >> L[i] >> R[i]; }

  LazySegmentTree seg(vector<mint>(N * 2 + 2, 0));

  seg.add(0, 1, 1);

  dump(seg.getsum(0, 1));

  rep(i, N) {
    rep(k, K) {
      int v = seg.getsum(i, i + 1).val;
      dump(v);
      seg.add(i + L[k], i + R[k] + 1, v);
    }
    rep(i, N) dump(i, seg.getsum(i, i + 1).val);
  }
  cout << seg.getsum(N - 1, N).val << endl;
}

signed main() {
  cout << fixed << setprecision(18);
  cerr << fixed;
  solve();
}

#include <bits/stdc++.h>
// #include <atcoder/all>

using namespace std;
// using namespace atcoder;

#ifdef DEBUG
#include "debug.h"
#define dump(...)                                                              \\
  DUMPOUT << "  " << string(#__VA_ARGS__) << ": "                              \\
          << "[" << to_string(__LINE__) << ":" << __FUNCTION__ << "]" << endl  \\
          << "    ",                                                           \\
      dump_func(__VA_ARGS__)
#else
#define dump(...)
#endif

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

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

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

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

#define int long long
#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define YES puts("YES")
#define Yes puts("Yes")
#define NO puts("NO")
#define No puts("No")
#define ALL(v) (v).begin(), (v).end()
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

/*
#define mod 1000000007 /*/
#define mod 998244353 //*/

typedef pair<int, int> P;
#define INF (1LL << 60)

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

using mint = Fp<mod>;

struct LazySegmentTree {
public:
  int n;
  vector<mint> node, lazy;

public:
  LazySegmentTree(vector<mint> v) {
    int sz = (int)v.size();
    n = 1;
    while (n < sz)
      n *= 2;
    node.resize(2 * n - 1);
    lazy.resize(2 * n - 1, 0);

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

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

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

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

void solve() {
  int N, K;
  cin >> N >> K;
  vector<int> L(K), R(K);
  rep(i, K) { cin >> L[i] >> R[i]; }
  /*
      vector<int> dp(2*N+2, 0);
      dp[0] = 1;
      for(int i=0; i<N; i++){
          rep(k,K){
              dp[i+L[k]] += dp[i];
              dp[i+R[k]+1] -= dp[i];
          }
          dump("-",i,dp);
          dp[i+1] += dp[i];
          dump("+", i,dp);
      }
      cout << dp[N-1] << endl;
  */
  LazySegmentTree seg(vector<mint>(N + 1, 0));

  seg.add(0, 1, 1);

  //    dump(seg.getsum(0,1));

  rep(i, N) {
    rep(k, K) {
      int v = seg.getsum(i, i + 1).val;
      //            dump(v);
      if (i + L[k] < N)
        seg.add(i + L[k], min(N, i + R[k] + 1), v);
    }
    //        rep(i,N) dump(i, seg.getsum(i,i+1).val);
  }
  cout << seg.getsum(N - 1, N).val << endl;
}

signed main() {
  cout << fixed << setprecision(18);
  cerr << fixed;
  solve();
}


#ifdef LOCAL
// #define _GLIBCXX_DEBUG
#endif
// #pragma GCC target("avx512f,avx512dq,avx512cd,avx512bw,avx512vl")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<int, int> Pi;
typedef vector<ll> Vec;
typedef vector<int> Vi;
typedef vector<string> Vs;
typedef vector<char> Vc;
typedef vector<P> VP;
typedef vector<vector<ll>> VV;
typedef vector<vector<int>> VVi;
typedef vector<vector<char>> VVc;
typedef vector<vector<vector<ll>>> VVV;
typedef vector<vector<vector<vector<ll>>>> VVVV;

#define REP(i, a, b) for (ll i = (a); i < (b); i++)
#define PER(i, a, b) for (ll i = (a); i >= (b); i--)
#define rep(i, n) REP(i, 0, n)
#define per(i, n) PER(i, n, 0)
const ll INF = 1e18 + 18;
const ll MOD = 998244353;
#define Yes(n) cout << ((n) ? "Yes" : "No") << endl;
#define YES(n) cout << ((n) ? "YES" : "NO") << endl;
#define ALL(v) v.begin(), v.end()
#define rALL(v) v.rbegin(), v.rend()
#define pb(x) push_back(x)
#define mp(a, b) make_pair(a, b)
#define Each(a, b) for (auto &a : b)
#define rEach(i, mp) for (auto i = mp.rbegin(); i != mp.rend(); ++i)
#ifdef LOCAL
#define dbg(x_) cerr << #x_ << ":" << x_ << endl;
#define dbgmap(mp)                                                             \\
  cerr << #mp << ":" << endl;                                                  \\
  for (auto i = mp.begin(); i != mp.end(); ++i) {                              \\
    cerr << i->first << ":" << i->second << endl;                              \\
  }
#define dbgset(st)                                                             \\
  cerr << #st << ":" << endl;                                                  \\
  for (auto i = st.begin(); i != st.end(); ++i) {                              \\
    cerr << *i << " ";                                                         \\
  }                                                                            \\
  cerr << endl;
#define dbgarr(n, m, arr)                                                      \\
  rep(i, n) {                                                                  \\
    rep(j, m) { cerr << arr[i][j] << " "; }                                    \\
    cerr << endl;                                                              \\
  }
#define dbgdp(n, arr)                                                          \\
  rep(i, n) { cerr << arr[i] << " "; }                                         \\
  cerr << endl;
#else
#define dbg(...)
#define dbgmap(...)
#define dbgset(...)
#define dbgarr(...)
#define dbgdp(...)
#endif
#define out(a) cout << a << endl
#define out2(a, b) cout << a << " " << b << endl
#define vout(v)                                                                \\
  rep(i, v.size()) { cout << v[i] << " "; }                                    \\
  cout << endl
#define Uniq(v) v.erase(unique(v.begin(), v.end()), v.end())
#define fi first
#define se second

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

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

template <typename T> istream &operator>>(istream &i, vector<T> &v) {
  rep(j, v.size()) i >> v[j];
  return i;
}

// vector
template <typename T> ostream &operator<<(ostream &s, const vector<T> &v) {
  int len = v.size();
  for (int i = 0; i < len; ++i) {
    s << v[i];
    if (i < len - 1)
      s << "	";
  }
  return s;
}

// 2 dimentional vector
template <typename T>
ostream &operator<<(ostream &s, const vector<vector<T>> &vv) {
  int len = vv.size();
  for (int i = 0; i < len; ++i) {
    s << vv[i] << endl;
  }
  return s;
}

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

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

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

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1])))
        return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, seg[a]);
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(seg[--b], R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }

  void debug(ll n) {
    Vec segv;
    rep(i, n) { segv.pb(query(i, i + 1)); }
    dbg(segv);
  }
};

int solve() {
  ll n;
  cin >> n;
  SegmentTree<ll> seg(
      n + 1, [](ll a, ll b) { return (a + b) % MOD; }, 0);

  ll k;
  cin >> k;
  VP span(k);
  rep(i, k) {
    ll l, r;
    cin >> l >> r;
    span[i] = mp(l, r);
  }
  sort(ALL(span));
  seg.update(0, 1);
  dbg(span);
  REP(i, 1, n) {
    rep(j, k) {
      auto [l, r] = span[j];
      ll il = i - r;
      ll ir = i - l;
      ir++;
      dbg(mp(il, ir));
      chmax(il, 0LL);
      chmax(ir, 0LL);
      ll sum = seg.query(il, ir);
      dbg(mp(i, sum));
      ll now = seg.query(i, i + 1);
      seg.update(i, sum + now);
    }
    seg.debug(n);
  }
  dbg(span);
  out(seg.query(n - 1, n));
  return 0;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << std::setprecision(10);
  //    ll T;
  //    cin>>T;
  //    while(T--)
  solve();
}

#ifdef LOCAL
// #define _GLIBCXX_DEBUG
#endif
// #pragma GCC target("avx512f,avx512dq,avx512cd,avx512bw,avx512vl")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<int, int> Pi;
typedef vector<ll> Vec;
typedef vector<int> Vi;
typedef vector<string> Vs;
typedef vector<char> Vc;
typedef vector<P> VP;
typedef vector<vector<ll>> VV;
typedef vector<vector<int>> VVi;
typedef vector<vector<char>> VVc;
typedef vector<vector<vector<ll>>> VVV;
typedef vector<vector<vector<vector<ll>>>> VVVV;

#define REP(i, a, b) for (ll i = (a); i < (b); i++)
#define PER(i, a, b) for (ll i = (a); i >= (b); i--)
#define rep(i, n) REP(i, 0, n)
#define per(i, n) PER(i, n, 0)
const ll INF = 1e18 + 18;
const ll MOD = 998244353;
#define Yes(n) cout << ((n) ? "Yes" : "No") << endl;
#define YES(n) cout << ((n) ? "YES" : "NO") << endl;
#define ALL(v) v.begin(), v.end()
#define rALL(v) v.rbegin(), v.rend()
#define pb(x) push_back(x)
#define mp(a, b) make_pair(a, b)
#define Each(a, b) for (auto &a : b)
#define rEach(i, mp) for (auto i = mp.rbegin(); i != mp.rend(); ++i)
#ifdef LOCAL
#define dbg(x_) cerr << #x_ << ":" << x_ << endl;
#define dbgmap(mp)                                                             \\
  cerr << #mp << ":" << endl;                                                  \\
  for (auto i = mp.begin(); i != mp.end(); ++i) {                              \\
    cerr << i->first << ":" << i->second << endl;                              \\
  }
#define dbgset(st)                                                             \\
  cerr << #st << ":" << endl;                                                  \\
  for (auto i = st.begin(); i != st.end(); ++i) {                              \\
    cerr << *i << " ";                                                         \\
  }                                                                            \\
  cerr << endl;
#define dbgarr(n, m, arr)                                                      \\
  rep(i, n) {                                                                  \\
    rep(j, m) { cerr << arr[i][j] << " "; }                                    \\
    cerr << endl;                                                              \\
  }
#define dbgdp(n, arr)                                                          \\
  rep(i, n) { cerr << arr[i] << " "; }                                         \\
  cerr << endl;
#else
#define dbg(...)
#define dbgmap(...)
#define dbgset(...)
#define dbgarr(...)
#define dbgdp(...)
#endif
#define out(a) cout << a << endl
#define out2(a, b) cout << a << " " << b << endl
#define vout(v)                                                                \\
  rep(i, v.size()) { cout << v[i] << " "; }                                    \\
  cout << endl
#define Uniq(v) v.erase(unique(v.begin(), v.end()), v.end())
#define fi first
#define se second

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

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

template <typename T> istream &operator>>(istream &i, vector<T> &v) {
  rep(j, v.size()) i >> v[j];
  return i;
}

// vector
template <typename T> ostream &operator<<(ostream &s, const vector<T> &v) {
  int len = v.size();
  for (int i = 0; i < len; ++i) {
    s << v[i];
    if (i < len - 1)
      s << "	";
  }
  return s;
}

// 2 dimentional vector
template <typename T>
ostream &operator<<(ostream &s, const vector<vector<T>> &vv) {
  int len = vv.size();
  for (int i = 0; i < len; ++i) {
    s << vv[i] << endl;
  }
  return s;
}

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

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

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

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1])))
        return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, seg[a]);
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(seg[--b], R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }

  void debug(ll n) {
    Vec segv;
    rep(i, n) { segv.pb(query(i, i + 1)); }
    dbg(segv);
  }
};

int solve() {
  ll n;
  cin >> n;
  SegmentTree<ll> seg(
      n + 1, [](ll a, ll b) { return (a + b) % MOD; }, 0);

  ll k;
  cin >> k;
  VP span(k);
  rep(i, k) {
    ll l, r;
    cin >> l >> r;
    span[i] = mp(l, r);
  }
  sort(ALL(span));
  seg.update(0, 1);
  dbg(span);
  REP(i, 1, n) {
    rep(j, k) {
      auto [l, r] = span[j];
      ll il = i - r;
      ll ir = i - l;
      ir++;
      dbg(mp(il, ir));
      chmax(il, 0LL);
      chmax(ir, 0LL);
      ll sum = seg.query(il, ir);
      dbg(mp(i, sum));
      ll now = seg.query(i, i + 1);
      seg.update(i, sum + now);
    }
    // seg.debug(n);
  }
  dbg(span);
  out(seg.query(n - 1, n));
  return 0;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << std::setprecision(10);
  //    ll T;
  //    cin>>T;
  //    while(T--)
  solve();
}


#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;

const int MAXN = 1e5 + 5;
const int mod = 998244353;
LL tr[MAXN], dp[MAXN];
int n, k, L[15], R[15];
void update(int x, LL y) {
  for (; x <= n; x += (x & (-x)))
    tr[x] = (tr[x] + y) % mod;
}
LL find(int x) {
  if (!x)
    return 0;
  LL res = 0;
  for (; x; x -= (x & (-x)))
    res = (res + tr[x]) % mod;
  return res;
}

int main() {
  scanf("%d %d", &n, &k);
  for (int i = 1; i <= k; ++i) {
    scanf("%d %d", &L[i], &R[i]);
  }
  dp[1] = 1;
  update(1, 1);
  for (int i = 2; i <= n; ++i) {
    for (int j = 1; j <= k; ++j) {
      if (i <= L[j])
        continue;
      dp[i] = (dp[i] + find(i - L[j]) - find(max(i - R[j] - 1, 0))) % mod;
      dp[i] = (dp[i] + mod) % mod;
    }
    update(i, dp[i]);
  }
  printf("%lld", dp[n]);
  return 0;
}

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;

const int MAXN = 2e5 + 5;
const int mod = 998244353;
LL tr[MAXN], dp[MAXN];
int n, k, L[15], R[15];
void update(int x, LL y) {
  for (; x <= n; x += (x & (-x)))
    tr[x] = (tr[x] + y) % mod;
}
LL find(int x) {
  if (!x)
    return 0;
  LL res = 0;
  for (; x; x -= (x & (-x)))
    res = (res + tr[x]) % mod;
  return res;
}

int main() {
  scanf("%d %d", &n, &k);
  for (int i = 1; i <= k; ++i) {
    scanf("%d %d", &L[i], &R[i]);
  }
  dp[1] = 1;
  update(1, 1);
  for (int i = 2; i <= n; ++i) {
    for (int j = 1; j <= k; ++j) {
      if (i <= L[j])
        continue;
      dp[i] = (dp[i] + find(i - L[j]) - find(max(i - R[j] - 1, 0))) % mod;
      dp[i] = (dp[i] + mod) % mod;
    }
    update(i, dp[i]);
  }
  printf("%lld", dp[n]);
  return 0;
}


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

#define what_is(x) cout << #x << " is " << x << endl;
#define PI acos(-1)
#define hell 1000000007
#define HELL 998244353
#define io                                                                     \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);                                                                  \\
  cout.tie(0)
#define fix(n) cout << fixed << setprecision(n)
#define mset(a, n) memset(a, n, sizeof a)
#define rep(i, a, b) for (__typeof((b)) i = (a); i < (b); i++)
#define repp(i, a, b, p) for (__typeof((b)) i = (a); i < (b); i += p)
#define ren(i, a, b) for (__typeof((a)) i = (a); i >= (b); i--)
#define renn(i, a, b, p) for(__typeof((a) i=(a);i>=(b);i-=p)
#define ADD(a, b, c) ((a) % c + (b) % c) % c
#define SUB(a, b, c) ((a) % c - (b) % c + c) % c
#define MUL(a, b, c) (((a) % c) * ((b) % c)) % c
#define lbd lower_bound
#define ubd upper_bound
#define ll long long
#define ld long double
#define pb push_back
#define fi first
#define se second
#define vll vector<ll>
#define pll pair<ll, ll>
#define vpll vector<pll>
#define all(v) (v).begin(), (v).end()
#define sz(x) (ll) x.size()
// #define out(n) cout<<n<<" "
#define outl(n) cout << n << endl
#define bug(n)                                                                 \\
  {                                                                            \\
    outl(n);                                                                   \\
    return;                                                                    \\
  }
#define pii pair<int, int>
#define lim 1000000000000000000
#define ninf -9223372036854775802
#define M 998244353
#define eps 1e-9
#define MAX 5
#define N 200005
#define db(a)                                                                  \\
  for (auto it : a) {                                                          \\
    cout << it << " ";                                                         \\
  }                                                                            \\
  cout << endl;
ll prime[MAX];
ll fact[MAX];

const long long INF64 = 1e18;
ll vpow(ll a, ll b, ll p) {
  if (b == 0)
    return 1;
  if (b == 1)
    return a;
  ll temp = vpow(a, b / 2, p);
  temp *= temp;
  temp %= p;
  if (b % 2 == 0)
    return temp;
  temp = temp * a;
  temp %= p;
  return temp;
}

ll gcd(ll a, ll b) {
  if (a == 0)
    return b;
  return gcd(b % a, a);
}

ll inverseMod(ll a, ll b, ll p) {
  if (b == 0)
    return 1;
  ll temp = vpow(b, p - 2, p);
  ll ans = temp * a;
  ans %= p;
  return ans;
}
void sieve() {
  prime[0] = prime[1] = 1;
  for (ll i = 2; i < MAX; i++) {
    if (prime[i] == 0) {
      for (int j = i * 2; j < MAX; j += i) {
        if (prime[j] == 0) {
          prime[j] = i;
        }
      }
      prime[i] = i;
    }
  }
}

void factorial() {
  fact[0] = 1;
  fact[1] = 1;
  rep(i, 2, MAX) {
    fact[i] = (fact[i - 1] * i);
    // fact[i]%=M;
  }
}

// ll seg[4*N];
// ll get(ll ind,ll left,ll right,ll l,ll r){
//     if(r<left || right<l)
//         return INT_MAX;
//     if(l<=left && right<=r){
//         return seg[ind];
//     }
//     ll mid=left+(right-left)/2;
//     return min(get(2*ind,left,mid,l,r),get(2*ind+1,mid+1,right,l,r));
// }
// void update(ll ind,ll left,ll right,ll ind,ll val){
//     if(ind<left || ind> right)
//         return ;
//     if(left==right){
//         seg[ind]=val;
//         return ;
//     }
//     ll mid=left+(right-left)/2;
//     update(2*ind,left,mid,ind,val);
//     update(2*ind+1,mid+1,right,ind,val);
//     seg[ind]=min(seg[2*ind],seg[2*ind+1]);
// }
ll bit[N];
void update(ll ind, ll val) {
  ind++;
  while (ind < N) {
    bit[ind] += val;
    bit[ind] %= M;
    ind += (ind & (-ind));
  }
}
ll getPref(ll ind) {
  ind++;
  ll ans = 0;
  while (ind > 0) {
    ans += bit[ind];
    ind -= (ind & (-ind));
    ans %= M;
  }
  return ans;
}
ll getRange(ll left, ll right) {
  ll ans = getPref(right);
  if (left > 0)
    ans -= getPref(left - 1);
  if (ans < M)
    ans += M;
  return ans;
}
void solve(ll ttt) {
  ll n, k;
  cin >> n >> k;
  vpll a(k);
  rep(i, 0, k) cin >> a[i].fi >> a[i].se;
  sort(all(a));
  // memset(seg,0x3f3f3f3f,sizeof(seg));
  vll ans(n, INT_MAX);
  ans[n - 1] = 0;
  // update(1,0,n-1,n-1,0);
  update(n - 1, 1);
  ren(i, n - 2, 0) {
    ll cur = 0;
    rep(j, 0, k) {
      cur += getRange(i + a[j].fi, i + a[j].se);
      cur %= M;
    }
    update(i, cur);
    ans[i] = cur;
    // cout<<"For "<<i<<" ans= "<<cur<<endl;
  }
  cout << ans[0] << endl;
}

int main() {
  io;
  // sieve();
  // factorial();
#ifndef ONLINE_JUDGE
  freopen("input1.txt", "r", stdin);
  // freopen("output1.txt","w",stdout);
#endif

  ll t = 1;
  // cin >> t;
  fix(12);
  rep(q, 1, t + 1) {
    // cout<<"Test case : "<<q<<endl;
    solve(q);
    // solve2();
  }
  return 0;
}

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

#define what_is(x) cout << #x << " is " << x << endl;
#define PI acos(-1)
#define hell 1000000007
#define HELL 998244353
#define io                                                                     \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);                                                                  \\
  cout.tie(0)
#define fix(n) cout << fixed << setprecision(n)
#define mset(a, n) memset(a, n, sizeof a)
#define rep(i, a, b) for (__typeof((b)) i = (a); i < (b); i++)
#define repp(i, a, b, p) for (__typeof((b)) i = (a); i < (b); i += p)
#define ren(i, a, b) for (__typeof((a)) i = (a); i >= (b); i--)
#define renn(i, a, b, p) for(__typeof((a) i=(a);i>=(b);i-=p)
#define ADD(a, b, c) ((a) % c + (b) % c) % c
#define SUB(a, b, c) ((a) % c - (b) % c + c) % c
#define MUL(a, b, c) (((a) % c) * ((b) % c)) % c
#define lbd lower_bound
#define ubd upper_bound
#define ll long long
#define ld long double
#define pb push_back
#define fi first
#define se second
#define vll vector<ll>
#define pll pair<ll, ll>
#define vpll vector<pll>
#define all(v) (v).begin(), (v).end()
#define sz(x) (ll) x.size()
// #define out(n) cout<<n<<" "
#define outl(n) cout << n << endl
#define bug(n)                                                                 \\
  {                                                                            \\
    outl(n);                                                                   \\
    return;                                                                    \\
  }
#define pii pair<int, int>
#define lim 1000000000000000000
#define ninf -9223372036854775802
#define M 998244353
#define eps 1e-9
#define MAX 5
#define N 200006
#define db(a)                                                                  \\
  for (auto it : a) {                                                          \\
    cout << it << " ";                                                         \\
  }                                                                            \\
  cout << endl;
ll prime[MAX];
ll fact[MAX];

const long long INF64 = 1e18;
ll vpow(ll a, ll b, ll p) {
  if (b == 0)
    return 1;
  if (b == 1)
    return a;
  ll temp = vpow(a, b / 2, p);
  temp *= temp;
  temp %= p;
  if (b % 2 == 0)
    return temp;
  temp = temp * a;
  temp %= p;
  return temp;
}

ll gcd(ll a, ll b) {
  if (a == 0)
    return b;
  return gcd(b % a, a);
}

ll inverseMod(ll a, ll b, ll p) {
  if (b == 0)
    return 1;
  ll temp = vpow(b, p - 2, p);
  ll ans = temp * a;
  ans %= p;
  return ans;
}
void sieve() {
  prime[0] = prime[1] = 1;
  for (ll i = 2; i < MAX; i++) {
    if (prime[i] == 0) {
      for (int j = i * 2; j < MAX; j += i) {
        if (prime[j] == 0) {
          prime[j] = i;
        }
      }
      prime[i] = i;
    }
  }
}

void factorial() {
  fact[0] = 1;
  fact[1] = 1;
  rep(i, 2, MAX) {
    fact[i] = (fact[i - 1] * i);
    // fact[i]%=M;
  }
}

ll bit[N];
void update(ll ind, ll val) {
  ind++;
  while (ind < N) {
    bit[ind] += val;
    bit[ind] %= M;
    ind += (ind & (-ind));
  }
}
ll getPref(ll ind) {
  ind++;
  ll ans = 0;
  while (ind > 0) {
    ans += bit[ind];
    ind -= (ind & (-ind));
    ans %= M;
  }
  return ans;
}
ll getRange(ll left, ll right) {
  right = min(right, (ll)N - 2);
  left = min(left, (ll)N - 2);
  ll ans = getPref(right);
  if (left > 0)
    ans -= getPref(left - 1);
  if (ans < M)
    ans += M;
  return ans;
}
void solve(ll ttt) {
  ll n, k;
  cin >> n >> k;
  vpll a(k);
  rep(i, 0, k) cin >> a[i].fi >> a[i].se;
  sort(all(a));
  // memset(seg,0x3f3f3f3f,sizeof(seg));
  vll ans(n, INT_MAX);
  ans[n - 1] = 0;
  // update(1,0,n-1,n-1,0);
  update(n - 1, 1);
  ren(i, n - 2, 0) {
    ll cur = 0;
    rep(j, 0, k) {
      cur += getRange(i + a[j].fi, i + a[j].se);
      cur %= M;
    }
    update(i, cur);
    ans[i] = cur;
    // cout<<"For "<<i<<" ans= "<<cur<<endl;
  }
  cout << ans[0] << endl;
}

int main() {
  io;
  // sieve();
  // factorial();
#ifndef ONLINE_JUDGE
  freopen("input1.txt", "r", stdin);
  // freopen("output1.txt","w",stdout);
#endif

  ll t = 1;
  // cin >> t;
  fix(12);
  rep(q, 1, t + 1) {
    // cout<<"Test case : "<<q<<endl;
    solve(q);
    // solve2();
  }
  return 0;
}

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