#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define AB_BHI_NI_DEGI                                                         \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define int long long
#define pb push_back
#define N 100009
#define inf 1e18
const double PI = 3.141592653589793238462643383279;
// int mod = 1e9 + 7;
int mod = 998244353;
#define P pair<int, int>
#define F first
#define S second
#define all(v) v.begin(), v.end()
#define vi vector<int>
#define ld long double

#define ordered_set                                                            \\
  tree<int, null_type, less<int>, rb_tree_tag,                                 \\
       tree_order_statistics_node_update>

int n, k;
vector<int> v;
int dp[2 * N];
int fun(int cur) {
  if (cur > n)
    return 0;
  if (cur == n)
    return 1;
  if (dp[cur] != -1)
    return dp[cur];
  int ans = 0;
  for (int i : v) {
    if (cur + i > n)
      break;
    ans += fun(cur + i) % mod;
    ans %= mod;
  }
  return dp[cur] = ans;
}

void solve() {
  cin >> n >> k;
  set<int> s;
  for (int i = 0; i < k; i++) {
    int l, r;
    cin >> l >> r;
    for (int j = l; j <= r; j++)
      s.insert(j);
  }
  for (int i : s)
    v.pb(i);
  sort(all(v));
  memset(dp, -1, sizeof(dp));
  cout << fun(1) << "\\n";
}
int32_t main() {
  AB_BHI_NI_DEGI
  int Test = 1;
  // cin >> Test;
  // init();
  while (Test--)
    solve();
  return 0;
}
/*

*/

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define AB_BHI_NI_DEGI                                                         \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define int long long
#define pb push_back
#define N 100009
#define inf 1e18
const double PI = 3.141592653589793238462643383279;
// int mod = 1e9 + 7;
int mod = 998244353;
#define P pair<int, int>
#define F first
#define S second
#define all(v) v.begin(), v.end()
#define vi vector<int>
#define ld long double

#define ordered_set                                                            \\
  tree<int, null_type, less<int>, rb_tree_tag,                                 \\
       tree_order_statistics_node_update>

void solve() {
  int n, k;
  cin >> n >> k;
  int vis[n + 1] = {0};
  int l[k], r[k];
  int dp[n + 1] = {0};
  for (int i = 0; i < k; i++) {
    cin >> l[i] >> r[i];
    for (int j = l[i]; j <= r[i]; j++)
      vis[j] = 1;
  }
  int ans = 0;
  for (int i = 2; i <= n; i++) {
    dp[i] = dp[i - 1] - vis[i - 2] + vis[i - 1];
    for (int j = 0; j < k; j++) {
      int L = l[j];
      int R = r[j];
      if (i - R - 1 > 0)
        dp[i] = (dp[i] - dp[i - R - 1] + mod) % mod;
      if (i - L > 0)
        dp[i] = (dp[i] + dp[i - L]) % mod;
    }
  }
  cout << dp[n] << "\\n";
}
int32_t main() {
  AB_BHI_NI_DEGI
  int Test = 1;
  // cin >> Test;
  // init();
  while (Test--)
    solve();
  return 0;
}
/*

*/


#include <bits/stdc++.h> //AtCoder
#include <iostream>      //Codeforces
#include <vector>        //Codeforces

#define int long long
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repeq(i, a, b) for (int i = a; i <= b; i++)
#define Vi vector<int>
#define VVi vector<Vi>
#define Vs vector<string>
#define Vc vector<char>
#define cYES cout << "YES" << endl
#define cNO cout << "NO" << endl
#define cYes cout << "Yes" << endl
#define cNo cout << "No" << endl
#define cyes cout << "yes" << endl
#define cno cout << "no" << endl

using namespace std;
/****************************** START ******************************/

signed main() {
  int N, K;
  cin >> N >> K;
  Vi L(K), R(K);
  map<int, int> S, ans;
  rep(i, 0, K) { cin >> L.at(i) >> R.at(i); }
  int mod = 998244353;

  repeq(i, 1, N) {
    rep(j, 0, K) {
      if (i >= L.at(j) && i <= R.at(j)) {
        S[i] = 1;
      }
    }
  }
  repeq(j, 1, N) {
    if (S[j]) {
      if (1 + j <= N) {
        ans[1 + j] = 1;
      }
    }
  }
  repeq(i, 2, N) {
    repeq(j, 1, N) {
      if (S[j]) {
        if (i + j <= N) {
          ans[i + j] += ans[i];
          ans[i + j] %= mod;
        }
      }
    }
  }
  cout << ans[N];
}

#include <bits/stdc++.h> //AtCoder
#include <iostream>      //Codeforces
#include <vector>        //Codeforces

#define int long long
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repeq(i, a, b) for (int i = a; i <= b; i++)
#define Vi vector<int>
#define VVi vector<Vi>
#define Vs vector<string>
#define Vc vector<char>
#define cYES cout << "YES" << endl
#define cNO cout << "NO" << endl
#define cYes cout << "Yes" << endl
#define cNo cout << "No" << endl
#define cyes cout << "yes" << endl
#define cno cout << "no" << endl

using namespace std;
/****************************** START ******************************/

signed main() {
  int N, K;
  cin >> N >> K;
  Vi L(K), R(K);
  map<int, int> S, a, f;
  rep(i, 0, K) { cin >> L.at(i) >> R.at(i); }
  int mod = 998244353;

  f[1] = 1;
  f[2] = -1;
  repeq(i, 1, N) {
    f[i] = (f[i] % mod + mod) % mod;
    f[i + 1] += f[i];
    rep(j, 0, K) {
      if (i + L.at(j) <= N) {
        f[i + L.at(j)] += f[i];
      }
      if (i + R.at(j) + 1 <= N) {
        f[i + R.at(j) + 1] -= f[i];
      }
    }
  }

  cout << f[N];
}


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

int main() {
  int n, k, mod = 998244353;
  cin >> n >> k;
  vector<int> s;
  rep(i, 0, k) {
    int l, r;
    cin >> l >> r;
    rep(j, l, r + 1) s.push_back(j);
  }
  sort(s.begin(), s.end());
  vector<bool> seen(n + 1, false);
  vector<ll> dp(n + 1);
  dp[1] = 1;
  seen[1] = 1;
  bool f = false;
  rep(i, 1, n + 1) {
    if (seen[i] == 0)
      continue;
    rep(j, 0, s.size()) {
      if (i + s[j] > n) {
        break;
        if (j == 0)
          f = true;
      }
      dp[i + s[j]] += dp[i];
      dp[i + s[j]] %= mod;
      seen[i + s[j]] = 1;
    }
    if (f)
      break;
  }
  cout << dp[n] << endl;
  // rep(i,1,n+1) cout << i << " " << dp[i] << endl;
}

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

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


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define FOR(i, a, b) for (ll i = a; i < b; i++)

ll mod = 998244353;
class SegmentTree {
private:
  int n;
  vector<ll> node, lazy;
  vector<bool> flag_lazy;

public:
  SegmentTree(int N) {
    n = 1;
    while (n < N)
      n *= 2;
    node.resize(2 * n - 1, 0);
    lazy.resize(2 * n - 1, 0);
    flag_lazy.resize(2 * n - 1, false);
  }

  void update(int i, int l, int r) {
    if (!flag_lazy[i])
      return;
    node[i] += lazy[i];
    node[i] %= mod;
    if (r - l > 1) {
      lazy[2 * i + 1] += lazy[i] / 2;
      lazy[2 * i + 2] += lazy[i] / 2;
      flag_lazy[2 * i + 1] = true;
      flag_lazy[2 * i + 2] = true;
    }
    lazy[i] = 0;
  }

  void add(int a, int b, ll x, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    update(k, l, r);
    if (b <= l || r <= a)
      return;

    if (a <= l && r <= b) {
      lazy[k] += ((r - l) * (x));
      flag_lazy[k] = true;
      update(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]) % mod;
    }
  }

  ll query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    update(k, l, r);
    if (b <= l || r <= a)
      return 0;
    if (a <= l && r <= b)
      return node[k] % mod;

    ll sum_l = query(a, b, 2 * k + 1, l, (l + r) / 2);
    ll sum_r = query(a, b, 2 * k + 2, (l + r) / 2, r);
    return (sum_l + sum_r) % mod;
  }

  void disp() {
    for (int i : node) {
      cout << i << " ";
    }
    cout << "\\n";
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int N, K;
  cin >> N >> K;
  int L[K], R[K];
  for (int i = 0; i < K; i++) {
    cin >> L[i] >> R[i];
  }

  SegmentTree st(500050);
  st.add(1, 2, 1);

  FOR(i, 1, N) {
    ll x = st.query(i, i + 1);
    for (int j = 0; j < K; j++) {
      int l = i + L[j];
      int r = i + R[j] + 1;

      // st.add(min(l, N + 1), min(r, N + 1), x);
      st.add(l, r, x);
    }
    // cout << x << "\\n";
  }

  cout << st.query(N, N + 1) << "\\n";

  return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define FOR(i, a, b) for (ll i = a; i < b; i++)

ll mod = 998244353;
class SegmentTree {
private:
  int n;
  vector<ll> node, lazy;
  vector<bool> flag_lazy;

public:
  SegmentTree(int N) {
    n = 1;
    while (n < N)
      n *= 2;
    node.resize(2 * n - 1, 0);
    lazy.resize(2 * n - 1, 0);
    flag_lazy.resize(2 * n - 1, false);
  }

  void update(int i, int l, int r) {
    if (!flag_lazy[i])
      return;
    node[i] += lazy[i];
    node[i] %= mod;
    if (r - l > 1) {
      lazy[2 * i + 1] += lazy[i] / 2;
      lazy[2 * i + 2] += lazy[i] / 2;
      flag_lazy[2 * i + 1] = true;
      flag_lazy[2 * i + 2] = true;
    }
    flag_lazy[i] = false;
    lazy[i] = 0;
  }

  void add(int a, int b, ll x, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    update(k, l, r);
    if (b <= l || r <= a)
      return;

    if (a <= l && r <= b) {
      lazy[k] += ((r - l) * (x));
      flag_lazy[k] = true;
      update(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]) % mod;
    }
  }

  ll query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    update(k, l, r);
    if (b <= l || r <= a)
      return 0;
    if (a <= l && r <= b)
      return node[k] % mod;

    ll sum_l = query(a, b, 2 * k + 1, l, (l + r) / 2);
    ll sum_r = query(a, b, 2 * k + 2, (l + r) / 2, r);
    return (sum_l + sum_r) % mod;
  }

  void disp() {
    for (int i : node) {
      cout << i << " ";
    }
    cout << "\\n";
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int N, K;
  cin >> N >> K;
  int L[K], R[K];
  for (int i = 0; i < K; i++) {
    cin >> L[i] >> R[i];
  }

  SegmentTree st(500050);
  st.add(1, 2, 1);

  for (int i = 1; i < N; i++) {
    ll x = st.query(i, i + 1);
    for (int j = 0; j < K; j++) {
      int l = i + L[j];
      int r = i + R[j] + 1;

      // st.add(min(l, N + 1), min(r, N + 1), x);
      st.add(l, r, x);
    }
    // cout << x << "\\n";
  }

  cout << st.query(N, N + 1) << "\\n";

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef pair<int, int> P;
const int INF = 1e9;
const ll MOD = 998244353;
int dp[2 * 10 + 100];
int main() {
  int N, K;
  cin >> N >> K;
  vector<int> L(K), R(K);
  REP(i, K) { cin >> L[i] >> R[i]; }
  vector<int> Wa(N + 100);
  dp[1] = 1;
  Wa[1] = 1;
  for (int i = 1; i <= N; i++) {
    ll num = 0;

    REP(j, K) {
      int l = max(0, i - R[j] - 1);
      int r = i - L[j];
      if (r < 0)
        continue;
      dp[i] += Wa[r] - Wa[l];
      while (dp[i] < 0) {
        dp[i] += MOD;
      }
      dp[i] %= MOD;
    }
    Wa[i] = dp[i] + Wa[i - 1];
    while (Wa[i] < 0) {
      Wa[i] += MOD;
    }
    Wa[i] %= MOD;
  }
  cout << dp[N] << endl;
}

#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef pair<int, int> P;
const int INF = 1e9;
const ll MOD = 998244353;
int main() {
  int N, K;
  cin >> N >> K;
  vector<int> L(K), R(K);
  REP(i, K) { cin >> L[i] >> R[i]; }
  vector<int> Wa(N + 100);
  vector<int> dp(N + 100);
  dp[1] = 1;
  Wa[1] = 1;
  for (int i = 1; i <= N; i++) {
    ll num = 0;

    REP(j, K) {
      int l = max(0, i - R[j] - 1);
      int r = i - L[j];
      if (r < 0)
        continue;
      dp[i] += Wa[r] - Wa[l];
      while (dp[i] < 0) {
        dp[i] += MOD;
      }
      dp[i] %= MOD;
    }
    Wa[i] = dp[i] + Wa[i - 1];
    while (Wa[i] < 0) {
      Wa[i] += MOD;
    }
    Wa[i] %= MOD;
  }
  cout << dp[N] << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(index, num) for (int index = 0; index < num; index++)
#define rep1(index, num) for (int index = 1; index <= num; index++)
#define brep(index, num) for (int index = num - 1; index >= 0; index--)
#define brep1(index, num) for (int index = num; index > 0; index--)
#define prin(a) cout << a << "\\n"
#define kaigyo cout << "\\n"
#define mp(a1, a2) make_pair(a1, a2)
#define ALL(a) (a).begin(), (a).end()
#define rALL(a) (a).rbegin(), (a).rend()
#define SORT(V) sort(ALL(V))
#define REV(V) reverse(ALL(V))
#define RSORT(V)                                                               \\
  SORT(V);                                                                     \\
  REV(V)
#define mem(x) memset(x, 0, sizeof(x))
#define mem1(x) memset(x, -1, sizeof(x))
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef pair<int, int> pint;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef vector<string> vst;
typedef vector<char> vc;
typedef vector<long double> vd;
typedef vector<pint> vpint;
typedef vector<pll> vpll;
typedef vector<vector<int>> vint2;
ll mod = 1e9 + 7;
ll smod = 998244353;
#define int1(x)                                                                \\
  int x;                                                                       \\
  cin >> x;
#define int2(x, y)                                                             \\
  int x, y;                                                                    \\
  cin >> x >> y;
#define int3(x, y, z)                                                          \\
  int x, y, z;                                                                 \\
  cin >> x >> y >> z;
#define int4(x, y, z, w)                                                       \\
  int x, y, z, w;                                                              \\
  cin >> x >> y >> z >> w;
#define ll1(x)                                                                 \\
  ll x;                                                                        \\
  cin >> x;
#define ll2(x, y)                                                              \\
  ll x, y;                                                                     \\
  cin >> x >> y;
#define vint1(a, n)                                                            \\
  vint a(n);                                                                   \\
  rep(i, n) cin >> a[i];
#define vint2(a, b, n)                                                         \\
  vint a(n), b(n);                                                             \\
  rep(i, n) cin >> a[i] >> b[i];
#define vll1(a, n)                                                             \\
  vll a(n);                                                                    \\
  rep(i, n) cin >> a[i];
struct aaa {
  aaa() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    cout << fixed << setprecision(20);
  };
} aaaaaaa;

const double pi = acos(-1.0);
const ll inf = 1LL << 60;

bool isPrime(ll n) {
  if (n < 2)
    return false;
  for (ll x = 2; x * x <= n; x++) {
    if (n % x == 0)
      return false;
  }
  return true;
}
ll kaizyo(ll k) {
  ll sum = 1;
  rep1(i, k) {
    sum *= i;
    sum %= mod;
  }
  return sum;
}
ll ncr(ll n, ll r) { return kaizyo(n) / (kaizyo(r) * kaizyo(n - r)); }
unsigned keta(unsigned num) { return log10(num) + 1; }
long long modpow(long long a, long long n, long long mod) {
  long long res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}

int main() {

  ll2(n, k);
  vll l(k), r(k);
  rep(i, k) cin >> l[i] >> r[i];
  vll s(n + 1, 0), cnt(n + 1, 0);
  cnt[1] = 1;
  rep1(i, n + 1) {
    rep(j, k) {
      if (l[j] <= i && i <= r[j])
        s[i]++;
    }
  }

  rep1(i, n) {
    rep1(j, i - 1) {
      if (s[i - j] > 0) { // cout<<i<<' '<<j<<' '<<cnt[j]<<endl;
        cnt[i] += cnt[j];
      }
    }
    cnt[i] %= smod;
  }
  prin(cnt[n]);
}

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

#define FASTIO                                                                 \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
using ll = long long;

const int MOD = 998244353;
const ll INF = 1e16;

int main() {
  FASTIO

  int n, k;
  cin >> n >> k;
  int b[k][2];
  for (int i = 0; i < k; i++) {
    cin >> b[i][0] >> b[i][1];
  }

  vector<int> dp(n + 1, 0);
  dp[1] = 1;
  for (int i = 2; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      dp[i] += dp[max(i - b[j][0], 0)] - dp[max(i - b[j][1] - 1, 0)];
      if (dp[i] < 0)
        dp[i] += MOD;
      else
        dp[i] %= MOD;
    }
    dp[i] += dp[i - 1];
    if (dp[i] < 0)
      dp[i] += MOD;
    else
      dp[i] %= MOD;
  }
  int ways = dp[n] - dp[n - 1];
  if (ways < 0)
    cout << ways + MOD << "\\n";
  else
    cout << ways % MOD << "\\n";

  return 0;
}


#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
using namespace std;
typedef long long ll;
const int mod = 998244353;
const int maxn = 2e5 + 7;
ll dp[maxn];
vector<int> v;
int main(void) {
  int n, k;
  cin >> n >> k;
  for (int i = 1; i <= k; i++) {
    int l, r;
    cin >> l >> r;
    for (int j = l; j <= r; j++) {
      v.push_back(j);
    }
  }
  dp[0] = 1;
  int len = v.size();
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < len; j++) {
      if (i - v[j] >= 0)
        dp[i] = (dp[i] + dp[i - v[j]]) % mod;
    }
  }
  cout << dp[n - 1];
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2E5 + 5;
const int mod = 998244353;

int dp[N];

void solve() {

  int n, k;
  scanf("%lld %lld", &n, &k);
  pair<int, int> p[15];

  for (int i = 0; i < k; i++) {
    int x, y;
    scanf("%lld %lld", &x, &y);
    p[i] = make_pair(x, y);
  }

  dp[1] = 1;

  for (int i = 2; i <= n; i++) {

    dp[i] = 0;

    for (int j = 0; j < k; j++) {

      int l = max(1LL, i - p[j].second);
      int r = i - p[j].first;

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

    dp[i] += dp[i - 1];
    dp[i] %= mod;
  }

  printf("%lld\\n", ((dp[n] - dp[n - 1]) + mod) % mod);
}

int32_t main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);

  solve();

  return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#define ll long long
#define N 100005
#define mod 998244353
#define rep(i, l, r) for (int i = l; i <= r; ++i)
using namespace std;
int t;
int n, k;
int l[11], r[11];
int f[N], s[N];
int main() {
  scanf("%d%d", &n, &k);
  rep(i, 1, k) { scanf("%d%d", &l[i], &r[i]); }
  s[0] = f[0] = 1;
  rep(i, 1, n) {
    rep(j, 1, k) {
      if (i >= l[j]) {
        if (i > r[j])
          f[i] += s[i - l[j]] - s[i - r[j] - 1];
        else
          f[i] += s[i - l[j]];
      }
    }
    // printf("%d %d\\n", i, f[i]);
    f[i] = (f[i] % mod + mod) % mod;
    s[i] = (s[i - 1] + f[i]) % mod;
  }
  printf("%d", f[n - 1]);
  return 0;
}

#include <algorithm>
#include <cstdio>
#include <cstring>
#define ll long long
#define N 200005
#define mod 998244353
#define rep(i, l, r) for (int i = l; i <= r; ++i)
using namespace std;
int t;
int n, k;
int l[11], r[11];
int f[N], s[N];
int main() {
  scanf("%d%d", &n, &k);
  rep(i, 1, k) { scanf("%d%d", &l[i], &r[i]); }
  s[1] = f[1] = 1;
  rep(i, 2, n) {
    rep(j, 1, k) {
      if (i > l[j]) {
        if (i > r[j])
          f[i] = ((f[i] + s[i - l[j]] - s[i - r[j] - 1]) % mod + mod) % mod;
        else
          f[i] = (f[i] + s[i - l[j]]) % mod;
      }
    }
    // printf("%d %d\\n", i, f[i]);
    s[i] = (s[i - 1] + f[i]) % mod;
  }
  printf("%d", f[n]);
  return 0;
}


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

using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define ull unsigned long long
#define ld long double
#define vi vector<int>
#define vll vector<ll>
#define vc vector<char>
#define vs vector<string>
#define vpii vector<pii>
#define vpll vector<pll>

#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; i++)
#define rep1(i, n) for (int i = 1, i##_len = (n); i <= i##_len; i++)
#define repr(i, n) for (int i = ((int)(n)-1); i >= 0; i--)
#define rep1r(i, n) for (int i = ((int)(n)); i >= 1; i--)

#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

#define SORT(v, n) sort(v, v + n);
#define VSORT(v) sort(v.begin(), v.end());
#define RSORT(x) sort(rall(x));
#define pb push_back
#define mp make_pair

#define INF (1e9)
#define PI (acos(-1))
#define EPS (1e-7)

ull gcd(ull a, ull b) { return b ? gcd(b, a % b) : a; }
ull lcm(ull a, ull b) { return a / gcd(a, b) * b; }

const long long mod = 998244353;

// auto mod int
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;
  vi l(k), r(k);
  rep(i, k) cin >> l[i] >> r[i];
  set<int> st;
  rep(i, k) {
    for (int j = l[i]; j <= r[i]; ++j)
      st.insert(j);
  }
  vector<mint> dp(n + 2);
  dp[1] = 1;
  for (int h = 1; h < n; ++h) {
    for (auto itr = st.begin(); itr != st.end(); ++itr) {
      if (h + (*itr) > n)
        break;
      dp[h + (*itr)] += dp[h];
    }
  }
  cout << dp[n] << endl;
  return 0;
}

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

using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define ull unsigned long long
#define ld long double
#define vi vector<int>
#define vll vector<ll>
#define vc vector<char>
#define vs vector<string>
#define vpii vector<pii>
#define vpll vector<pll>

#define rep(i, n) for (int i = 0, i##_len = (n); i < i##_len; i++)
#define rep1(i, n) for (int i = 1, i##_len = (n); i <= i##_len; i++)
#define repr(i, n) for (int i = ((int)(n)-1); i >= 0; i--)
#define rep1r(i, n) for (int i = ((int)(n)); i >= 1; i--)

#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

#define SORT(v, n) sort(v, v + n);
#define VSORT(v) sort(v.begin(), v.end());
#define RSORT(x) sort(rall(x));
#define pb push_back
#define mp make_pair

#define INF (1e9)
#define PI (acos(-1))
#define EPS (1e-7)

ull gcd(ull a, ull b) { return b ? gcd(b, a % b) : a; }
ull lcm(ull a, ull b) { return a / gcd(a, b) * b; }

const long long mod = 998244353;

// auto mod int
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;
  vi l(k), r(k);
  rep(i, k) cin >> l[i] >> r[i];
  vector<mint> dp(n + 2);
  dp[1] = 1;
  dp[2] = -1;
  for (int h = 1; h < n + 1; ++h) {
    dp[h] += dp[h - 1];
    rep(i, k) {
      dp[min(n + 1, h + l[i])] += dp[h];
      dp[min(n + 1, h + r[i] + 1)] -= dp[h];
    }
  }
  cout << dp[n] << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\\n'
#define Rapido                                                                 \\
  ios::sync_with_stdio(0);                                                     \\
  cin.tie(0)
const int maxS = 2e5 + 10;
int MOD = 998244353;

int N, K;
int DP[maxS];
set<pair<int, int>> SET;

int go(int pos) {
  if (pos == N)
    return 1;
  if (pos > N)
    return 0;
  if (DP[pos] != -1)
    return DP[pos];
  int ans = 0;
  for (auto it : SET) {
    for (int i = it.first; i <= it.second; i++)
      ans = (ans + go(pos + i)) % MOD;
  }
  return DP[pos] = ans;
}

void code_idhr_h() {
  cin >> N >> K;
  while (K--) {
    int x, y;
    cin >> x >> y;
    SET.insert({x, y});
    // SET.insert(y);
  }
  memset(DP, -1, sizeof DP);
  cout << go(1);
}

int32_t main() {
  Rapido;
  int T = 1; // cin >> T;
  for (int t = 1; t <= T; t++) {
    code_idhr_h();
  }
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\\n'
#define Rapido                                                                 \\
  ios::sync_with_stdio(0);                                                     \\
  cin.tie(0)
const int maxS = 2e5 + 10;
int MOD = 998244353;
int DP[2 * maxS];

void code_idhr_h() {
  int N, K;
  cin >> N >> K;
  vector<int> L(K + 1), R(K + 1);
  for (int i = 1; i <= K; i++)
    cin >> L[i] >> R[i];
  DP[1] = 1;
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j <= K; j++) {
      DP[i + L[j]] = (DP[i + L[j]] + DP[i]) % MOD;
      DP[i + R[j] + 1] = (DP[i + R[j] + 1] - DP[i] + MOD) % MOD;
    }
    DP[i + 1] = (DP[i + 1] + DP[i]) % MOD;
  }
  cout << (DP[N] - DP[N - 1] + MOD) % MOD;
}

int32_t main() {
  Rapido;
  int T = 1; // cin >> T;
  for (int t = 1; t <= T; t++) {
    code_idhr_h();
  }
  return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#define fo(i, n) for (long long i = 0; i < n; i++)
#define ll long long int
#define inf 999999999999999999
#define pb push_back
#define fi first
#define se second
#define vi vector<ll>
#define vii vector<vector<ll>>
#define pi pair<ll, ll>
#define mp make_pair
#define MOD 998244353
#define tr(c, it) for (auto it = (c).begin(); it != (c).end(); ++it)
#define fio                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);
using namespace std;
// cerr<< '\\n' << "Time elapsed :" << clock() * 1000.0 / CLOCKS_PER_SEC << "
// ms\\n" ; freopen("explicit.in", "r", stdin); freopen("explicit.out", "w",
// stdout);

void SieveOfEratosthenes() {
  bool prime[10000001];
  memset(prime, true, sizeof(prime));

  for (ll p = 2; p * p <= 10000000; p++) {
    if (prime[p] == true) {
      // Update all multiples of p greater than or
      // equal to the square of it
      // numbers which are multiple of p and are
      // less than p^2 are already been marked.
      for (ll i = p * p; i <= 10000000; i += p) {
        prime[i] = false;
      }
    }
  }
}
ll binpow(ll a, ll b) {
  ll res = 1;
  while (b > 0) {
    if (b & 1)
      res = (res * a);
    a = (a * a);
    b >>= 1;
  }
  return res;
}
ll gcd(ll a, ll b) {
  if (b % a == 0)
    return a;
  return gcd(b % a, a);
}
ll power(ll x, ll y, ll p) {
  ll r = 1;

  x = x % p;
  while (y > 0) {
    if (y & 1)
      r = (r * x) % p;
    y = y >> 1;
    x = (x * x) % p;
  }
  return r;
}
ll modInverse(ll n, ll p) { return power(n, p - 2, p); }

ll nCrModP(ll n, ll r, ll p) {
  ll fac[100005];
  if (r == 0)
    return 1;

  return (fac[n] * modInverse(fac[r], p) % p * modInverse(fac[n - r], p) % p) %
         p;
}
ll a[200006] = {0};
ll dp[200007] = {0};
int32_t main() {
  fio ll j, i, n, t, l, r, c, h, k, m, maxi, d, x;
  cin >> n >> k;
  vector<ll> v;
  for (j = 0; j < k; j++) {
    cin >> l >> r;
    a[l] += 1;
    a[r + 1] += -1;
  }
  c = 0;
  for (j = 1; j <= 200006; j++) {
    c = c + a[j];
    if (c > 0) {
      v.pb(j);
      dp[j] = 1;
    }
  }

  for (i = 1; i <= n - 1; i++) {
    for (j = 0; j < v.size(); j++) {
      if (i - (v[j]) > 0) {
        dp[i] = (dp[i] + dp[i - v[j]]) % MOD;
      } else
        break;
    }
  }
  cout << dp[n - 1];
}

#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#define fo(i, n) for (long long i = 0; i < n; i++)
#define ll long long int
#define inf 999999999999999999
#define pb push_back
#define fi first
#define se second
#define vi vector<ll>
#define vii vector<vector<ll>>
#define pi pair<ll, ll>
#define mp make_pair
#define MOD 998244353
#define tr(c, it) for (auto it = (c).begin(); it != (c).end(); ++it)
#define fio                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);
using namespace std;
// cerr<< '\\n' << "Time elapsed :" << clock() * 1000.0 / CLOCKS_PER_SEC << "
// ms\\n" ; freopen("explicit.in", "r", stdin); freopen("explicit.out", "w",
// stdout);

void SieveOfEratosthenes() {
  bool prime[10000001];
  memset(prime, true, sizeof(prime));

  for (ll p = 2; p * p <= 10000000; p++) {
    if (prime[p] == true) {
      // Update all multiples of p greater than or
      // equal to the square of it
      // numbers which are multiple of p and are
      // less than p^2 are already been marked.
      for (ll i = p * p; i <= 10000000; i += p) {
        prime[i] = false;
      }
    }
  }
}
ll binpow(ll a, ll b) {
  ll res = 1;
  while (b > 0) {
    if (b & 1)
      res = (res * a);
    a = (a * a);
    b >>= 1;
  }
  return res;
}
ll gcd(ll a, ll b) {
  if (b % a == 0)
    return a;
  return gcd(b % a, a);
}
ll power(ll x, ll y, ll p) {
  ll r = 1;

  x = x % p;
  while (y > 0) {
    if (y & 1)
      r = (r * x) % p;
    y = y >> 1;
    x = (x * x) % p;
  }
  return r;
}
ll modInverse(ll n, ll p) { return power(n, p - 2, p); }

ll nCrModP(ll n, ll r, ll p) {
  ll fac[100005];
  if (r == 0)
    return 1;

  return (fac[n] * modInverse(fac[r], p) % p * modInverse(fac[n - r], p) % p) %
         p;
}
ll a[200006] = {0};
ll pre[200007] = {0};
int32_t main() {
  fio ll j, i, n, t, l, r, c, h, k, m, maxi, d, x;
  cin >> n >> k;
  ll a[n], b[n];
  vector<ll> v;
  pre[0] = 0;
  for (j = 0; j < k; j++) {
    cin >> a[j] >> b[j];
  }
  pre[1] = 1;
  for (i = 2; i <= n; i++) {
    for (j = 0; j < k; j++) {
      if (i - a[j] < 1)
        continue;
      if (i - b[j] < 1)
        pre[i] += pre[i - a[j]];
      else {
        pre[i] += pre[i - a[j]] - pre[i - b[j] - 1];
      }
    }
    pre[i] %= MOD;
    if (i != n)
      pre[i] += pre[i - 1];
  }
  cout << pre[n];
}


#pragma GCC optimize("Ofast")
#include "bits/stdc++.h"

// Begin Header {{{
using namespace std;

#ifndef DEBUG
#define dump(...)
#endif

#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define rep(i, b, e) for (intmax_t i = (b), i##_limit = (e); i < i##_limit; ++i)
#define repc(i, b, e)                                                          \\
  for (intmax_t i = (b), i##_limit = (e); i <= i##_limit; ++i)
#define repr(i, b, e)                                                          \\
  for (intmax_t i = (b), i##_limit = (e); i >= i##_limit; --i)
#define var(Type, ...)                                                         \\
  Type __VA_ARGS__;                                                            \\
  input(__VA_ARGS__)

constexpr size_t operator""_zu(unsigned long long value) { return value; };
constexpr intmax_t operator""_jd(unsigned long long value) { return value; };
constexpr uintmax_t operator""_ju(unsigned long long value) { return value; };

constexpr int INF = 0x3f3f3f3f;
constexpr intmax_t LINF = 0x3f3f3f3f3f3f3f3f_jd;

template <class T, class Compare = less<>>
using MaxHeap = priority_queue<T, vector<T>, Compare>;
template <class T, class Compare = greater<>>
using MinHeap = priority_queue<T, vector<T>, Compare>;

inline void input() {}
template <class Head, class... Tail>
inline void input(Head &&head, Tail &&...tail) {
  cin >> head;
  input(forward<Tail>(tail)...);
}

template <class Container, class Value = typename Container::value_type,
          enable_if_t<!is_same<Container, string>::value, nullptr_t> = nullptr>
inline istream &operator>>(istream &is, Container &vs) {
  for (auto &v : vs)
    is >> v;
  return is;
}

inline void output() { cout << "\\n"; }
template <class Head, class... Tail>
inline void output(Head &&head, Tail &&...tail) {
  cout << head;
  if (sizeof...(tail))
    cout << " ";
  output(forward<Tail>(tail)...);
}

template <class Container, class Value = typename Container::value_type,
          enable_if_t<!is_same<Container, string>::value, nullptr_t> = nullptr>
inline ostream &operator<<(ostream &os, const Container &vs) {
  static constexpr const char *delim[] = {" ", ""};
  for (auto it = begin(vs); it != end(vs); ++it) {
    os << delim[it == begin(vs)] << *it;
  }
  return os;
}

template <class Iterator>
inline void join(const Iterator &Begin, const Iterator &End,
                 const string &delim = "\\n", const string &last = "\\n") {
  for (auto it = Begin; it != End; ++it) {
    cout << ((it == Begin) ? "" : delim) << *it;
  }
  cout << last;
}

template <class T> inline vector<T> makeVector(const T &initValue, size_t sz) {
  return vector<T>(sz, initValue);
}

template <class T, class... Args>
inline auto makeVector(const T &initValue, size_t sz, Args... args) {
  return vector<decltype(makeVector<T>(initValue, args...))>(
      sz, makeVector<T>(initValue, args...));
}

template <class Func> class FixPoint : Func {
public:
  explicit constexpr FixPoint(Func &&f) noexcept : Func(forward<Func>(f)) {}

  template <class... Args>
  constexpr decltype(auto) operator()(Args &&...args) const {
    return Func::operator()(*this, std::forward<Args>(args)...);
  }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func &&f) noexcept {
  return FixPoint<Func>{forward<Func>(f)};
}

template <class Container> struct reverse_t {
  Container &c;
  reverse_t(Container &c) : c(c) {}
  auto begin() { return c.rbegin(); }
  auto end() { return c.rend(); }
};

template <class Container> auto reversed(Container &c) {
  return reverse_t<Container>(c);
}

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

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

template <class T> inline T diff(const T &a, const T &b) noexcept {
  return a < b ? b - a : a - b;
}

void ioinit() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << fixed << setprecision(10);
  clog << fixed << setprecision(10);
}
// }}} End Header

// ModInt {{{
template <intmax_t Modulo> class ModInt {
public:
  using value_type = intmax_t;

private:
  static constexpr value_type cmod = Modulo; // compile-time
  static value_type rmod;                    // runtime
  value_type value = 0;

  static constexpr value_type inverse(value_type n, value_type m) {
    value_type a = n;
    value_type b = m;
    value_type x = 0;
    value_type y = 1;
    for (value_type u = y, v = x; a;) {
      const value_type t = b / a;
      swap(x -= t * u, u);
      swap(y -= t * v, v);
      swap(b -= t * a, a);
    }
    if ((x %= m) < 0)
      x += m;
    return x;
  }

  static value_type normalize(intmax_t n, value_type m) {
    if (n >= m) {
      n %= m;
    } else if (n < 0) {
      if ((n %= m) < 0)
        n += m;
    }
    return n;
  }

public:
  ModInt() = default;
  ModInt(intmax_t n) : value(normalize(n, getModulo())) {}

  template <typename T> constexpr explicit operator T() const {
    return static_cast<T>(value);
  }

  ModInt &operator=(intmax_t n) {
    value = normalize(n, getModulo());
    return *this;
  }

  ModInt &operator+=(const ModInt &other) {
    if ((value += other.value) >= getModulo())
      value -= getModulo();
    return *this;
  }
  ModInt &operator-=(const ModInt &other) {
    if ((value -= other.value) < 0)
      value += getModulo();
    return *this;
  }
  ModInt &operator*=(const ModInt &other) {
    value = (value * other.value) % getModulo();
    return *this;
  }
  ModInt &operator/=(const ModInt &other) {
    value = (value * inverse(other.value, getModulo())) % getModulo();
    return *this;
  }

  ModInt &operator++() {
    if (++value == getModulo())
      value = 0;
    return *this;
  }
  ModInt &operator--() {
    if (value-- == 0)
      value = getModulo() - 1;
    return *this;
  }

  ModInt operator++(int) {
    const ModInt tmp(*this);
    ++*this;
    return tmp;
  }
  ModInt operator--(int) {
    const ModInt tmp(*this);
    --*this;
    return tmp;
  }

  friend ModInt operator+(ModInt lhs, const ModInt &rhs) { return lhs += rhs; }
  friend ModInt operator-(ModInt lhs, const ModInt &rhs) { return lhs -= rhs; }
  friend ModInt operator*(ModInt lhs, const ModInt &rhs) { return lhs *= rhs; }
  friend ModInt operator/(ModInt lhs, const ModInt &rhs) { return lhs /= rhs; }

  ModInt operator+() const { return *this; }
  ModInt operator-() const {
    if (value == 0)
      return *this;
    return ModInt(getModulo() - value);
  }

  friend bool operator==(const ModInt &lhs, const ModInt &rhs) {
    return lhs.value == rhs.value;
  }
  friend bool operator!=(const ModInt &lhs, const ModInt &rhs) {
    return !(lhs == rhs);
  }

  friend ostream &operator<<(ostream &os, const ModInt &n) {
    return os << n.value;
  }
  friend istream &operator>>(istream &is, ModInt &n) {
    is >> n.value;
    n.value = normalize(n.value, getModulo());
    return is;
  }

  static value_type getModulo() { return ((cmod > 0) ? cmod : rmod); }

  template <int M = Modulo, typename T = typename enable_if<(M <= 0)>::type>
  static T setModulo(value_type m) {
    rmod = m;
  }
};

template <intmax_t M> constexpr typename ModInt<M>::value_type ModInt<M>::cmod;
template <intmax_t M> typename ModInt<M>::value_type ModInt<M>::rmod;
// }}}

// constexpr intmax_t MOD = intmax_t(1e9) + 7;
constexpr intmax_t MOD = 998244353;
using Mint = ModInt<MOD>;

signed main() {
  ioinit();

  var(size_t, N, K);

  vector<intmax_t> w;
  rep(i, 0, K) {
    var(intmax_t, L, R);
    repc(j, L, R) { w.emplace_back(j); }
  }

  sort(w.begin(), w.end(), greater<>());

  vector<Mint> dp(N + 1);
  dp[1] = 1;
  repc(j, 1, N) {
    for (const auto wi : w) {
      if (j + wi <= N) {
        dp[j + wi] += dp[j];
      }
    }
  }

  output(dp.back());
  return 0;
}

#pragma GCC optimize("Ofast")
#include "bits/stdc++.h"

// Begin Header {{{
using namespace std;

#ifndef DEBUG
#define dump(...)
#endif

#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define rep(i, b, e) for (intmax_t i = (b), i##_limit = (e); i < i##_limit; ++i)
#define repc(i, b, e)                                                          \\
  for (intmax_t i = (b), i##_limit = (e); i <= i##_limit; ++i)
#define repr(i, b, e)                                                          \\
  for (intmax_t i = (b), i##_limit = (e); i >= i##_limit; --i)
#define var(Type, ...)                                                         \\
  Type __VA_ARGS__;                                                            \\
  input(__VA_ARGS__)

constexpr size_t operator""_zu(unsigned long long value) { return value; };
constexpr intmax_t operator""_jd(unsigned long long value) { return value; };
constexpr uintmax_t operator""_ju(unsigned long long value) { return value; };

constexpr int INF = 0x3f3f3f3f;
constexpr intmax_t LINF = 0x3f3f3f3f3f3f3f3f_jd;

template <class T, class Compare = less<>>
using MaxHeap = priority_queue<T, vector<T>, Compare>;
template <class T, class Compare = greater<>>
using MinHeap = priority_queue<T, vector<T>, Compare>;

inline void input() {}
template <class Head, class... Tail>
inline void input(Head &&head, Tail &&...tail) {
  cin >> head;
  input(forward<Tail>(tail)...);
}

template <class Container, class Value = typename Container::value_type,
          enable_if_t<!is_same<Container, string>::value, nullptr_t> = nullptr>
inline istream &operator>>(istream &is, Container &vs) {
  for (auto &v : vs)
    is >> v;
  return is;
}

inline void output() { cout << "\\n"; }
template <class Head, class... Tail>
inline void output(Head &&head, Tail &&...tail) {
  cout << head;
  if (sizeof...(tail))
    cout << " ";
  output(forward<Tail>(tail)...);
}

template <class Container, class Value = typename Container::value_type,
          enable_if_t<!is_same<Container, string>::value, nullptr_t> = nullptr>
inline ostream &operator<<(ostream &os, const Container &vs) {
  static constexpr const char *delim[] = {" ", ""};
  for (auto it = begin(vs); it != end(vs); ++it) {
    os << delim[it == begin(vs)] << *it;
  }
  return os;
}

template <class Iterator>
inline void join(const Iterator &Begin, const Iterator &End,
                 const string &delim = "\\n", const string &last = "\\n") {
  for (auto it = Begin; it != End; ++it) {
    cout << ((it == Begin) ? "" : delim) << *it;
  }
  cout << last;
}

template <class T> inline vector<T> makeVector(const T &initValue, size_t sz) {
  return vector<T>(sz, initValue);
}

template <class T, class... Args>
inline auto makeVector(const T &initValue, size_t sz, Args... args) {
  return vector<decltype(makeVector<T>(initValue, args...))>(
      sz, makeVector<T>(initValue, args...));
}

template <class Func> class FixPoint : Func {
public:
  explicit constexpr FixPoint(Func &&f) noexcept : Func(forward<Func>(f)) {}

  template <class... Args>
  constexpr decltype(auto) operator()(Args &&...args) const {
    return Func::operator()(*this, std::forward<Args>(args)...);
  }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func &&f) noexcept {
  return FixPoint<Func>{forward<Func>(f)};
}

template <class Container> struct reverse_t {
  Container &c;
  reverse_t(Container &c) : c(c) {}
  auto begin() { return c.rbegin(); }
  auto end() { return c.rend(); }
};

template <class Container> auto reversed(Container &c) {
  return reverse_t<Container>(c);
}

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

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

template <class T> inline T diff(const T &a, const T &b) noexcept {
  return a < b ? b - a : a - b;
}

void ioinit() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << fixed << setprecision(10);
  clog << fixed << setprecision(10);
}
// }}} End Header

// ModInt {{{
template <intmax_t Modulo> class ModInt {
public:
  using value_type = intmax_t;

private:
  static constexpr value_type cmod = Modulo; // compile-time
  static value_type rmod;                    // runtime
  value_type value = 0;

  static constexpr value_type inverse(value_type n, value_type m) {
    value_type a = n;
    value_type b = m;
    value_type x = 0;
    value_type y = 1;
    for (value_type u = y, v = x; a;) {
      const value_type t = b / a;
      swap(x -= t * u, u);
      swap(y -= t * v, v);
      swap(b -= t * a, a);
    }
    if ((x %= m) < 0)
      x += m;
    return x;
  }

  static value_type normalize(intmax_t n, value_type m) {
    if (n >= m) {
      n %= m;
    } else if (n < 0) {
      if ((n %= m) < 0)
        n += m;
    }
    return n;
  }

public:
  ModInt() = default;
  ModInt(intmax_t n) : value(normalize(n, getModulo())) {}

  template <typename T> constexpr explicit operator T() const {
    return static_cast<T>(value);
  }

  ModInt &operator=(intmax_t n) {
    value = normalize(n, getModulo());
    return *this;
  }

  ModInt &operator+=(const ModInt &other) {
    if ((value += other.value) >= getModulo())
      value -= getModulo();
    return *this;
  }
  ModInt &operator-=(const ModInt &other) {
    if ((value -= other.value) < 0)
      value += getModulo();
    return *this;
  }
  ModInt &operator*=(const ModInt &other) {
    value = (value * other.value) % getModulo();
    return *this;
  }
  ModInt &operator/=(const ModInt &other) {
    value = (value * inverse(other.value, getModulo())) % getModulo();
    return *this;
  }

  ModInt &operator++() {
    if (++value == getModulo())
      value = 0;
    return *this;
  }
  ModInt &operator--() {
    if (value-- == 0)
      value = getModulo() - 1;
    return *this;
  }

  ModInt operator++(int) {
    const ModInt tmp(*this);
    ++*this;
    return tmp;
  }
  ModInt operator--(int) {
    const ModInt tmp(*this);
    --*this;
    return tmp;
  }

  friend ModInt operator+(ModInt lhs, const ModInt &rhs) { return lhs += rhs; }
  friend ModInt operator-(ModInt lhs, const ModInt &rhs) { return lhs -= rhs; }
  friend ModInt operator*(ModInt lhs, const ModInt &rhs) { return lhs *= rhs; }
  friend ModInt operator/(ModInt lhs, const ModInt &rhs) { return lhs /= rhs; }

  ModInt operator+() const { return *this; }
  ModInt operator-() const {
    if (value == 0)
      return *this;
    return ModInt(getModulo() - value);
  }

  friend bool operator==(const ModInt &lhs, const ModInt &rhs) {
    return lhs.value == rhs.value;
  }
  friend bool operator!=(const ModInt &lhs, const ModInt &rhs) {
    return !(lhs == rhs);
  }

  friend ostream &operator<<(ostream &os, const ModInt &n) {
    return os << n.value;
  }
  friend istream &operator>>(istream &is, ModInt &n) {
    is >> n.value;
    n.value = normalize(n.value, getModulo());
    return is;
  }

  static value_type getModulo() { return ((cmod > 0) ? cmod : rmod); }

  template <int M = Modulo, typename T = typename enable_if<(M <= 0)>::type>
  static T setModulo(value_type m) {
    rmod = m;
  }
};

template <intmax_t M> constexpr typename ModInt<M>::value_type ModInt<M>::cmod;
template <intmax_t M> typename ModInt<M>::value_type ModInt<M>::rmod;
// }}}

// constexpr intmax_t MOD = intmax_t(1e9) + 7;
constexpr intmax_t MOD = 998244353;
using Mint = ModInt<MOD>;

// BinaryIndexedTree {{{
template <class T> struct BinaryIndexedTree {
  vector<T> bit;
  const size_t SIZE;

  explicit BinaryIndexedTree(size_t n)
      : bit(n + 5, 0), SIZE(1 << (__lg(n + 5) + 1)) {}

  void add(int i, const T &v) {
    for (++i; i < bit.size(); i += i & -i)
      bit[i] += v;
  }

  // [0, i]
  T sum(int i) const {
    T ret = 0;
    for (++i; i > 0; i -= i & -i)
      ret += bit[i];
    return ret;
  }

  // [s, t]
  T sum(int s, int t) const {
    if (s > t)
      swap(s, t);
    return sum(t) - sum(s - 1);
  }

  size_t lower_bound(T v) const {
    if (v <= 0)
      return 0;
    T x = 0;
    for (size_t k = SIZE; k > 0; k >>= 1) {
      if (x + k < bit.size() && bit[x + k] < v) {
        v -= bit[x + k];
        x += k;
      }
    }
    return x;
  }
};
// }}}

signed main() {
  ioinit();

  var(size_t, N, K);

  vector<intmax_t> L(K), R(K);
  rep(i, 0, K) input(L[i], R[i]);

  vector<Mint> dp(N + 1);
  // dp[i] := マス i に行く方法の総数
  vector<Mint> imos(N + 1);
  dp[1] = 1;
  repc(i, 1, N) {
    imos[i] += imos[i - 1];
    dp[i] += imos[i];
    rep(j, 0, K) {
      if (i + L[j] <= N)
        imos[i + L[j]] += dp[i];
      if (i + R[j] < N)
        imos[i + R[j] + 1] -= dp[i];
    }
  }

  output(dp[N]);
  return 0;
}


#include <bits/stdc++.h>
typedef long long int lli;

#define em emplace_back
#define rep(i, j, n) for (lli i = j; i < n; i++)
#define repf(i, a, j, n) for (lli i = j, a = 0; i < n; i++, a++)
#define repg(i, j, n) for (int i = j; i > n; --i)
using namespace std;
lli m = 998244353;

void solve() {

  lli n, k;
  cin >> n >> k;

  vector<lli> arrfront(n + 1, 0);

  vector<pair<lli, lli>> v;
  unordered_map<lli, lli> s;

  rep(i, 0, k) {
    lli a, b;
    cin >> a >> b;

    v.em(make_pair(a, b));
  }

  vector<lli> arrback(n + 1, 0);
  sort(v.begin(), v.end());
  lli ans = 0;
  rep(i, 1, n) {

    if (arrfront[i] == 0) {
      if (i != 1) {
        continue;
      } else {
        arrfront[i] = 1;
      }
    }

    rep(j, 0, v.size()) {
      if (i + v[j].first > n) {
        break;
      }
      rep(k, v[j].first, v[j].second + 1) {
        if (i + k > n) {
          break;
        }
        arrfront[i + k] = arrfront[i + k] % m;
        arrfront[i + k] = (arrfront[i + k] % m + arrfront[i] % m) % m;
        arrfront[i + k] = arrfront[i + k] % m;
      }
    }
  }

  cout << (arrfront[n] % m);
}

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

  return 0;
}

#include <bits/stdc++.h>
typedef long long int lli;

#define em emplace_back
#define rep(i, j, n) for (lli i = j; i < n; i++)
#define repf(i, a, j, n) for (lli i = j, a = 0; i < n; i++, a++)
#define repg(i, j, n) for (int i = j; i > n; --i)
using namespace std;
lli m = 998244353;

void solve() {

  lli n, k;
  cin >> n >> k;

  vector<lli> temp(n + 1, 0);

  vector<pair<lli, lli>> v;

  rep(i, 0, k) {
    lli a, b;
    cin >> a >> b;

    v.em(make_pair(a, b));
  }

  sort(v.begin(), v.end());
  lli ans = 0;

  temp[1] = 1;

  lli current = 0;
  rep(i, 1, n) {
    temp[i] %= m;
    current = (current + temp[i]);
    if (current <= 0) {
      continue;
    }

    rep(j, 0, v.size()) {
      lli f = i + v[j].first;
      lli l = i + v[j].second;
      if (f > n) {
        break;
      } else {
        temp[f] = (temp[f] + (current));
      }
      if (l + 1 > n) {
        continue;
      } else {
        temp[l + 1] = (temp[l + 1] - current);
      }
    }
    temp[i] = temp[i] % m;
  }

  cout << temp[n] % m;
}

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

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define MOD 998244353
#define N 200005
int n, k;
vector<pair<int, int>> d;
long dp[N], sumdp[N];
int dcnt = 0;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> n >> k;
  d.reserve(k + 1);
  for (int i = 0; i < k; i++) {
    int s, e;
    cin >> s >> e;
    d.push_back({s, e});
  }
  dp[1] = 1;
  sumdp[1] = 1;
  for (int i = 2; i <= n; i++) {
    for (const auto &sect : d) {
      if (sect.first > i)
        continue;
      int ubound = i - sect.first;
      int lbound = min(i - sect.second, i);
      dp[i] = (dp[i] + MOD + sumdp[ubound] - sumdp[lbound - 1]) % MOD;
    }
    sumdp[i] = (sumdp[i - 1] + dp[i]) % MOD;
  }
  cout << dp[n] << '\\n';

  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define MOD 998244353
#define N 200005
int n, k;
vector<pair<int, int>> d;
long dp[N], sumdp[N];
int dcnt = 0;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> n >> k;
  d.reserve(k + 1);
  for (int i = 0; i < k; i++) {
    int s, e;
    cin >> s >> e;
    d.push_back({s, e});
  }
  dp[1] = 1;
  sumdp[1] = 1;
  for (int i = 2; i <= n; i++) {
    for (const auto &sect : d) {
      if (sect.first > i)
        continue;
      int ubound = i - sect.first;
      int lbound = max(i - sect.second, 1);
      dp[i] = (dp[i] + MOD + sumdp[ubound] - sumdp[lbound - 1]) % MOD;
    }
    sumdp[i] = (sumdp[i - 1] + dp[i]) % MOD;
  }
  cout << dp[n] << '\\n';

  return 0;
}


#include <algorithm>
#include <iostream>
#include <set>
#include <string>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 0; i < int(n); i++)
const ll mod = 998244353;
ll dp[200005];

int main() {
  int n, k;
  cin >> n >> k;
  set<int> st;
  rep(i, k) {
    int x, y;
    cin >> x >> y;
    for (int i = x; i <= y; i++) {
      st.insert(i);
    }
  }
  dp[1] = 1LL;

  for (int i = 1; i <= n; i++) {
    for (auto q : st) {
      if (q + i > n)
        break;
      else {
        dp[i + q] += dp[i];
        dp[i + q] %= mod;
      }
    }
  }
  cout << dp[n] << endl;

  return 0;
}

#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 0; i < int(n); i++)
const ll mod = 998244353;

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

  // 総和を N に
  --N;
  vector<ll> dp(N + 1, 0), sdp(N + 2, 0);
  dp[0] = 1, sdp[1] = 1;
  for (int n = 1; n <= N; ++n) {
    for (auto p : v) {
      int left = max(0, n - p.second);
      int right = max(0, n - p.first + 1);
      int diff = sdp[right] - sdp[left];
      if (diff < 0)
        diff += mod;
      dp[n] += diff;
      dp[n] %= mod;
    }
    sdp[n + 1] = sdp[n] + dp[n];
    sdp[n + 1] %= mod;
  }
  cout << dp[N] << endl;
}


#include <algorithm>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using namespace std;

int main() {
  // cout << "" << endl; // prints
  int N, K;
  const int mod = 998244353;
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N >> K;
  int dp[N + 1];
  dp[0] = 0;
  dp[1] = 1;
  for (int a = 2; a <= N; a++) {
    dp[a] = 0;
  }
  int LR[K + 1][3];
  bool TF[N + 1];
  for (int i = 0; i <= N; i++) {
    TF[i] = false;
  }
  for (int i = 1; i <= K; i++) {
    cin >> LR[i][1] >> LR[i][2];
    for (int j = LR[i][1]; j <= LR[i][2]; j++) {
      TF[j] = true;
    }
  }

  for (int i = 1; i <= N; i++) {
    for (int j = 1; j < i; j++) {
      if (TF[i - j] == true) {
        dp[i] += dp[j];
      }
      dp[i] = dp[i] % mod;
    }
  }
  cout << dp[N] << endl;
  return 0;
}

#include <algorithm>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using namespace std;

int main() {
  // cout << "" << endl; // prints
  int N, K;
  const long long int mod = 998244353;
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N >> K;
  long long int dp[N + 1];
  dp[0] = 1;
  dp[1] = -1;
  dp[2] = 0;
  for (int a = 3; a <= N; a++) {
    dp[a] = 0;
  }
  long long int LR[K + 1][3];
  bool TF[N + 1];
  for (int i = 0; i <= N; i++) {
    TF[i] = false;
  }
  for (int i = 1; i <= K; i++) {
    cin >> LR[i][1] >> LR[i][2];
    for (int j = LR[i][1]; j <= LR[i][2]; j++) {
      TF[j] = true;
    }
  }

  for (int i = 0; i < N; i++) {
    if (i > 0)
      dp[i] += dp[i - 1];
    dp[i] = dp[i] % mod;
    for (int j = 1; j <= K; j++) {
      if (i + LR[j][1] < N) {
        dp[i + LR[j][1] + 0] += dp[i];
        dp[i + LR[j][1] + 0] = dp[i + LR[j][1] + 0] % mod;
      }
      if (i + LR[j][2] + 1 < N) {
        dp[i + LR[j][2] + 1] -= dp[i];
        dp[i + LR[j][2] + 1] = dp[i + LR[j][2] + 1] % mod;
      }
    }
  }
  dp[N - 1] = dp[N - 1] % mod;
  if (dp[N - 1] < 0) {
    dp[N - 1] += mod;
  }
  cout << dp[N - 1] << endl;
  return 0;
}


#include <bits/stdc++.h>

#pragma region Macro
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, m, n) for (int i = m; i < n; i++)
#define SORT(v) sort(v.begin(), v.end())
#define pb(a) push_back(a)
#define eb(a) emplace_back(a)
#define vi vector<int>
#define vvi vector<vector<int>>
#define chmax(x, y) (x = max(x, y))
#define chmin(x, y) (x = min(x, y))

using namespace std;
typedef long long ll;
typedef pair<int, int> P;
#pragma endregion

#define MOD 998244353

void solve() {
#define int ll
  // ここに処理を記述
  // コンパイル時はエイリアス「gpp」--> c++17でコンパイル
  int n, k;
  cin >> n >> k;

  int l, r;
  vi s;
  rep(i, k) {
    cin >> l >> r;
    FOR(j, l, r + 1) { s.eb(j); }
  }
  sort(s.begin(), s.end());

  // dp
  vi dp(n + 1, -1);
  dp[1] = 1;
  // 配るDP
  FOR(i, 1, n + 1) {
    // そこにたどり着く方法がないならスキップ
    if (dp[i] == -1)
      continue;
    // 現在位置からいけるところを探索
    rep(j, s.size()) {
      int ele = s[j];
      // マスからはみ出るなら終了
      if (ele + i > n)
        break;
      // はみ出ないなら今までのルートを配る
      if (dp[i + ele] == -1)
        dp[i + ele] = 0;
      dp[i + ele] += dp[i];
      dp[i + ele] = dp[i + ele] % MOD;
    }
  }

  if (dp[n] == -1)
    cout << "0" << endl;
  else
    cout << dp[n] << endl;
}

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(15);

  solve();
  return 0;
}

#include <bits/stdc++.h>

#pragma region Macro
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, m, n) for (int i = m; i < n; i++)
#define SORT(v) sort(v.begin(), v.end())
#define pb(a) push_back(a)
#define eb(a) emplace_back(a)
#define vi vector<int>
#define vvi vector<vector<int>>
#define chmax(x, y) (x = max(x, y))
#define chmin(x, y) (x = min(x, y))

using namespace std;
typedef long long ll;
typedef pair<int, int> P;
#pragma endregion

#define MOD 998244353

void solve() {
#define int ll
  // ここに処理を記述
  // コンパイル時はエイリアス「gpp」--> c++17でコンパイル
  int n, k;
  cin >> n >> k;

  vector<P> rng;
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    r++;
    rng.eb(make_pair(l, r));
  }

  vi dp(n);
  dp[0] = 1;
  dp[1] = -1;

  rep(i, n) {
    // a[i] = f[i] - f[i-1]と定義する
    // a[i]の更新は 各jについて
    // a[i + l[j]] <-- a[i + l[j]] + f[i]
    // a[i + r[j] + 1] <-- a[i + r[j] + 1] - f[i]
    // とすると
    // f[i] = f[i+1] + a[i]で復元できる
    if (i > 0) {
      dp[i] += dp[i - 1];
      dp[i] = (dp[i] % MOD + MOD) % MOD;
    }
    rep(j, k) {
      int l, r;
      tie(l, r) = rng[j];
      if (i + l < n) {
        dp[i + l] += dp[i];
        dp[i + l] = (dp[i + l] % MOD + MOD) % MOD;
      }
      if (i + r < n) {
        dp[i + r] -= dp[i];
        dp[i + r] = (dp[i + r] % MOD + MOD) % MOD;
      }
    }
  }

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

  /*
  int l,r;
  vi s;
  rep(i,k){
          cin >> l >> r;
          FOR(j,l,r+1){
                  s.eb(j);
          }
  }
  sort(s.begin(),s.end());

  // dp
  vi dp(n+1,-1);
  dp[1] = 1;
  // 配るDP
  FOR(i,1,n+1){
          // そこにたどり着く方法がないならスキップ
          if(dp[i] == -1) continue;
          // 現在位置からいけるところを探索
          rep(j, s.size()){
                  int ele = s[j];
                  // マスからはみ出るなら終了
                  if(ele + i > n) break;
                  // はみ出ないなら今までのルートを配る
                  if(dp[i + ele] == -1) dp[i + ele] = 0;
                  dp[i + ele] += dp[i];
                  dp[i + ele] = dp[i + ele] % MOD;
          }
  }

  if(dp[n] == -1) cout << "0" << endl;
  else cout << dp[n] << endl;
  */
}

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(15);

  solve();
  return 0;
}


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

#define ALL(v) v.begin(), v.end()
#define V vector
#define P pair
using ll = long long;
const ll MOD = 998244353;

int main() {
  int n, k;
  cin >> n >> k;
  set<int> se;
  for (int i = 0; i < k; i++) {
    int l, r;
    cin >> l >> r;
    for (int j = l; j <= r; j++) {
      se.insert(j);
    }
  }

  V<ll> dp(n + 1, 0);
  dp[1] = 1;
  for (int i = 1; i < n; i++) {
    for (auto s : se) {
      if (i + s <= n) {
        dp[i + s] += dp[i];
        dp[i + s] %= MOD;
      }
    }
  }
  cout << dp[n] % MOD << endl;

  return 0;
}

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

#define ALL(v) v.begin(), v.end()
#define V vector
#define P pair
using ll = long long;
const ll MOD = 998244353;

int main() {
  int n, k;
  cin >> n >> k;
  V<P<int, int>> v(k);
  for (int i = 0; i < k; i++)
    cin >> v[i].first >> v[i].second;

  V<ll> dp(n, 0), s(n + 1, 0);
  dp[0] = 1, s[1] = 1;
  for (int i = 1; i < n; i++) {
    for (int j = 0; j < k; j++) {
      int l = max(0, i - v[j].second);
      int r = max(0, i - v[j].first + 1);
      dp[i] += (s[r] - s[l] + MOD) % MOD;
      dp[i] %= MOD;
    }
    s[i + 1] = dp[i] + s[i];
    s[i + 1] %= MOD;
  }
  cout << dp[n - 1] << endl;

  return 0;
}


/*
Author- Aasav Badera
Time- Sat Sep 19 17:16:57 2020
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize("-O3")
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include <sys/resource.h>
#define meminc                                                                 \\
  rlimit rlim;                                                                 \\
  if (getrlimit(RLIMIT_STACK, &rlim))                                          \\
    return 1;                                                                  \\
  rlim.rlim_cur = 268435456;                                                   \\
  if (setrlimit(RLIMIT_STACK, &rlim))                                          \\
    return 2;
#else
#define meminc
#endif
#ifdef LOCAL
#define dbg(args...)                                                           \\
  {                                                                            \\
    string _s = #args;                                                         \\
    replace(_s.begin(), _s.end(), ',', ' ');                                   \\
    stringstream _ss(_s);                                                      \\
    istream_iterator<string> _it(_ss);                                         \\
    err(_it, args);                                                            \\
  }
#else
#define dbg(args...)
#endif
struct custom_hash {
  static uint64_t splitmix64(uint64_t x) {
    // http://xorshift.di.unimi.it/splitmix64.c
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }

  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }
};
void err(istream_iterator<string> it) {}
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << endl;
  err(++it, args...);
}
#define ll int
#define vi vector<int>
#define ordered_set                                                            \\
  tree<int, null_type, less<int>, rb_tree_tag,                                 \\
       tree_order_statistics_node_update>
// -------------------Standard Traversal Moves---------------------
// vi fx = {1 ,-1 ,0, 0}, fy = {0, 0, -1, 1};
// vi fx = {2, -2, 2, -2,  1, -1, 1, -1}, fy = {1, 1, -1, -1, 2, 2, -2, -2};
// vi fx = {1, 1, 1, -1, -1 , -1, 0, 0}, fy = {1, -1, 0, 1, -1, 0, 1, -1};
// ----------------------------------------------------------------

#define rep(i, a, b) for (int i = a; i < b; i++)
#define all(a) (a).begin(), (a).end()
#define sz(x) (int)x.size()
#define yes cout << "YES" << endl
#define no cout << "NO" << endl
#define endl '\\n'
const int hell = (int)998244353;
// const int hell = (int)1e9 + 7;
const long long int inf = 3223372036854775807;
const double PI = 3.14159265;
const int N = (int)1e6 + 5;
int n, m, k, a[N];

long long int dp[N];
set<int> s;
long long int solve(int curpos) {
  if (curpos == 1)
    return 1;
  if (curpos <= 0)
    return 0;
  long long int &res = dp[curpos];
  if (res != -1)
    return res;
  res = 0;
  for (auto it : s) {
    if (it >= curpos)
      break;
    res += solve(curpos - it);
    res %= hell;
  }
  return res;
}

int32_t main() {
  meminc;
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cerr.precision(10);
  cout.precision(25);
  cout << fixed;
#ifdef LOCAL
  // for getting input from input.txt
  freopen("input.txt", "r", stdin);
  // for writing output to output.txt
  freopen("output.txt", "w", stdout);
#endif
  int tests = 1;
  // cin >> tests;
  rep(test, 1, tests + 1) {
    cin >> n;
    cin >> k;
    memset(dp, -1, sizeof dp);
    rep(i, 0, k) {
      int l, r;
      cin >> l >> r;
      rep(j, l, r + 1) s.insert(j);
    }
    cout << solve(n);
  }
#ifdef LOCAL
  // cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\\n";
#endif
  return 0;
}

/*
Author- Aasav Badera
Time- Sat Sep 19 17:16:57 2020
*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize("-O3")
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
using namespace std;
using namespace __gnu_pbds;
#ifdef LOCAL
#include <sys/resource.h>
#define meminc                                                                 \\
  rlimit rlim;                                                                 \\
  if (getrlimit(RLIMIT_STACK, &rlim))                                          \\
    return 1;                                                                  \\
  rlim.rlim_cur = 268435456;                                                   \\
  if (setrlimit(RLIMIT_STACK, &rlim))                                          \\
    return 2;
#else
#define meminc
#endif
#ifdef LOCAL
#define dbg(args...)                                                           \\
  {                                                                            \\
    string _s = #args;                                                         \\
    replace(_s.begin(), _s.end(), ',', ' ');                                   \\
    stringstream _ss(_s);                                                      \\
    istream_iterator<string> _it(_ss);                                         \\
    err(_it, args);                                                            \\
  }
#else
#define dbg(args...)
#endif
struct custom_hash {
  static uint64_t splitmix64(uint64_t x) {
    // http://xorshift.di.unimi.it/splitmix64.c
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }

  size_t operator()(uint64_t x) const {
    static const uint64_t FIXED_RANDOM =
        chrono::steady_clock::now().time_since_epoch().count();
    return splitmix64(x + FIXED_RANDOM);
  }
};
void err(istream_iterator<string> it) {}
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << endl;
  err(++it, args...);
}
#define ll int
#define vi vector<int>
#define ordered_set                                                            \\
  tree<int, null_type, less<int>, rb_tree_tag,                                 \\
       tree_order_statistics_node_update>
// -------------------Standard Traversal Moves---------------------
// vi fx = {1 ,-1 ,0, 0}, fy = {0, 0, -1, 1};
// vi fx = {2, -2, 2, -2,  1, -1, 1, -1}, fy = {1, 1, -1, -1, 2, 2, -2, -2};
// vi fx = {1, 1, 1, -1, -1 , -1, 0, 0}, fy = {1, -1, 0, 1, -1, 0, 1, -1};
// ----------------------------------------------------------------

#define rep(i, a, b) for (int i = a; i < b; i++)
#define all(a) (a).begin(), (a).end()
#define sz(x) (int)x.size()
#define yes cout << "YES" << endl
#define no cout << "NO" << endl
#define endl '\\n'
const int hell = (int)998244353;
// const int hell = (int)1e9 + 7;
const long long int inf = 3223372036854775807;
const double PI = 3.14159265;
const int N = (int)2e5 + 5;
int n, m, k, a[N];

long long int dp[N];
set<int> s;

int32_t main() {
  meminc;
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cerr.precision(10);
  cout.precision(25);
  cout << fixed;
#ifdef LOCAL
  // for getting input from input.txt
  freopen("input.txt", "r", stdin);
  // for writing output to output.txt
  freopen("output.txt", "w", stdout);
#endif
  int tests = 1;
  // cin >> tests;
  rep(test, 1, tests + 1) {
    cin >> n;
    cin >> k;
    memset(dp, 0, sizeof dp);
    int l[k], r[k];
    rep(i, 0, k) { cin >> l[i] >> r[i]; }
    int dp1[n + 1];
    memset(dp1, 0, sizeof dp1);
    dp[1] = 1;
    rep(i, 1, n) {
      if (i > 1)
        dp[i] = dp1[i];
      dp[i] %= hell;
      rep(j, 0, k) {
        if (i + l[j] > n)
          continue;
        dp1[i + l[j]] += dp[i];
        dp1[i + l[j]] %= hell;
        if (i + r[j] + 1 > n)
          continue;
        dp1[i + r[j] + 1] -= dp[i];
        dp1[i + r[j] + 1] %= hell;
        dp1[i + r[j] + 1] += hell;
        dp1[i + r[j] + 1] %= hell;
      }
      dp1[i + 1] += dp1[i];
      dp1[i + 1] %= hell;
    }
    cout << dp1[n] % hell;
  }
#ifdef LOCAL
  cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\\n";
#endif
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
/// Welcome to Nasif's Code
#define bug printf("bug\\n");
#define bug2(var) cout << #var << " " << var << endl;
#define co(q) cout << q << endl;
#define all(q) (q).begin(), (q).end()
#define pi acos(-1)
#define inf 1000000000000000LL
#define FastRead                                                               \\
  ios::sync_with_stdio(0);                                                     \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define MODADD(ADD_X, ADD_Y) (ADD_X + ADD_Y) % MOD;
#define MODSUB(SUB_X, SUB_Y)  (SUB_X-SUB_Y)+MOD)%MOD;
#define MODMUL(MUL_X, MUL_Y) (MUL_X * MUL_Y) % MOD;
#define LCM(LCM_X, LCM_Y) (LCM_X * LCM_Y) / __gcd(LCM_X, LCM_Y);
typedef long long int ll;
typedef unsigned long long int ull;
const int MOD = (int)998244353;
const int MAX = 1e6;
int dx[] = {1, 0, -1, 0, 1, -1, 1, -1};
int dy[] = {0, 1, 0, -1, 1, -1, -1, 1};
int arr[MAX], n, k;
ll ans[MAX];
ll dp[MAX];
ll recur(int pos) {
  if (pos == n)
    return 1;
  else if (pos > n)
    return 0;
  ll &ret = dp[pos];
  if (~ret)
    return ret;
  ret = 0;
  for (int i = 1; i + pos <= n; i++) {
    if (!arr[i])
      continue;
    ret += recur(pos + i);
    ret %= MOD;
  }
  return ret;
}
int main() {
  FastRead
          // freopen("output.txt", "w", stdout);
          cin >>
      n >> k;
  while (k--) {
    int l, r;
    cin >> l >> r;
    arr[l]++;
    arr[r + 1]--;
  }
  memset(dp, -1, sizeof(dp));
  for (int i = 1; i <= n; i++)
    arr[i] += arr[i - 1];
  cout << recur(1) << endl;

  return 0;
}

#include <bits/stdc++.h>
using namespace std;
/// Welcome to Nasif's Code
#define bug printf("bug\\n");
#define bug2(var) cout << #var << " " << var << endl;
#define co(q) cout << q << endl;
#define all(q) (q).begin(), (q).end()
#define pi acos(-1)
#define inf 1000000000000000LL
#define FastRead                                                               \\
  ios::sync_with_stdio(0);                                                     \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define MODADD(ADD_X, ADD_Y) (ADD_X + ADD_Y) % MOD;
#define MODSUB(SUB_X, SUB_Y)  (SUB_X-SUB_Y)+MOD)%MOD;
#define MODMUL(MUL_X, MUL_Y) (MUL_X * MUL_Y) % MOD;
#define LCM(LCM_X, LCM_Y) (LCM_X * LCM_Y) / __gcd(LCM_X, LCM_Y);
typedef long long int ll;
typedef unsigned long long int ull;
const ll MOD = 998244353;
const int MAX = 1e6;
int dx[] = {1, 0, -1, 0, 1, -1, 1, -1};
int dy[] = {0, 1, 0, -1, 1, -1, -1, 1};
ll tree[MAX];
ll query(int idx) {
  ll sum = 0;
  while (idx > 0) {
    sum += tree[idx];
    idx -= idx & (-idx);
  }
  return sum;
}
void update(int idx, int x,
            int n) // n is the size of the array, x is the number to add
{
  while (idx <= n) {
    tree[idx] += x;
    idx += idx & (-idx);
  }
}
int x[20], y[20];
ll dp[MAX];
int main() {
  FastRead
      // freopen("output.txt", "w", stdout);
      int n,
      k;
  cin >> n >> k;
  for (int i = 0; i < k; i++)
    cin >> x[i] >> y[i];
  dp[n] = 1;
  update(n, 1, n);
  for (int i = n - 1; i > 0; i--) {
    for (int j = 0; j < k; j++) {

      int l = i + x[j];
      int r = i + y[j];
      if (l > n)
        continue;
      r = min(r, n);
      ll ways = query(r) - query(l - 1);
      // cout<<i<<" "<<ways<<endl;
      dp[i] = MODADD(dp[i], ways);
    }
    update(i, dp[i], n);
  }
  cout << dp[1] << endl;

  return 0;
}


#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <forward_list>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <tuple>
#include <utility>
#include <vector>
#define rep(i, s, g) for ((i) = (s); (i) < (g); ++(i))
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
const ll MOD = 998244353;
const ll INF = (1ll << 60);

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

  vector<ll> l(k), r(k), dp(n + 1, 0), s(n + 1, 0);

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

  dp[0] = 1;
  s[1] = 1;

  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      ll x, y;

      if (i - l[j] < 0) {
        continue;
      }

      x = max(i - l[j], 0ll) + 1; // big
      y = max(i - r[j], 0ll);     // small

      dp[i] += s[x] - s[y] + MOD;
      dp[i] %= MOD;
    }

    s[i + 1] = s[i] + dp[i] + MOD;
    s[i + 1] %= MOD;
  }

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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <forward_list>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <tuple>
#include <utility>
#include <vector>
#define rep(i, s, g) for ((i) = (s); (i) < (g); ++(i))
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
const ll MOD = 998244353;
const ll INF = (1ll << 60);

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

  vector<ll> l(k), r(k), dp(n + 100, 0), s(n + 100, 0);

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

  dp[0] = 1;
  s[1] = 1;

  for (int i = 1; i < n; i++) {
    for (int j = 0; j < k; j++) {
      ll x, y;

      if (i - l[j] < 0) {
        continue;
      }

      x = max(i - l[j], 0ll) + 1; // big
      y = max(i - r[j], 0ll);     // small

      dp[i] += s[x] - s[y] + MOD;
      dp[i] %= MOD;
    }

    s[i + 1] = s[i] + dp[i] + MOD;
    s[i + 1] %= MOD;
  }

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


#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <forward_list>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <tuple>
#include <utility>
#include <vector>
#define rep(i, s, g) for ((i) = (s); (i) < (g); ++(i))
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
const ll MOD = 998244353;
const ll INF = (1ll << 60);

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

  vector<ll> l(k), r(k), dp(n, 0), s(n + 1, 0);

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

  dp[0] = 1;
  s[1] = 1;

  for (int i = 1; i < n; i++) {
    for (int j = 0; j < k; j++) {
      ll x, y;

      if (i - l[j] < 0) {
        continue;
      }

      x = i - l[j] + 1; // big
      y = i - r[j];     // small

      dp[i] += s[x] - s[y] + MOD;
      dp[i] %= MOD;
    }

    s[i + 1] = s[i] + dp[i] + MOD;
    s[i + 1] %= MOD;
  }

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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>
#include <forward_list>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <tuple>
#include <utility>
#include <vector>
#define rep(i, s, g) for ((i) = (s); (i) < (g); ++(i))
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
const ll MOD = 998244353;
const ll INF = (1ll << 60);

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

  vector<ll> l(k), r(k), dp(n, 0), s(n + 1, 0);

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

  dp[0] = 1;
  s[1] = 1;

  for (int i = 1; i < n; i++) {
    for (int j = 0; j < k; j++) {
      ll x, y;

      if (i - l[j] < 0) {
        continue;
      }

      x = max(i - l[j], 0ll) + 1; // big
      y = max(i - r[j], 0ll);     // small

      dp[i] += s[x] - s[y] + MOD;
      dp[i] %= MOD;
    }

    s[i + 1] = s[i] + dp[i] + MOD;
    s[i + 1] %= MOD;
  }

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


#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define pb push_back
#define ll long long
#define Mid ((L + R) / 2)
#define pi pair<int, int>
#define pii pair<int, pi>
#define deb(x) cout << #x << "=" << x << endl
#define go                                                                     \\
  ios::sync_with_stdio(0);                                                     \\
  cin.tie(0);                                                                  \\
  cout.tie(0)
const int N = 2e5 + 7;
int dp[5 * N], lazy[5 * N], n, k, a[20], b[20];
int mod = 998244353;
int sum(int x, int y) {
  x %= mod;
  y %= mod;
  return (x + y) % mod;
}
void Lazy(int p, int L, int R) {
  dp[p] = sum(dp[p], lazy[p]);
  if (L != R) {
    lazy[2 * p] = sum(lazy[p], lazy[2 * p]);
    lazy[2 * p + 1] = sum(lazy[p], lazy[2 * p + 1]);
  }
  lazy[p] = 0;
  return;
}
int get(int i, int p = 1, int L = 1, int R = n) {
  Lazy(p, L, R);
  if (L == R)
    return dp[p];
  if (i <= Mid)
    return get(i, 2 * p, L, Mid);
  return get(i, 2 * p + 1, Mid + 1, R);
}
void upd(int l, int r, int x, int p = 1, int L = 1, int R = n) {
  Lazy(p, L, R);
  if (l > R || r < L)
    return;
  if (L >= l && R <= r) {
    lazy[p] = x;
    Lazy(p, L, R);
    return;
  }
  upd(l, r, x, 2 * p, L, Mid);
  upd(l, r, x, 2 * p + 1, Mid + 1, R);
  return;
}
int main() {
  go;
  cin >> n >> k;
  for (int i = 0; i < k; i++)
    cin >> a[i] >> b[i];
  upd(1, 1, 1);
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      int L = i + a[j];
      int R = i + b[j];
      if (L > n)
        continue;
      R = min(R, n);
      upd(L, R, get(i));
    }
  }
  cout << get(n);
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define pb push_back
#define ll long long
#define Mid ((L + R) / 2)
#define pi pair<int, int>
#define pii pair<int, pi>
#define deb(x) cout << #x << "=" << x << endl
#define go                                                                     \\
  ios::sync_with_stdio(0);                                                     \\
  cin.tie(0);                                                                  \\
  cout.tie(0)
const int N = 2e5 + 7;
int dp[5 * N], lazy[5 * N], n, k, a[20], b[20];
int mod = 998244353;
int sum(int x, int y) {
  x += y;
  if (x >= mod)
    x -= mod;
  return x;
}
void Lazy(int p, int L, int R) {
  dp[p] = sum(dp[p], lazy[p]);
  if (L != R) {
    lazy[2 * p] = sum(lazy[p], lazy[2 * p]);
    lazy[2 * p + 1] = sum(lazy[p], lazy[2 * p + 1]);
  }
  lazy[p] = 0;
  return;
}
int get(int i, int p = 1, int L = 1, int R = n) {
  Lazy(p, L, R);
  if (L == R)
    return dp[p];
  if (i <= Mid)
    return get(i, 2 * p, L, Mid);
  return get(i, 2 * p + 1, Mid + 1, R);
}
void upd(int l, int r, int x, int p = 1, int L = 1, int R = n) {
  Lazy(p, L, R);
  if (l > R || r < L)
    return;
  if (L >= l && R <= r) {
    lazy[p] = x;
    Lazy(p, L, R);
    return;
  }
  upd(l, r, x, 2 * p, L, Mid);
  upd(l, r, x, 2 * p + 1, Mid + 1, R);
  return;
}
int main() {
  scanf("%d %d", &n, &k);
  for (int i = 0; i < k; i++)
    scanf("%d %d", a + i, b + i);
  upd(1, 1, 1);
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      int L = i + a[j];
      int R = i + b[j];
      if (L > n)
        continue;
      R = min(R, n);
      upd(L, R, get(i));
    }
  }
  printf("%d", get(n));
  return 0;
}


#include <algorithm>
#include <array>
#include <bitset>
#include <cctype>
#include <cfloat>
#include <cinttypes>
#include <climits>
#include <cmath>
#include <complex>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <valarray>
#include <vector>

using namespace std;

const double EPS = 1e-10;
const int64_t INF = 1e9;
// typedef long long ll;
typedef int ll;

const int QMAX = 530000;
const int MOD = 998244353;

int n;
ll dat[QMAX];

void init(int _n) {
  n = 1;
  while (n < _n)
    n *= 2;

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

ll val(int k) {
  k += n - 1;
  ll ans = dat[k];
  while (k > 0) {
    k = (k - 1) / 2;
    ans = (ans + dat[k]) % MOD;
  }
}

void add(int a, int b, ll x, int k, int l, int r) {
  if (r <= a || b <= l)
    return;

  if (a <= l && r <= b) {
    dat[k] = (dat[k] + x) % MOD;
  } else {
    add(a, b, x, k * 2 + 1, l, (l + r) / 2);
    add(a, b, x, k * 2 + 2, (l + r) / 2, r);
  }
}

int main() {
  int m, k;
  int l[10], r[10];
  scanf("%d%d", &m, &k);
  for (int i = 0; i < k; ++i) {
    scanf("%d%d", &l[i], &r[i]);
  }

  init(m + 2);

  add(1, 2, 1, 0, 0, n);
  for (int i = 1; i < m; ++i) {
    ll a = val(i);
    for (int j = 0; j < k; ++j) {
      if (i + l[j] > n)
        continue;
      int ed = min(i + r[j], n);
      add(i + l[j], ed + 1, a, 0, 0, n);
    }

    /*
    for (int j = 0; j <= m; ++j) {
            printf("%d: %d\\n", j, val(j));
    }
    printf("\\n");
    */
  }

  printf("%lld\\n", val(m));

  return 0;
}

#include <algorithm>
#include <array>
#include <bitset>
#include <cctype>
#include <cfloat>
#include <cinttypes>
#include <climits>
#include <cmath>
#include <complex>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <valarray>
#include <vector>

using namespace std;

const double EPS = 1e-10;
const int64_t INF = 1e9;
// typedef long long ll;
typedef int ll;

const int QMAX = 530000;
const int MOD = 998244353;

int n;
ll dat[QMAX];

void init(int _n) {
  n = 1;
  while (n < _n)
    n *= 2;

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

ll val(int k) {
  k += n - 1;
  ll ans = dat[k];
  while (k > 0) {
    k = (k - 1) / 2;
    ans = (ans + dat[k]) % MOD;
  }
  return ans;
}

void add(int a, int b, ll x, int k, int l, int r) {
  if (r <= a || b <= l)
    return;

  if (a <= l && r <= b) {
    dat[k] = (dat[k] + x) % MOD;
  } else {
    add(a, b, x, k * 2 + 1, l, (l + r) / 2);
    add(a, b, x, k * 2 + 2, (l + r) / 2, r);
  }
}

int main() {
  int m, k;
  int l[10], r[10];
  scanf("%d%d", &m, &k);
  for (int i = 0; i < k; ++i) {
    scanf("%d%d", &l[i], &r[i]);
  }

  init(m + 2);

  add(1, 2, 1, 0, 0, n);
  for (int i = 1; i < m; ++i) {
    ll a = val(i);
    for (int j = 0; j < k; ++j) {
      if (i + l[j] > n)
        continue;
      int ed = min(i + r[j], n);
      add(i + l[j], ed + 1, a, 0, 0, n);
    }

    /*
    for (int j = 0; j <= m; ++j) {
            printf("%d: %d\\n", j, val(j));
    }
    printf("\\n");
    */
  }

  printf("%lld\\n", val(m));

  return 0;
}


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

using namespace std;

typedef long long ll;

const ll MOD = 998244353;

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

struct segment_tree {
  vector<ll> t;
  segment_tree(int n) { t.resize(n << 2); }
  void update(int v, int tl, int tr, int l, int r, int val) {
    if (l > r)
      return;
    if (l == tl && r == tr) {
      t[v] = sum(t[v], val);
      return;
    }
    int tm = (tl + tr) / 2;
    t[v * 2] = sum(t[v * 2], t[v]);
    t[v * 2 + 1] = sum(t[v * 2 + 1], t[v]);
    t[v] = 0;
    update(v * 2, tl, tm, l, min(r, tm), val);
    update(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r, val);
  }
  ll get(int v, int tl, int tr, int pos) {
    if (tl == tr)
      return t[v];
    int tm = (tl + tr) / 2;
    t[v * 2] = sum(t[v * 2], t[v]);
    t[v * 2 + 1] = sum(t[v * 2 + 1], t[v]);
    t[v] = 0;
    if (pos <= tm)
      get(v * 2, tl, tm, pos);
    else
      get(v * 2 + 1, tm + 1, tr, pos);
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, k;
  cin >> n >> k;
  vector<pair<int, int>> a(k);
  for (int i = 0; i < k; i++)
    cin >> a[i].first >> a[i].second;
  segment_tree se(n);
  se.update(1, 0, n - 1, 0, 0, 1);
  for (int i = 0; i < n; i++) {
    ll val = se.get(1, 0, n - 1, i);
    for (auto &now : a)
      se.update(1, 0, n - 1, i + now.first, min(i + now.second, n - 1), val);
  }
  cout << se.get(1, 0, n - 1, n - 1);
  return 0;
}

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

using namespace std;

typedef long long ll;

const ll MOD = 998244353;

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

struct segment_tree {
  vector<ll> t;
  segment_tree(int n) { t.resize(n << 2); }
  void update(int v, int tl, int tr, int l, int r, int val) {
    if (l > r)
      return;
    if (l == tl && r == tr) {
      t[v] = sum(t[v], val);
      return;
    }
    int tm = (tl + tr) / 2;
    t[v * 2] = sum(t[v * 2], t[v]);
    t[v * 2 + 1] = sum(t[v * 2 + 1], t[v]);
    t[v] = 0;
    update(v * 2, tl, tm, l, min(r, tm), val);
    update(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r, val);
  }
  ll get(int v, int tl, int tr, int pos) {
    if (tl == tr)
      return t[v];
    int tm = (tl + tr) / 2;
    t[v * 2] = sum(t[v * 2], t[v]);
    t[v * 2 + 1] = sum(t[v * 2 + 1], t[v]);
    t[v] = 0;
    if (pos <= tm)
      return get(v * 2, tl, tm, pos);
    else
      return get(v * 2 + 1, tm + 1, tr, pos);
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, k;
  cin >> n >> k;
  vector<pair<int, int>> a(k);
  for (int i = 0; i < k; i++)
    cin >> a[i].first >> a[i].second;
  segment_tree se(n);
  se.update(1, 0, n - 1, 0, 0, 1);
  for (int i = 0; i < n; i++) {
    ll val = se.get(1, 0, n - 1, i);
    for (auto &now : a)
      se.update(1, 0, n - 1, i + now.first, min(i + now.second, n - 1), val);
  }
  cout << se.get(1, 0, n - 1, n - 1);
  return 0;
}


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

const ll mod = 998244353;
int main() {
  ll n, k;
  cin >> n >> k;

  vector<pair<int, int>> s(0);
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    s.push_back({l, r});
  }

  static ll dp[2000000] = {0};
  dp[0] = 1;
  rep(i, n) {
    for (auto p : s) {
      for (int j = p.first; j <= p.second; j++) {
        dp[i + j] += dp[i];
        dp[i + j] %= mod;
      }
    }
  }
  cout << dp[n - 1] << endl;
}

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

const ll mod = 998244353;
int main() {
  ll n, k;
  cin >> n >> k;

  vector<pair<int, int>> s(0);
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    s.push_back({l, r});
  }

  static ll dp[200005] = {0};
  static ll dpsum[200005] = {0};
  dp[1] = 1;
  dpsum[1] = 1;
  for (int i = 2; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      int li = i - s[j].second;
      int ri = i - s[j].first;
      if (ri < 0)
        continue;
      li = max(1, li);
      dp[i] += dpsum[ri] - dpsum[li - 1] + mod;
      dp[i] %= mod;
    }
    dpsum[i] = dpsum[i - 1] + dp[i];
    dpsum[i] %= mod;
  }
  cout << dp[n] << endl;
}


#include <math.h>
#include <stdio.h>
#include <string.h>

#include <algorithm>
#include <bitset>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

constexpr long long INFLL = 1e18;

using namespace std;
using ll = long long;
using P = pair<int, int>;

int main() {
  const int mPN = 998244353;
  int n, k;
  cin >> n >> k;
  int l, r;
  vector<int> v;
  for (int i = 0; i < k; i++) {
    cin >> l >> r;

    for (int j = l; j <= r; j++) {
      v.push_back(j);
    }
  }
  sort(v.begin(), v.end());
  vector<int> dp(n, 0);
  dp.at(0) = 1;
  int temp;
  for (int i = 1; i < n; i++) {
    for (int j = 0; j < v.size(); j++) {
      temp = i - v.at(j);
      if (temp >= 0) {
        dp.at(i) += dp.at(temp);
        dp.at(i) %= mPN;
      } else {
        break;
      }
    }
  }

  cout << dp.at(n - 1) << endl;
  return 0;
}

#include <math.h>
#include <stdio.h>
#include <string.h>

#include <algorithm>
#include <bitset>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

constexpr long long INFLL = 1e18;

using namespace std;
using ll = long long;
using P = pair<int, int>;

int main() {
  const int mPN = 998244353;
  ll n, k;
  cin >> n >> k;
  vector<ll> l(k);
  vector<ll> r(k);

  for (int i = 0; i < k; i++) {
    cin >> l.at(i) >> r.at(i);
  }

  vector<ll> alSum(n + 1, 0);
  vector<ll> dp(n + 1, 0);

  dp.at(1) = 1;
  alSum.at(1) = 1;

  for (int i = 2; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      ll tempL, tempR;
      tempL = i - l.at(j);
      tempR = i - r.at(j);
      if (tempR >= 1) {
        if (tempR == tempL) {
          dp.at(i) += dp.at(tempL);
        } else {
          dp.at(i) += alSum.at(tempL) - alSum.at(tempR - 1);
        }
      } else if (tempL >= 0) {
        dp.at(i) += alSum.at(tempL) - alSum.at(0);
      }
      dp.at(i) %= mPN;
    }
    alSum.at(i) = alSum.at(i - 1) + dp.at(i);
    alSum.at(i) %= mPN;
  }
  if (dp.at(n) < 0) {
    dp.at(n) += mPN;
  }
  cout << dp.at(n) << endl;
  return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

#define ff first
#define ss second
#define endl "\\n"
#define loop(i, s, e) for (int i = s; i < e; i++)
#define int long long
#define vi vector<int>
#define S(v) sort(v.begin(), v.end())
#define RS(v) sort(v.rbegin(), v.rend())
#define R(v) reverse(v.begin(), v.end())
#define mxpq(T) priority_queue<T>
#define mnpq(T) priority_queue<T, vector<T>, greater<T>>
#define prv(v)                                                                 \\
  for (auto &x : v)                                                            \\
    cout << x << " ";
#define piirv(v)                                                               \\
  for (auto &x : v)                                                            \\
    cout << x.ff << " " << x.ss << endl;
#define prvv(v)                                                                \\
  for (auto &x : v)                                                            \\
    for (auto &y : x.ss)                                                       \\
      cout << y << " ";
#define mp make_pair
#define pii pair<int, int>
#define mset(a, f) memset(a, f, sizeof(a))
#define pb push_back
#define inf INT_MAX
#define INF LLONG_MAX
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    oset;

const int N = 2e6 + 6;
const int M = 998244353;
int A[N];
int dp[N];
int n, k;
map<int, int> mmp;

int alpha(int i) {
  if (i == n)
    return 1;
  if (i > n)
    return 0;
  int &abs = dp[i];
  if (abs != -1)
    return abs;

  int ans = 0;

  for (auto &it : mmp) {
    ans = (ans % M + alpha(i + it.ff) % M) % M;
    ans %= M;
  }

  return abs = ans % M;
}

void solve() {
  cin >> n >> k;

  map<int, int> m;

  loop(i, 0, k) {
    int x, y;
    cin >> x >> y;
    loop(j, x, y + 1) m[j]++;
    // mmp[x]++ , mmp[y]++;
  }
  for (auto &it : m) {
    if (it.ff < n)
      mmp[it.ff]++;
    else
      break;
  }
  mset(dp, -1);
  int ans = alpha(1);

  cout << ans;
}

int32_t main() {

  cout << fixed << setprecision(16);

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

  int t = 1;
  // cin >> t;
  while (t--)
    solve();
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

#define ff first
#define ss second
#define endl "\\n"
#define loop(i, s, e) for (int i = s; i < e; i++)
#define int long long
#define vi vector<int>
#define S(v) sort(v.begin(), v.end())
#define RS(v) sort(v.rbegin(), v.rend())
#define R(v) reverse(v.begin(), v.end())
#define mxpq(T) priority_queue<T>
#define mnpq(T) priority_queue<T, vector<T>, greater<T>>
#define prv(v)                                                                 \\
  for (auto &x : v)                                                            \\
    cout << x << " ";
#define piirv(v)                                                               \\
  for (auto &x : v)                                                            \\
    cout << x.ff << " " << x.ss << endl;
#define prvv(v)                                                                \\
  for (auto &x : v)                                                            \\
    for (auto &y : x.ss)                                                       \\
      cout << y << " ";
#define mp make_pair
#define pii pair<int, int>
#define mset(a, f) memset(a, f, sizeof(a))
#define pb push_back
#define inf INT_MAX
#define INF LLONG_MAX
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    oset;

const int N = 2e6 + 6;
const int M = 998244353;
int A[N];
int dp[N];
int n, m;

inline int mul(int a, int b) { return (a * b) % M; };
inline int add(int a, int b) {
  int res = a + b;
  if (res < 0)
    res += M;
  if (res >= M)
    res -= M;
  return res;
}

void solve() {
  int n, k;
  cin >> n >> k;
  vector<pii> vec(k);
  loop(i, 0, k) cin >> vec[i].ff >> vec[i].ss;
  S(vec);

  dp[0] = 0;
  dp[1] = 1;

  loop(i, 2, n + 1) {
    loop(j, 0, k) {
      int l = max(i - vec[j].ss, 1ll);
      int r = max(i - vec[j].ff, 0ll);

      dp[i] = add(dp[i], add(dp[r], -dp[l - 1]));
    }
    dp[i] = add(dp[i], dp[i - 1]);
  }

  cout << (dp[n] - dp[n - 1] + M) % M;
}

int32_t main() {

  cout << fixed << setprecision(16);

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

  int t = 1;
  // cin >> t;
  while (t--)
    solve();
}


#include <algorithm>
#include <bits/stdc++.h>
#include <bitset>
#include <cmath>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define exout(x) printf("%.10f\\n", x)
#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)
const double pi = acos(-1.0);
const ll MOD = 1000000007;
const ll INF = 1e18;
const ll MAX_N = 201010;

// 組み合わせの余りを求める
ll fac[MAX_N], finv[MAX_N], inv[MAX_N];
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX_N; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算
long long COM(ll n, ll k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

// 最大公約数
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }

ll lcm(ll x, ll y) {
  if (x == 0 || y == 0)
    return 0;
  return (x / gcd(x, y) * y);
}

ll dx[4] = {0, 0, -1, 1};
ll dy[4] = {-1, 1, 0, 0};
ll dp[201010];

// long longしか使わない
// 素数は1より大きい
// lower_boundは指定したkey以上の要素の一番左のイテレータをかえす
// upper_boundは指定したkeyより大きい要素の一番左のイテレータをかえす
int main() {
  ll n, k;
  cin >> n >> k;
  vector<ll> sum(n);
  ll waru = 998244353;
  rep(i, k) {
    ll r, l;
    cin >> l >> r;
    l--;
    r--;
    sum[l]++;
    sum[r + 1]--;
  }
  rep(i, n - 1) { sum[i + 1] += sum[i]; }
  vector<ll> option;
  rep(i, n) {
    if (sum[i])
      option.push_back(i + 1);
  }
  dp[0] = 1;
  rep(i, n) {
    rep(j, option.size()) {
      if (i + option[j] < n) {
        dp[i + option[j]] += dp[i];
        dp[i + option[j]] %= waru;
      }
    }
  }
  cout << dp[n - 1] << endl;
  return 0;
}

#include <algorithm>
#include <bits/stdc++.h>
#include <bitset>
#include <cmath>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define exout(x) printf("%.10f\\n", x)
#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)
const double pi = acos(-1.0);
const ll MOD = 1000000007;
const ll INF = 1e18;
const ll MAX_N = 201010;

// 組み合わせの余りを求める
ll fac[MAX_N], finv[MAX_N], inv[MAX_N];
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX_N; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算
long long COM(ll n, ll k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

// 最大公約数
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }

ll lcm(ll x, ll y) {
  if (x == 0 || y == 0)
    return 0;
  return (x / gcd(x, y) * y);
}

ll dx[4] = {0, 0, -1, 1};
ll dy[4] = {-1, 1, 0, 0};
ll dp[201010];

// long longしか使わない
// 素数は1より大きい
// lower_boundは指定したkey以上の要素の一番左のイテレータをかえす
// upper_boundは指定したkeyより大きい要素の一番左のイテレータをかえす
int main() {
  ll n, k;
  cin >> n >> k;
  vector<pair<ll, ll>> p(k);
  ll waru = 998244353;
  rep(i, k) {
    ll r, l;
    cin >> l >> r;
    r++;
    p[i].first = l;
    p[i].second = r;
  }
  dp[0] = 1;
  dp[1] = -1;
  rep(i, n - 1) {
    dp[i + 1] += dp[i];
    dp[i + 1] %= waru;
    rep(j, k) {
      if (i + p[j].first < n)
        dp[i + p[j].first] += dp[i];
      dp[i + p[j].first] %= waru;
      if (i + p[j].second < n)
        dp[i + p[j].second] -= dp[i];
      dp[i + p[j].second] += waru;
      dp[i + p[j].second] %= waru;
    }
  }
  cout << dp[n - 1] << endl;
  return 0;
}