#include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;
template <typename T> bool chmax(T &u, const T z) {
  if (u < z) {
    u = z;
    return true;
  } else
    return false;
}
template <typename T> bool chmin(T &u, const T z) {
  if (u > z) {
    u = z;
    return true;
  } else
    return false;
}
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define ll long long
typedef pair<ll, ll> P;
const ll INF = 1LL << 60;
// const int MOD = 1000000007;
const ll MOD = 998244353;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }

ll dp[202020];
ll mp[202020];
int main() {
  ll n, k;
  cin >> n >> k;
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    mp[l]++;
    mp[r + 1]--;
  }
  for (int i = 1; i < 202020; i++) {
    mp[i] += mp[i - 1];
  }
  vector<int> num;
  rep(i, 202020) if (mp[i] > 0) num.push_back(i);
  sort(num.begin(), num.end());
  dp[1] = 1;
  for (int i = 1; i <= n; i++) {
    rep(j, num.size()) {
      if (i + num[j] > n)
        break;
      dp[i + num[j]] += dp[i];
      dp[i + num[j]] %= MOD;
    }
  }
  cout << dp[n] << endl;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;
template <typename T> bool chmax(T &u, const T z) {
  if (u < z) {
    u = z;
    return true;
  } else
    return false;
}
template <typename T> bool chmin(T &u, const T z) {
  if (u > z) {
    u = z;
    return true;
  } else
    return false;
}
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define ll long long
typedef pair<ll, ll> P;
const ll INF = 1LL << 60;
// const int MOD = 1000000007;
const ll MOD = 998244353;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }

struct mint {
  long long x; // typedef long long ll;
  mint(long long 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(long long t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

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

mint dp[202020];
mint dprui[202020];
int main() {
  ll n, k;
  cin >> n >> k;
  vector<pair<int, int>> h(k);
  rep(i, k) {
    int l, r;
    cin >> h[i].first >> h[i].second;
  }
  dp[1] = 1;
  dprui[1] = 1;
  for (int i = 2; i <= n; i++) {
    rep(j, k) {
      int li = i - h[j].second;
      int ri = i - h[j].first;
      if (ri < 0)
        continue;
      li = max(li, 1);
      dp[i] += dprui[ri] - dprui[li - 1];
    }
    dprui[i] = dprui[i - 1] + dp[i];
  }
  cout << dp[n] << endl;
  return 0;
}


#include <cstdio>
#include <iostream>
#include <set>
#include <vector>
using namespace std;

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

  vector<long long> slide;
  set<long long> T;

  for (long long i = 0; i < k; i++) {
    long long l, r;
    cin >> l >> r;

    for (long long j = l; j <= r; j++) {
      T.insert(j);
    }
  }

  set<long long>::iterator it;
  for (it = T.begin(); it != T.end(); it++)
    slide.push_back(*it);

  vector<long long> dp(n, 0);

  dp[0] = 1;
  for (long long i = 0; i < n; i++) {
    for (long long j = 0; j < slide.size(); j++) {
      if (i - slide[j] >= 0) {
        dp[i] += dp[i - slide[j]];
        dp[i] %= mod;
      }
    }
  }
  cout << dp[n - 1] << endl;
  return 0;
}

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

long long mod = 998244353;

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

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

  vector<long long> dp(n, 0);
  dp[0] = 1;
  dp[1] = -1;

  for (long long i = 0; i < n; i++) {
    if (i > 0)
      dp[i] += dp[i - 1];
    dp[i] %= mod;
    for (long long j = 0; j < k; j++) {
      if (i + l[j] < n) {
        dp[i + l[j]] += dp[i];
        dp[i + l[j]] %= mod;
      }

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

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


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

constexpr int mod = 998244353;

int calc(int n, const std::vector<int> &s, std::vector<int> &dp) {
  int result = 0;
  for (auto d : s) {
    if (n - d <= 0)
      break;
    if (dp[n - d] < 0) {
      dp[n - d] = calc(n - d, s, dp);
    }
    result += dp[n - d];
    result %= mod;
  }
  dp[n] = result;
  return result;
}

int solve(int n, int k, std::vector<int> &s) {
  sort(s.begin(), s.end());
  std::vector<int> dp(n + 1, -1);
  dp[1] = 1;
  return calc(n, s, dp);
}

int main() {
  int n, k;
  std::cin >> n >> k;
  std::vector<int> s;
  for (int i = 0; i < k; ++i) {
    int left, right;
    std::cin >> left >> right;
    for (int j = left; j <= right; ++j) {
      s.push_back(j);
    }
  }

  std::cout << std::setprecision(20);
  std::cout << solve(n, k, s) << std::endl;
}

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

constexpr int mod = 998244353;

std::vector<int> sums;

int calc(int n, const std::vector<std::pair<int, int>> &lrs,
         std::vector<int> &dp) {
  for (std::size_t i = 0; i < lrs.size(); ++i) {
    const auto &p = lrs[i];
    if (n - p.second - 1 > 0) {
      sums[i] -= dp[n - p.second - 1];
      if (sums[i] < 0)
        sums[i] += mod;
      sums[i] %= mod;
    }
    if (n - p.first > 0) {
      sums[i] += dp[n - p.first];
      sums[i] %= mod;
    }
  }

  int result = 0;
  for (std::size_t i = 0; i < lrs.size(); ++i) {
    result += sums[i];
    result %= mod;
  }
  dp[n] = result;
  return result;
}

int solve(int n, int k, std::vector<std::pair<int, int>> &lrs) {
  std::sort(lrs.begin(), lrs.end());

  sums = std::vector<int>(k);

  std::vector<int> dp(n + 1, -1);
  dp[1] = 1;
  for (int i = 2; i < n; ++i) {
    calc(i, lrs, dp);
  }
  return calc(n, lrs, dp);
}

int main() {
  int n, k;
  std::cin >> n >> k;
  std::vector<std::pair<int, int>> lrs(k);
  for (auto &p : lrs) {
    std::cin >> p.first >> p.second;
  }

  std::cout << std::setprecision(20);
  std::cout << solve(n, k, lrs) << std::endl;
}


#include <algorithm>
#include <cmath>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
#define ll long long
#define pb push_back
#define pp pair<long long, long long>
#define ppp pair<long long, pair<long long, long long>>
#define f first
#define s second
#define pd pair<double, long long>
ll barr[200100], M = 998244353;
void solveTestCase() {
  ll n, i, j, k, l;
  cin >> n >> k;
  vector<pp> arr(k + 1);
  for (i = 1; i <= k; i++)
    cin >> arr[i].f >> arr[i].s;
  barr[1] = 1;
  barr[2] = -1;
  for (i = 1; i <= n; i++) {
    barr[i] += barr[i - 1];
    barr[i] %= M;
    if (!barr[i])
      continue;
    for (j = 1; j <= k; j++) {
      barr[i + arr[j].f] += barr[i];
      barr[i + arr[j].f] %= M;
      barr[i + arr[j].s + 1] += (M - barr[i]);
      barr[i + arr[j].s + 1] %= M;
    }
  }
  cout << barr[n] << '\\n';
}
int main() {
  ll t, n, i, j, k, l, m;
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  ll p;
  t = 1;
  // cin>>t;
  for (ll T = 1; T <= t; T++) {
    solveTestCase();
  }
  return 0;
}

#include <algorithm>
#include <cmath>
#include <cstring>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
#define ll long long
#define pb push_back
#define pp pair<long long, long long>
#define ppp pair<long long, pair<long long, long long>>
#define f first
#define s second
#define pd pair<double, long long>
ll barr[200100], M = 998244353;
void solveTestCase() {
  ll n, i, j, k, l;
  cin >> n >> k;
  vector<pp> arr(k + 1);
  for (i = 1; i <= k; i++)
    cin >> arr[i].f >> arr[i].s;
  barr[1] = 1;
  barr[2] = -1;
  for (i = 1; i <= n; i++) {
    barr[i] += barr[i - 1];
    barr[i] %= M;
    if (!barr[i])
      continue;
    for (j = 1; j <= k; j++) {
      if (i + arr[j].f <= n) {
        barr[i + arr[j].f] += barr[i];
        barr[i + arr[j].f] %= M;
      }
      if (i + arr[j].s + 1 <= n) {
        barr[i + arr[j].s + 1] += (M - barr[i]);
        barr[i + arr[j].s + 1] %= M;
      }
    }
  }
  cout << barr[n] << '\\n';
}
int main() {
  ll t, n, i, j, k, l, m;
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  ll p;
  t = 1;
  // cin>>t;
  for (ll T = 1; T <= t; T++) {
    solveTestCase();
  }
  return 0;
}


#include <bits/stdc++.h>
// #include <set>
// #include <vector>
// #include <ostream>
// #include <atcoder/notall>

using namespace std;
using ll = long long;
using VI = vector<int>;
using VL = vector<ll>;
using VD = vector<double>;
using VS = vector<string>;
using VB = vector<bool>;
using VVB = vector<vector<bool>>;
using VVI = vector<VI>;
using VVL = vector<VL>;
using VVD = vector<VD>;
using PII = std::pair<int, int>;
using VPII = std::vector<std::pair<int, int>>;
using PLL = std::pair<ll, ll>;
using VPLL = std::vector<std::pair<ll, ll>>;
using TI3 = std::tuple<int, int, int>;
using TI4 = std::tuple<int, int, int, int>;
using TL3 = std::tuple<ll, ll, ll>;
using TL4 = std::tuple<ll, ll, ll, ll>;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define repr(i, n) for (int i = (int)(n)-1; i >= 0; i--)
#define rep2(i, s, n) for (int i = (s); i < (int)(n); i++)
#define rep3(i, s, n, d) for (int i = (s); i < (int)(n); i += (d))
#define allpt(v) (v).begin(), (v).end()
#define allpt_c(v) (v).cbegin(), (v).cend()
#define allpt_r(v) (v).rbegin(), (v).rend()
#define allpt_cr(v) (v).crbegin(), (v).crend()

const int mod1 = 1e9 + 7, mod2 = 998244353, mod3 = 1e9 + 9;
const int mod = mod2;
const ll inf = 1e18;

const string wsp = " ";
const string tb = "\\t";
const string rt = "\\n";
const string alphabets = "abcdefghijklmnopqrstuvwxyz";

template <typename T> void show1dvec(const vector<T> &v) {
  if (v.size() == 0)
    return;
  int n = v.size() - 1;
  rep(i, n) cout << v[i] << wsp;
  cout << v[n] << rt;
  return;
}

template <typename T> void show2dvec(const vector<vector<T>> &v) {
  int n = v.size();
  rep(i, n) show1dvec(v[i]);
}

template <typename T> void range_sort(vector<T> &arr, int l, int r) {
  sort(arr.begin() + l, arr.begin() + r);
}

template <typename T, typename S> void show1dpair(const vector<pair<T, S>> &v) {
  int n = v.size();
  rep(i, n) cout << v[i].first << wsp << v[i].second << rt;
  return;
}

template <typename T, typename S>
void pairzip(const vector<pair<T, S>> &v, vector<T> &t, vector<T> &s) {
  int n = v.size();
  rep(i, n) {
    t.push_back(v[i].first);
    s.push_back(v[i].second);
  }
  return;
}

template <typename T> void maxvec(vector<T> &v) {
  T s = v[0];
  int n = v.size();
  rep(i, n - 1) {
    if (s > v[i + 1]) {
      v[i + 1] = s;
    }
    s = v[i + 1];
  }
}

template <typename T, typename S> bool myfind(T t, S s) {
  return find(t.cbegin(), t.cend(), s) != t.cend();
}

bool check(int y, int x, int h, int w) {
  return 0 <= y && y < h && 0 <= x && x < w;
}

bool iskadomatsu(int a, int b, int c) {
  return (a != b && b != c && c != a) && ((a > b && b < c) || (a < b && b > c));
}

double euc_dist(PII a, PII b) {
  return sqrt(pow(a.first - b.first, 2) + pow(a.second - b.second, 2));
}

VS split(string s, char c) {
  VS ret;
  string part;
  s += c;
  rep(i, s.length()) {
    if (s[i] == c) {
      if (part != "")
        ret.emplace_back(part);
      part = "";
    } else if (s[i] != c) {
      part += s[i];
    }
  }
  return ret;
}

template <typename T, typename S, typename R>
ll pow_mod(T p, S q, R mod = 1ll) {
  ll ret = 1, r = p;
  while (q) {
    if (q % 2)
      ret *= r, ret %= mod;
    r = (r * r) % mod, q /= 2;
  }
  return ret % mod;
}

template <typename T, typename S> ll pow_no_mod(T p, S q) {
  ll ret = 1, r = p;
  while (q) {
    if (q % 2)
      ret *= r;
    r = (r * r), q /= 2;
  }
  return ret;
}

void make_frac_tables(VL &frac_list, VL &frac_inv_list) {
  rep(i, frac_list.size() - 1) {
    frac_list[i + 1] *= frac_list[i] * (i + 1);
    frac_list[i + 1] %= mod;
    frac_inv_list[i + 1] *= frac_inv_list[i] * pow_mod(i + 1, mod - 2, mod);
    frac_inv_list[i + 1] %= mod;
  }
}

pair<VL, VL> make_frac_tables(int n) {
  VL frac_list(n + 1, 1), frac_inv_list(n + 1, 1);
  rep(i, n) {
    frac_list[i + 1] *= frac_list[i] * (i + 1);
    frac_list[i + 1] %= mod;
    frac_inv_list[i + 1] *= frac_inv_list[i] * pow_mod(i + 1, mod - 2, mod);
    frac_inv_list[i + 1] %= mod;
  }
  return make_pair(frac_list, frac_inv_list);
}

ll comb(int a, int b, const VL &frac_list, const VL &frac_inv_list) {
  if (a < b)
    return 0;
  if (b < 0)
    return 0;
  ll ret = frac_list[a];
  ret *= frac_inv_list[b];
  ret %= mod;
  ret *= frac_inv_list[a - b];
  ret %= mod;
  return ret;
}

struct vec2d {
  ll x;
  ll y;
  vec2d(ll _x, ll _y) {
    x = _x;
    y = _y;
  }
  ll dot(vec2d p) { return x * p.x + y * p.y; }
  vec2d diff(vec2d p) { return vec2d(x - p.x, y - p.y); }
};

// void djkstra(int n, vector<vec2d> point_list, const VVL cost_list,
//              const VVI &connect) {
//     const ll llm = 1e18;
//     VVL min_cost(n, VL(n, llm));
//     min_cost[0][0] = 0;

//     vector<PII> search = {make_pair(0, 0)};
//     vector<PII> new_search;
//     while (!search.empty()) {
//         for (auto [p, q] : search) {
//             for (auto r : connect[p]) {
//                 if (point_list[r]
//                             .diff(point_list[p])
//                             .dot(point_list[q].diff(point_list[p])) <= 0 &&
//                     min_cost[r][p] > cost_list[r][p] + min_cost[p][q]) {
//                     min_cost[r][p] = cost_list[r][p] + min_cost[p][q];
//                     new_search.emplace_back(make_pair(r, p));
//                 }
//             }
//         }
//         search.clear();
//         search = new_search;
//         new_search.clear();
//         // show1dvec(search);
//         // show1dvec(shortest);
//     }
//     auto ans = *min_element(allpt_c(min_cost[1]));
//     cout << ((ans == llm) ? -1 : ans) << rt;
//     // show2dvec(min_cost);
// }

struct node {
  int parent = -1;
  ll weight = 0;
  int depth = 0;
  int subtree = 0;
  VPII children;
  VPII connect;
  node(int n) {
    parent = -1;
    weight = 0;
    depth = 0;
    subtree = 0;
    children;
    connect;
  }
};

struct graph {
  int _n;
  int root = 0;
  vector<node> nodes;
  graph(int n) {
    _n = n;
    rep(i, _n) nodes.emplace_back(node(_n));
  }
  void showparent() {
    rep(i, _n - 1) cout << nodes[i].parent << wsp;
    cout << nodes[_n - 1].parent << rt;
  }
  void showweight() {
    rep(i, _n - 1) cout << nodes[i].weight << wsp;
    cout << nodes[_n - 1].weight << rt;
  }
  void showsubtree() {
    rep(i, _n - 1) cout << nodes[i].subtree << wsp;
    cout << nodes[_n - 1].subtree << rt;
  }
  void showdepth() {
    rep(i, _n - 1) cout << nodes[i].depth << wsp;
    cout << nodes[_n - 1].depth << rt;
  }
};

struct point {
  int x;
  int y;
  point() {
    x = 0;
    y = 0;
  }
  point(int _x, int _y) {
    x = _x;
    y = _y;
  }
  void pointinput() {
    int _x, _y;
    cin >> _x >> _y;
    x = _x;
    y = _y;
  }
  void pointinv() { swap(x, y); }
};

double pointseuc(point a, point b) {
  return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}

double dist_segment_point(TL3 segment, point p) {
  double a = get<0>(segment);
  double b = get<1>(segment);
  double c = get<2>(segment);
  return abs(a * p.x + b * p.y - c) / (a * a + b * b + c * c);
}

TL3 segment_parameter(point p, point q) {
  ll a, b, c;
  a = q.y - p.y;
  b = p.x - q.x;
  c = a * p.x + b * p.y;
  TL3 ret = (TL3){a, b, c};
  // cout << a << b << c << rt;
  return ret;
}

int cross_check(TL3 segment, point p) {
  ll a = get<0>(segment);
  ll b = get<1>(segment);
  ll c = get<2>(segment);

  auto f = a * p.x + b * p.y - c;
  int ret;
  if (f > 0)
    ret = 1;
  if (f == 0)
    ret = 0;
  if (f < 0)
    ret = -1;
  return ret;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  // リアクティブ問題のときはコメントアウト

#ifdef DEBUG
  cout << "DEBUG MODE" << endl;
  ifstream in("input.txt"); // for debug
  cin.rdbuf(in.rdbuf());    // for debug
#endif

  int n, k, l, r;
  cin >> n >> k;
  VI move_list;
  rep(i, k) {
    cin >> l >> r;
    rep2(j, l, r + 1) { move_list.emplace_back(j); }
  }
  sort(allpt(move_list));
  // show1dvec(move_list);
  VL dp(n, 0);
  dp[0] = 1;

  rep(i, n) {
    for (auto p : move_list) {
      if (i + p < n) {
        dp[i + p] += dp[i];
        dp[i + p] %= mod;
      } else {
        break;
      }
    }
  }
  cout << dp[n - 1] << rt;
  // show1dvec(dp);

  // ll n, x, m;
  // cin >> n >> x >> m;
  // ll a = x;
  // VL a_list;
  // const int d = 2e5;
  // rep(i, 5e5) {
  //     a_list.emplace_back(a);
  //     a = (a * a) % m;
  //     if (a ==  a_list[100001]){
  //         cout << i << rt;
  //     }
  // }
  // // cout << a_list[900000] << rt;

  return 0;
}

#include <bits/stdc++.h>
// #include <set>
// #include <vector>
// #include <ostream>
// #include <atcoder/notall>

using namespace std;
using ll = long long;
using VI = vector<int>;
using VL = vector<ll>;
using VD = vector<double>;
using VS = vector<string>;
using VB = vector<bool>;
using VVB = vector<vector<bool>>;
using VVI = vector<VI>;
using VVL = vector<VL>;
using VVD = vector<VD>;
using PII = std::pair<int, int>;
using VPII = std::vector<std::pair<int, int>>;
using PLL = std::pair<ll, ll>;
using VPLL = std::vector<std::pair<ll, ll>>;
using TI3 = std::tuple<int, int, int>;
using TI4 = std::tuple<int, int, int, int>;
using TL3 = std::tuple<ll, ll, ll>;
using TL4 = std::tuple<ll, ll, ll, ll>;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define repr(i, n) for (int i = (int)(n)-1; i >= 0; i--)
#define rep2(i, s, n) for (int i = (s); i < (int)(n); i++)
#define rep3(i, s, n, d) for (int i = (s); i < (int)(n); i += (d))
#define allpt(v) (v).begin(), (v).end()
#define allpt_c(v) (v).cbegin(), (v).cend()
#define allpt_r(v) (v).rbegin(), (v).rend()
#define allpt_cr(v) (v).crbegin(), (v).crend()

const int mod1 = 1e9 + 7, mod2 = 998244353, mod3 = 1e9 + 9;
const int mod = mod2;
const ll inf = 1e18;

const string wsp = " ";
const string tb = "\\t";
const string rt = "\\n";
const string alphabets = "abcdefghijklmnopqrstuvwxyz";

template <typename T> void show1dvec(const vector<T> &v) {
  if (v.size() == 0)
    return;
  int n = v.size() - 1;
  rep(i, n) cout << v[i] << wsp;
  cout << v[n] << rt;
  return;
}

template <typename T> void show2dvec(const vector<vector<T>> &v) {
  int n = v.size();
  rep(i, n) show1dvec(v[i]);
}

template <typename T> void range_sort(vector<T> &arr, int l, int r) {
  sort(arr.begin() + l, arr.begin() + r);
}

template <typename T, typename S> void show1dpair(const vector<pair<T, S>> &v) {
  int n = v.size();
  rep(i, n) cout << v[i].first << wsp << v[i].second << rt;
  return;
}

template <typename T, typename S>
void pairzip(const vector<pair<T, S>> &v, vector<T> &t, vector<T> &s) {
  int n = v.size();
  rep(i, n) {
    t.push_back(v[i].first);
    s.push_back(v[i].second);
  }
  return;
}

template <typename T> void maxvec(vector<T> &v) {
  T s = v[0];
  int n = v.size();
  rep(i, n - 1) {
    if (s > v[i + 1]) {
      v[i + 1] = s;
    }
    s = v[i + 1];
  }
}

template <typename T, typename S> bool myfind(T t, S s) {
  return find(t.cbegin(), t.cend(), s) != t.cend();
}

bool check(int y, int x, int h, int w) {
  return 0 <= y && y < h && 0 <= x && x < w;
}

bool iskadomatsu(int a, int b, int c) {
  return (a != b && b != c && c != a) && ((a > b && b < c) || (a < b && b > c));
}

double euc_dist(PII a, PII b) {
  return sqrt(pow(a.first - b.first, 2) + pow(a.second - b.second, 2));
}

VS split(string s, char c) {
  VS ret;
  string part;
  s += c;
  rep(i, s.length()) {
    if (s[i] == c) {
      if (part != "")
        ret.emplace_back(part);
      part = "";
    } else if (s[i] != c) {
      part += s[i];
    }
  }
  return ret;
}

template <typename T, typename S, typename R>
ll pow_mod(T p, S q, R mod = 1ll) {
  ll ret = 1, r = p;
  while (q) {
    if (q % 2)
      ret *= r, ret %= mod;
    r = (r * r) % mod, q /= 2;
  }
  return ret % mod;
}

template <typename T, typename S> ll pow_no_mod(T p, S q) {
  ll ret = 1, r = p;
  while (q) {
    if (q % 2)
      ret *= r;
    r = (r * r), q /= 2;
  }
  return ret;
}

void make_frac_tables(VL &frac_list, VL &frac_inv_list) {
  rep(i, frac_list.size() - 1) {
    frac_list[i + 1] *= frac_list[i] * (i + 1);
    frac_list[i + 1] %= mod;
    frac_inv_list[i + 1] *= frac_inv_list[i] * pow_mod(i + 1, mod - 2, mod);
    frac_inv_list[i + 1] %= mod;
  }
}

pair<VL, VL> make_frac_tables(int n) {
  VL frac_list(n + 1, 1), frac_inv_list(n + 1, 1);
  rep(i, n) {
    frac_list[i + 1] *= frac_list[i] * (i + 1);
    frac_list[i + 1] %= mod;
    frac_inv_list[i + 1] *= frac_inv_list[i] * pow_mod(i + 1, mod - 2, mod);
    frac_inv_list[i + 1] %= mod;
  }
  return make_pair(frac_list, frac_inv_list);
}

ll comb(int a, int b, const VL &frac_list, const VL &frac_inv_list) {
  if (a < b)
    return 0;
  if (b < 0)
    return 0;
  ll ret = frac_list[a];
  ret *= frac_inv_list[b];
  ret %= mod;
  ret *= frac_inv_list[a - b];
  ret %= mod;
  return ret;
}

struct vec2d {
  ll x;
  ll y;
  vec2d(ll _x, ll _y) {
    x = _x;
    y = _y;
  }
  ll dot(vec2d p) { return x * p.x + y * p.y; }
  vec2d diff(vec2d p) { return vec2d(x - p.x, y - p.y); }
};

// void djkstra(int n, vector<vec2d> point_list, const VVL cost_list,
//              const VVI &connect) {
//     const ll llm = 1e18;
//     VVL min_cost(n, VL(n, llm));
//     min_cost[0][0] = 0;

//     vector<PII> search = {make_pair(0, 0)};
//     vector<PII> new_search;
//     while (!search.empty()) {
//         for (auto [p, q] : search) {
//             for (auto r : connect[p]) {
//                 if (point_list[r]
//                             .diff(point_list[p])
//                             .dot(point_list[q].diff(point_list[p])) <= 0 &&
//                     min_cost[r][p] > cost_list[r][p] + min_cost[p][q]) {
//                     min_cost[r][p] = cost_list[r][p] + min_cost[p][q];
//                     new_search.emplace_back(make_pair(r, p));
//                 }
//             }
//         }
//         search.clear();
//         search = new_search;
//         new_search.clear();
//         // show1dvec(search);
//         // show1dvec(shortest);
//     }
//     auto ans = *min_element(allpt_c(min_cost[1]));
//     cout << ((ans == llm) ? -1 : ans) << rt;
//     // show2dvec(min_cost);
// }

struct node {
  int parent = -1;
  ll weight = 0;
  int depth = 0;
  int subtree = 0;
  VPII children;
  VPII connect;
  node(int n) {
    parent = -1;
    weight = 0;
    depth = 0;
    subtree = 0;
    children;
    connect;
  }
};

struct graph {
  int _n;
  int root = 0;
  vector<node> nodes;
  graph(int n) {
    _n = n;
    rep(i, _n) nodes.emplace_back(node(_n));
  }
  void showparent() {
    rep(i, _n - 1) cout << nodes[i].parent << wsp;
    cout << nodes[_n - 1].parent << rt;
  }
  void showweight() {
    rep(i, _n - 1) cout << nodes[i].weight << wsp;
    cout << nodes[_n - 1].weight << rt;
  }
  void showsubtree() {
    rep(i, _n - 1) cout << nodes[i].subtree << wsp;
    cout << nodes[_n - 1].subtree << rt;
  }
  void showdepth() {
    rep(i, _n - 1) cout << nodes[i].depth << wsp;
    cout << nodes[_n - 1].depth << rt;
  }
};

struct point {
  int x;
  int y;
  point() {
    x = 0;
    y = 0;
  }
  point(int _x, int _y) {
    x = _x;
    y = _y;
  }
  void pointinput() {
    int _x, _y;
    cin >> _x >> _y;
    x = _x;
    y = _y;
  }
  void pointinv() { swap(x, y); }
};

double pointseuc(point a, point b) {
  return sqrt(pow(a.x - b.x, 2) + pow(a.y - b.y, 2));
}

double dist_segment_point(TL3 segment, point p) {
  double a = get<0>(segment);
  double b = get<1>(segment);
  double c = get<2>(segment);
  return abs(a * p.x + b * p.y - c) / (a * a + b * b + c * c);
}

TL3 segment_parameter(point p, point q) {
  ll a, b, c;
  a = q.y - p.y;
  b = p.x - q.x;
  c = a * p.x + b * p.y;
  TL3 ret = (TL3){a, b, c};
  // cout << a << b << c << rt;
  return ret;
}

int cross_check(TL3 segment, point p) {
  ll a = get<0>(segment);
  ll b = get<1>(segment);
  ll c = get<2>(segment);

  auto f = a * p.x + b * p.y - c;
  int ret;
  if (f > 0)
    ret = 1;
  if (f == 0)
    ret = 0;
  if (f < 0)
    ret = -1;
  return ret;
}

template <typename T>
class RangeMinorMaxorSumQuery // 0-index
{
  int const intmax = 2147483647;
  int const intmin = 0;
  vector<T> sgt;
  int n;
  int k;

public:
  RangeMinorMaxorSumQuery(int n1, int f = -1) {
    if (f == -1)
      f = intmax;
    else if (f == 0)
      f = intmin;
    int na = 1;
    int ka = 0;
    while (na < n1) {
      na *= 2;
      ka++;
    }
    for (int i = 0; i < 2 * na; i++)
      sgt.push_back(f);
    n = na;
    k = ka;
  }

  void add_sum(int i, T x) {
    i += n;
    sgt[i] += x;
    sgt[i] %= mod;
    while (i > 1) {
      i /= 2;
      sgt[i] = sgt[2 * i] + sgt[2 * i + 1];
      sgt[i] %= mod;
    }
  }

  T getsum(int a, int b, int k = 1, int l = 0,
           int r = -1) // 閉区間 l <= x < r とする
  {
    if (r == -1)
      r = n;
    if (r <= a || b <= l)
      return intmin;
    if (a == l && b == r)
      return sgt[k];
    else
      return (getsum(a, min(b, (l + r) / 2), 2 * k, l, (l + r) / 2) +
              getsum(max(a, (l + r) / 2), b, 2 * k + 1, (l + r) / 2, r)) %= mod;
  }

  T operator[](int i) { return sgt[i + n]; }

  void printsegtree() {
    for (int i = 0; i < 2 * n; i++) {
      cout << sgt[i] << " ";
    }
    cout << endl;
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  // リアクティブ問題のときはコメントアウト

#ifdef DEBUG
  cout << "DEBUG MODE" << endl;
  ifstream in("input.txt"); // for debug
  cin.rdbuf(in.rdbuf());    // for debug
#endif

  int n, k, l, r;
  cin >> n >> k;
  VL dp(3 * n, 0), cum_dp(3 * n, 0);
  VPII move_list;
  rep(_, k) {
    cin >> l >> r;
    move_list.emplace_back(make_pair(l, r + 1));
  }
  dp[0] = 1;
  rep(i, n) {
    // cout << dp[i] << rt;
    for (auto [l, r] : move_list) {
      cum_dp[i + l] += dp[i];
      cum_dp[i + l] %= mod;
      cum_dp[i + r] -= dp[i];
      cum_dp[i + r] += mod;
      cum_dp[i + r] %= mod;
    }
    cum_dp[i + 1] += cum_dp[i];
    cum_dp[i + 1] %= mod;
    dp[i + 1] = cum_dp[i + 1];
    // show1dvec(cum_dp);
    // show1dvec(dp);
  }

  cout << dp[n - 1] << rt;
  // show1dvec(dp);

  // ll n, x, m;
  // cin >> n >> x >> m;
  // ll a = x;
  // VL a_list;
  // const int d = 2e5;
  // rep(i, 5e5) {
  //     a_list.emplace_back(a);
  //     a = (a * a) % m;
  //     if (a ==  a_list[100001]){
  //         cout << i << rt;
  //     }
  // }
  // // cout << a_list[900000] << rt;

  return 0;
}


#include <bits/stdc++.h>
// clang-format off
using namespace std; using ll = int64_t; using ull = uint64_t; const ll INF = 9e18;
void print() { cout << endl; }
template<typename Head,typename... Tail> void print(Head head,Tail... tail){cout<<head;if(sizeof...(Tail)>0)cout<<" ";print(tail...);}
void print0() {}
template<typename Head,typename... Tail> void print0(Head head,Tail... tail){cout<<head;print0(tail...);}
// clang-format on

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

  vector<ll> dp(200003, 0);
  vector<ll> exist(200003, 0);
  vector<ll> moves;
  for (ll i = 0; i < K; i++) {
    ll l, r;
    cin >> l >> r;
    for (ll j = l; j <= r; j++) {
      // exist[j] = 1;
      moves.push_back(j);
    }
  }
  sort(moves.begin(), moves.end());

  dp[1] = 1;
  for (ll i = 1; i <= N; i++) {
    for (auto j : moves) {
      if (i + j > N) {
        break;
      }
      dp[i + j] = (dp[i + j] + dp[i]) % 998244353;
    }
  }
  print(dp[N]);
}

#include <bits/stdc++.h>
// clang-format off
using namespace std; using ll = int64_t; using ull = uint64_t; const ll INF = 9e18;
void print() { cout << endl; }
template<typename Head,typename... Tail> void print(Head head,Tail... tail){cout<<head;if(sizeof...(Tail)>0)cout<<" ";print(tail...);}
void print0() {}
template<typename Head,typename... Tail> void print0(Head head,Tail... tail){cout<<head;print0(tail...);}
// clang-format on

const ll MODULO = 998244353L;
ll mod_minus(ll x, ll modval) {
  if (x >= 0) {
    return x % modval;
  } else {
    ll mm = ((-x) % modval);
    if (mm == 0) {
      return 0;
    } else {
      return modval - mm;
    }
  }
}
ll mod(ll x) { return mod_minus(x, MODULO); }

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

  vector<ll> dp(200003, 0);
  vector<ll> left(K);
  vector<ll> right(K);
  vector<ll> exist(200003, 0);
  for (ll i = 0; i < K; i++) {
    cin >> left[i] >> right[i];
    for (ll j = left[i]; j <= right[i]; j++) {
      exist[j] = 1;
    }
  }

  for (ll i = 2; i <= N; i++) {
    dp[i] = dp[i - 1] - exist[i - 2] + exist[i - 1];
    for (ll j = 0; j < K; j++) {
      ll l = left[j];
      ll r = right[j];
      if (i - r - 1 >= 1) {
        dp[i] = mod(dp[i] - dp[i - r - 1]);
      }
      if (i - l >= 1) {
        dp[i] = mod(dp[i] + dp[i - l]);
      }
    }
  }
  print(dp[N]);
}


#define IO                                                                     \\
  ios::sync_with_stdio(false);                                                 \\
  cin.tie();                                                                   \\
  cout.tie(0)
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 200010;
const ll MOD = 998244353;
int n, k;
ll dp[N];
struct node {
  int l, r;
} a[N];
int main() {
  IO;
  cin >> n >> k;
  int minpos = 1e9;
  for (int i = 1; i <= k; i++) {
    cin >> a[i].l >> a[i].r;
    minpos = min(minpos, a[i].l);
  }
  dp[1] = 1;
  for (int i = 2; i <= minpos; i++)
    dp[i] = 0;
  for (int i = 1 + minpos; i <= n; i++) {
    for (int j = 1; j <= k; j++) {
      for (int m = a[j].l; m <= a[j].r; m++) {
        dp[i] = (dp[i] + dp[max(i - m, 0)]) % MOD;
      }
    }
  }
  cout << (dp[n] + MOD) % MOD << '\\n';
  return 0;
}

// O(nk)
#define IO                                                                     \\
  ios::sync_with_stdio(false);                                                 \\
  cin.tie();                                                                   \\
  cout.tie(0)
#pragma GCC optimize(2)
#include <algorithm>
#include <iostream>
#define l first
#define r second
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 200010;
const ll mod = 998244353;
int n, k;
ll f[N], s[N];
pii a[N];
int main() {
  IO;
  int minpos = 1e9;
  cin >> n >> k;
  for (int i = 1; i <= n; i++) {
    cin >> a[i].l >> a[i].r;
    minpos = min(minpos, a[i].l);
  }
  f[1] = 1;
  s[1] = 1;
  for (int i = 1 + minpos; i <= n; i++) {
    for (int j = 1; j <= k; j++)
      f[i] = (f[i] + s[max(0, i - a[j].l)] - s[max(0, i - a[j].r - 1)]) % mod;
    ;
    s[i] = (s[i - 1] + f[i]) % mod;
  }
  cout << (f[n] + mod) % mod << '\\n';
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
#define MOD 998244353
#define mod9 1000000009
#define fast                                                                   \\
  ios_base ::sync_with_stdio(0);                                               \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define mp make_pair
#define pb push_back
#define ct                                                                     \\
  ll t;                                                                        \\
  cin >> t;                                                                    \\
  while (t--)
#define bi begin()
#define ei end()
#define fi first
#define se second
#define foe(i, a, b) for (ll i = a; i < b; i++)
#define rfoe(i, a, b) for (ll i = a; i >= 0; i--)
#define sz(s) s.size()
#define mem(a, s) memset(a, s, sizeof(a))
#define all(v) v.bi, v.ei
#define MAX 8000000000000000064LL
#define MIN -8000000000000000064LL

typedef pair<ll, ll> pii;

ll add(ll a, ll b) { return (a % MOD + b % MOD + ((MAX) / MOD) * MOD) % MOD; }
ll sub(ll a, ll b) { return (a % MOD - b % MOD + ((MAX) / MOD) * MOD) % MOD; }
ll mul(ll a, ll b) {
  return ((a % MOD) * (b % MOD) + ((MAX) / MOD) * MOD) % MOD;
}
ll lcm(ll a, ll b) { return (a * b) / __gcd(a, b); }
ll fact[1000007] = {0};
ll expo(ll x, ll y) {
  ll res = 1;
  x = x % MOD;
  while (y > 0) {
    if (y & 1)
      res = (1ll * res * x) % MOD;
    y = y >> 1;
    x = (1ll * x * x) % MOD;
  }
  return res;
}
void facto() {
  fact[0] = 1;
  fact[1] = 1;
  for (ll i = 2; i < 1000007; i++)
    fact[i] = (fact[i - 1] * i) % MOD;
}
ll ncr(ll n, ll r) {
  ll res = 1;
  res = fact[n];
  res = (res * (expo(fact[r], MOD - 2))) % MOD;
  res = (res * (expo(fact[n - r], MOD - 2))) % MOD;
  return res;
}
ll npr(ll n, ll r) {
  facto();
  ll res = 1;
  res = fact[n];
  res = (res * (expo(fact[n - r], MOD - 2))) % MOD;
  return res;
}
int const N = 2e5 + 9;
ll const INF = 2e18 + 5;
ll dx[8] = {0, 0, 1, -1, 1, 1, -1, -1};
ll dy[8] = {1, -1, 0, 0, -1, 1, -1, 1};
long long binpow(long long a, long long b) {
  long long res = 1;
  while (b > 0) {
    if (b & 1)
      res = mul(res, a);
    a = mul(a, a);
    b >>= 1;
  }
  return res;
}

void solve() {
  ll n, k;
  cin >> n >> k;
  vector<ll> v;
  foe(i, 0, k) {
    ll l, r;
    cin >> l >> r;
    foe(i, l, r + 1) { v.pb(i); }
  }
  sort(all(v));
  ll dp[n + 1];
  mem(dp, 0);
  dp[0] = 1;
  foe(i, 1, n) {
    for (auto x : v) {
      if ((i - x) >= 0) {
        dp[i] = add(dp[i], dp[i - x]);
      } else {
        break;
      }
    }
  }
  cout << dp[n - 1] << " ";
}
int main() {
  fast
  // facto();
  // Sieve();
  //    ct
  {
    solve();
  }
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
#define MOD 998244353
#define mod9 1000000009
#define fast                                                                   \\
  ios_base ::sync_with_stdio(0);                                               \\
  cin.tie(NULL);                                                               \\
  cout.tie(NULL);
#define mp make_pair
#define pb push_back
#define ct                                                                     \\
  ll t;                                                                        \\
  cin >> t;                                                                    \\
  while (t--)
#define bi begin()
#define ei end()
#define fi first
#define se second
#define foe(i, a, b) for (ll i = a; i < b; i++)
#define rfoe(i, a, b) for (ll i = a; i >= 0; i--)
#define sz(s) s.size()
#define mem(a, s) memset(a, s, sizeof(a))
#define all(v) v.bi, v.ei
#define MAX 8000000000000000064LL
#define MIN -8000000000000000064LL

typedef pair<ll, ll> pii;

ll add(ll a, ll b) { return (a % MOD + b % MOD + ((MAX) / MOD) * MOD) % MOD; }
ll sub(ll a, ll b) { return (a % MOD - b % MOD + ((MAX) / MOD) * MOD) % MOD; }
ll mul(ll a, ll b) {
  return ((a % MOD) * (b % MOD) + ((MAX) / MOD) * MOD) % MOD;
}
ll lcm(ll a, ll b) { return (a * b) / __gcd(a, b); }
ll fact[1000007] = {0};
ll expo(ll x, ll y) {
  ll res = 1;
  x = x % MOD;
  while (y > 0) {
    if (y & 1)
      res = (1ll * res * x) % MOD;
    y = y >> 1;
    x = (1ll * x * x) % MOD;
  }
  return res;
}
void facto() {
  fact[0] = 1;
  fact[1] = 1;
  for (ll i = 2; i < 1000007; i++)
    fact[i] = (fact[i - 1] * i) % MOD;
}
ll ncr(ll n, ll r) {
  ll res = 1;
  res = fact[n];
  res = (res * (expo(fact[r], MOD - 2))) % MOD;
  res = (res * (expo(fact[n - r], MOD - 2))) % MOD;
  return res;
}
ll npr(ll n, ll r) {
  facto();
  ll res = 1;
  res = fact[n];
  res = (res * (expo(fact[n - r], MOD - 2))) % MOD;
  return res;
}
int const N = 2e5 + 9;
ll const INF = 2e18 + 5;
ll dx[8] = {0, 0, 1, -1, 1, 1, -1, -1};
ll dy[8] = {1, -1, 0, 0, -1, 1, -1, 1};
long long binpow(long long a, long long b) {
  long long res = 1;
  while (b > 0) {
    if (b & 1)
      res = mul(res, a);
    a = mul(a, a);
    b >>= 1;
  }
  return res;
}

void solve() {
  ll n, k;
  cin >> n >> k;
  vector<ll> v;
  ll l[k], r[k];
  foe(i, 0, k) { cin >> l[i] >> r[i]; }
  sort(all(v));
  ll dp[n + 1];
  mem(dp, 0);
  dp[0] = 0;
  dp[1] = 1;
  foe(i, 2, n + 1) {
    foe(j, 0, k) {
      if ((i - l[j]) >= 1) {
        dp[i] = add(dp[i], dp[i - l[j]]);
        //    if(l[j]==r[j])continue;
        dp[i] = sub(dp[i], dp[max(0LL, i - r[j] - 1)]);
      }
    }
    //    cout<<dp[i]<<" ";
    if (i == n) {
      cout << dp[n] << " ";
      return;
    }
    dp[i] = add(dp[i], dp[i - 1]);
  }
}
int main() {
  fast
  // facto();
  // Sieve();
  //    ct
  {
    solve();
  }
}


#include <bits/stdc++.h>

using namespace std;

int main() {

  int n, k;
  cin >> n >> k;
  int mod = 998244353;
  vector<pair<int, int>> steps;
  for (int i = 0; i < k; i++) {
    int x, y;
    cin >> x >> y;
    steps.push_back({x, y});
  }

  sort(steps.begin(), steps.end());
  vector<int> dp(n);
  dp[0] = 1;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      int l = i - steps[j].second;
      int r = i - steps[j].first;
      if (r >= 0) {
        dp[i] = (dp[i] + dp[r]) % mod;
      }
      if (l > 0) {
        dp[i] = (dp[i] - dp[l - 1] + mod) % mod;
      }
    }

    if (i != n - 1) {
      dp[i] = (dp[i] + dp[i - 1]) % mod;
    }
  }

  cout << dp[n - 1];

  return 0;
}

#include <bits/stdc++.h>

using namespace std;

int main() {

  int n, k;
  cin >> n >> k;
  int mod = 998244353;
  vector<pair<int, int>> steps;
  for (int i = 0; i < k; i++) {
    int x, y;
    cin >> x >> y;
    steps.push_back({x, y});
  }

  sort(steps.begin(), steps.end());
  vector<int> dp(n);
  dp[0] = 1;
  for (int i = 1; i < n; i++) {
    for (int j = 0; j < k; j++) {
      int l = i - steps[j].second;
      int r = i - steps[j].first;
      if (r >= 0) {
        dp[i] = (dp[i] + dp[r]) % mod;
      }
      if (l > 0) {
        dp[i] = (dp[i] - dp[l - 1] + mod) % mod;
      }
    }

    if (i != n - 1) {
      dp[i] = (dp[i] + dp[i - 1]) % mod;
    }
  }

  cout << dp[n - 1];

  return 0;
}


#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <bitset>    // bitset
#include <cctype>    // isupper, islower, isdigit, toupper, tolower
#include <cmath>     //sqrt pow
#include <cstdint>   // int64_t, int*_t
#include <cstdio>    // printf
#include <deque>     // dequef
#include <iostream>  // cout, endl, cin
#include <map>       // map
#include <queue>     // queue, priority_queue
#include <set>       // set
#include <stack>     // stack
#include <string>    // string, to_string, stoi
#include <tuple>     // tuple, make_tuple
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <utility>       // pair, make_pair
#include <vector>        // vector

#define rep(i, n) for (int i = 0; i < n; i++)
#define vi vector<int>
#define vvi vector<vi>
#define pii pair<int, int>
#define all(a) (a).begin(), (a).end()
#define mod 998244353
using ll = long long;
using namespace std;
int main() {
  int n, k;
  cin >> n >> k;
  vi cnt(n + 2);
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    cnt[l]++;
    cnt[r + 1]--;
  }
  rep(i, n) cnt[i + 1] += cnt[i];
  set<int> check;
  rep(i, n) if (cnt[i + 1] > 0) check.insert(i + 1);
  vi dp(n + 1);
  dp[0] = 1;
  rep(i, n) {
    for (auto a : check) {
      if (i + a < n)
        (dp[i + a] += dp[i]) %= mod;
      else
        break;
    }
  }
  cout << dp[n - 1] << endl;
}

#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <bitset>    // bitset
#include <cctype>    // isupper, islower, isdigit, toupper, tolower
#include <cmath>     //sqrt pow
#include <cstdint>   // int64_t, int*_t
#include <cstdio>    // printf
#include <deque>     // dequef
#include <iostream>  // cout, endl, cin
#include <map>       // map
#include <queue>     // queue, priority_queue
#include <set>       // set
#include <stack>     // stack
#include <string>    // string, to_string, stoi
#include <tuple>     // tuple, make_tuple
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <utility>       // pair, make_pair
#include <vector>        // vector

#define rep(i, n) for (int i = 0; i < n; i++)
#define vi vector<int>
#define vvi vector<vi>
#define pii pair<int, int>
#define all(a) (a).begin(), (a).end()
#define mod 998244353
using ll = long long;
using namespace std;
int main() {
  int n, k;
  cin >> n >> k;
  vector<pii> cnt(k);
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    cnt[i] = make_pair(l, r);
  }
  vi dp(n);
  dp[0] = 1;
  dp[1] = -1;
  rep(i, n) {
    if (i > 0)
      (dp[i] += dp[i - 1]) %= mod;
    rep(j, k) {
      int l = cnt[j].first, r = cnt[j].second;
      if (i + l < n)
        (dp[i + l] += dp[i]) %= mod;
      if (i + r + 1 < n)
        (dp[i + r + 1] += -dp[i] + mod) %= mod;
    }
  }
  cout << dp[n - 1] << endl;
}


#include <bits/stdc++.h>
#include <math.h>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define M_PI 3.14159265358979323846

const int M = 998244353;
long long mod(long long x) { return ((x % M + M) % M); }
long long add(long long a, long long b) { return mod(mod(a) + mod(b)); }
long long mul(long long a, long long b) { return mod(mod(a) * mod(b)); }

ll modPow(ll a, ll b) {
  if (b == 0)
    return 1LL;
  if (b == 1)
    return a % M;
  ll res = 1;
  while (b) {
    if (b % 2 == 1)
      res = mul(res, a);
    a = mul(a, a);
    b = b / 2;
  }
  return res;
}
vector<ll> a(200005);
vector<pair<ll, ll>> seg(12);
void solve() {
  ll n, k;
  cin >> n >> k;
  for (int i = 1; i <= k; i++) {
    cin >> seg[i].first >> seg[i].second;
  }
  for (int i = 1; i <= k; i++) {
    a[seg[i].first + 1]++;
    a[seg[i].second + 1 + 1]--;
  }
  ll total = 0;
  for (int i = 2; i < n; i++) {
    total = add(total, a[i]);
    for (int j = 1; j <= k; j++) {
      a[seg[j].first + i] += total;
      a[seg[j].second + i + 1] -= total;
    }
  }
  cout << add(total, a[n]);
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout << fixed;
  cout << setprecision(10);
  //        freopen("timber_input.txt", "r", stdin);
  //        freopen("timber_output.txt", "w", stdout);
  int t = 1;
  // cin>>t;
  for (int i = 1; i <= t; i++) {
    //            cout<<"Case #"<<i<<": ";
    solve();
  }
  return 0;
}

#include <bits/stdc++.h>
#include <math.h>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define M_PI 3.14159265358979323846

const int M = 998244353;
long long mod(long long x) { return ((x % M + M) % M); }
long long add(long long a, long long b) { return mod(mod(a) + mod(b)); }
long long mul(long long a, long long b) { return mod(mod(a) * mod(b)); }
long long mins(long long a, long long b) { return mod(mod(a) - mod(b)); }

ll modPow(ll a, ll b) {
  if (b == 0)
    return 1LL;
  if (b == 1)
    return a % M;
  ll res = 1;
  while (b) {
    if (b % 2 == 1)
      res = mul(res, a);
    a = mul(a, a);
    b = b / 2;
  }
  return res;
}
vector<ll> a(200005);
vector<pair<ll, ll>> seg(12);
void solve() {
  ll n, k;
  cin >> n >> k;
  for (int i = 0; i < k; i++) {
    cin >> seg[i].first >> seg[i].second;
  }
  vector<ll> dp(n + 1), psum(n + 1);
  psum[1] = 1;
  for (int i = 1; i <= n; i++) {
    if (i > 2)
      psum[i] = add(psum[i], psum[i - 1]);
    psum[i] = add(psum[i], dp[i]);
    for (int j = 0; j < k; j++) {
      if (i + seg[j].first <= n)
        dp[i + seg[j].first] = add(dp[i + seg[j].first], psum[i]);
      if (i + seg[j].second + 1 <= n)
        dp[i + seg[j].second + 1] = mins(dp[i + seg[j].second + 1], psum[i]);
    }
  }
  cout << psum[n];
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout << fixed;
  cout << setprecision(10);
  //        freopen("timber_input.txt", "r", stdin);
  //        freopen("timber_output.txt", "w", stdout);
  int t = 1;
  // cin>>t;
  for (int i = 1; i <= t; i++) {
    //            cout<<"Case #"<<i<<": ";
    solve();
  }
  return 0;
}


#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define X first
#define Y second
#define nl '\\n'
#define AC return 0
#define pb(a) push_back(a)
#define mst(a, b) memset(a, b, sizeof a)
#define rep(i, n) for (int i = 0; (i) < (n); i++)
#define rep1(i, n) for (int i = 1; (i) <= (n); i++)
#define scd(a) scanf("%lld", &a)
#define scdd(a, b) scanf("%lld%lld", &a, &b)
#define scs(s) scanf("%s", s)
// #pragma GCC optimize(2)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const ll INF = (ll)0x3f3f3f3f3f3f3f, MAX = 9e18, MIN = -9e18;
const int N = 1e6 + 10, M = 2e6 + 10, mod = 998244353, inf = 0x3f3f3f;
ll v[N], dp[N];
vector<int> a;

int dfs(ll n) {
  if (~dp[n])
    return dp[n];

  dp[n] = 0;
  for (auto u : a)
    if (u <= n)
      dp[n] = (dp[n] + dfs(n - u)) % mod;
    else
      break;
  return dp[n];
}

int main() {
  IOS;
  ll n, k, ans = 0;
  cin >> n >> k;
  rep1(i, k) {
    int l, r;
    cin >> l >> r;
    v[l]++;
    v[r + 1]--;
  }
  rep1(i, n) {
    dp[i] = -1;
    v[i] += v[i - 1];
    if (v[i])
      a.pb(i);
  }

  dp[0] = 1;
  cout << dfs(n - 1) << nl;

  AC;
}

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
typedef long long ll;
typedef long double ld;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int, int>

const double PI = acos(-1.0);
const double eps = 1e-6;
const ll mod = 998244353;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 + 10;
const int maxm = 100 + 10;
#define ios                                                                    \\
  ios::sync_with_stdio(false);                                                 \\
  cin.tie(0);                                                                  \\
  cout.tie(0);

ll dp[maxn];
int vis[maxn];
int n, k;
int main() {
  cin >> n >> k;
  vector<pii> e;
  for (int i = 1; i <= k; i++) {
    int l, r;
    cin >> l >> r;
    e.push_back(make_pair(l, r));
  }
  sort(e.begin(), e.end());
  dp[1] = 1;
  for (int i = 2; i <= n; i++) {
    for (int j = 0; j < e.size(); j++) {
      int l = e[j].fi;
      int r = e[j].se;
      if (i - l < 0) {
        break;
      } else if (i - r >= 1)
        dp[i] = (dp[i] + dp[i - l] - dp[i - r - 1] + mod) % mod;
      else
        dp[i] = (dp[i] + dp[i - l]) % mod;
    }
    dp[i] = (dp[i] + dp[i - 1]) % mod;
  }
  cout << (dp[n] - dp[n - 1] + mod) % mod << endl;
}


#include <bits/stdc++.h>
#define ll long long
#define MODV 998244353
#define INFLL (1LL << 62) // 9223372036854775807
#define EPS 1e-9
#define rep(i, n) for (ll i = 0, i##_len = (ll)(n); i < i##_len; i++)
#define repf(i, n) for (ll i = 1, i##_len = (ll)(n + 1); i < i##_len; i++)
#define all(v) v.begin(), v.end()
#define endl "\\n"
#define vi vector<ll>
#define vvi vector<vector<ll>>
#define Yes() cout << "Yes" << endl
#define YES() cout << "YES" << endl
#define No() cout << "No" << endl
#define NO() cout << "NO" << endl
#define Init()                                                                 \\
  std::ios::sync_with_stdio(false);                                            \\
  std::cin.tie(0);                                                             \\
  std::cout << fixed << setprecision(15);
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
using namespace std;

int main() {
  Init();
  ll n, k;
  cin >> n >> k;
  vector<pair<ll, ll>> lr(k);
  rep(i, k) cin >> lr[i].first >> lr[i].second;
  sort(all(lr));

  vi dp(n + 400, 0), sect(n + 400, 0);
  dp[1] = 1, sect[1] = 1;

  for (ll i = 1; i <= n; i++) {
    dp[i] = dp[i - 1] + sect[i];
    dp[i] %= MODV;
    for (auto &range : lr) {
      sect[i + range.first] += dp[i];
      sect[i + range.first] %= MODV;
      sect[i + range.second + 1] -= dp[i];
      sect[i + range.second + 1] %= MODV;
    }
  }
  cout << sect[n] << endl;
  return 0;
}

#include <bits/stdc++.h>
#define ll long long
#define MODV 998244353
#define INFLL (1LL << 62) // 9223372036854775807
#define EPS 1e-9
#define rep(i, n) for (ll i = 0, i##_len = (ll)(n); i < i##_len; i++)
#define repf(i, n) for (ll i = 1, i##_len = (ll)(n + 1); i < i##_len; i++)
#define all(v) v.begin(), v.end()
#define endl "\\n"
#define vi vector<ll>
#define vvi vector<vector<ll>>
#define Yes() cout << "Yes" << endl
#define YES() cout << "YES" << endl
#define No() cout << "No" << endl
#define NO() cout << "NO" << endl
#define Init()                                                                 \\
  std::ios::sync_with_stdio(false);                                            \\
  std::cin.tie(0);                                                             \\
  std::cout << fixed << setprecision(15);
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
using namespace std;

int main() {
  Init();
  ll n, k;
  cin >> n >> k;
  vector<pair<ll, ll>> lr(k);
  rep(i, k) cin >> lr[i].first >> lr[i].second;
  sort(all(lr));

  vi dp(n * 2 + 1, 0), sect(n * 2 + 1, 0);
  dp[1] = 1, sect[1] = 1;

  for (ll i = 1; i <= n; i++) {
    dp[i] = dp[i - 1] + sect[i];
    dp[i] %= MODV;
    for (auto &range : lr) {
      sect[i + range.first] = (sect[i + range.first] + dp[i]) % MODV;
      sect[i + range.second + 1] =
          ((sect[i + range.second + 1] - dp[i]) % MODV + MODV) % MODV;
    }
  }
  cout << sect[n] << endl;
  return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define st first
#define sc second
#define pb push_back

using namespace std;

const int maxn = 1e6 + 69;
const ll mod = 998244353;

int a[maxn][10];
ll dp[maxn];

vector<int> s;

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

  int n, t;
  cin >> n >> t;
  for (int i = 1; i <= t; i++) {
    int l, r;
    cin >> l >> r;
    for (int j = l; j <= r; j++)
      s.pb(j);
  }
  sort(s.begin(), s.end());
  dp[1]++;
  for (int i = 1; i <= n; i++) {
    for (auto j : s) {
      if (j >= i)
        break;
      if (i - j >= 1) {
        dp[i] += dp[i - j];
        dp[i] %= mod;
      }
    }
  }
  cout << dp[n] % mod;
}

#include <bits/stdc++.h>
#define ll long long
#define st first
#define sc second
#define pb push_back

using namespace std;

const int maxn = 1e6 + 69;
const ll mod = 998244353;

int a[maxn][10];
ll dp[maxn];
ll st[4 * maxn];

void update(int id, int l, int r, int pos, ll val) {
  if (pos < l || pos > r)
    return;
  if (l == r) {
    st[id] += val;
    st[id] %= mod;
    return;
  }
  int mid = (l + r) / 2;
  update(id * 2, l, mid, pos, val);
  update(id * 2 + 1, mid + 1, r, pos, val);
  st[id] = (st[id * 2] + st[id * 2 + 1]) % mod;
}

ll get(int id, int l, int r, int u, int v) {
  if (v < l || u > r)
    return 0;
  if (u <= l && r <= v) {
    return st[id];
  }
  int mid = (l + r) / 2;
  return (get(id * 2, l, mid, u, v) + get(id * 2 + 1, mid + 1, r, u, v)) % mod;
}

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

  int n, t;
  cin >> n >> t;
  vector<pair<int, int>> p;
  for (int i = 1; i <= t; i++) {
    int l, r;
    cin >> l >> r;
    p.pb({l, r});
  }
  sort(p.begin(), p.end());
  update(1, 1, n, 1, 1);
  for (int i = 2; i <= n; i++) {
    for (int k = 0; k < t; k++) {
      int l = p[k].st;
      int r = p[k].sc;
      if (i < l)
        break;
      if (r < i) {
        if (i - l < 1)
          continue;
        int lf = max(i - l, 1);
        int rg = max(i - r, 1);
        ll cur = get(1, 1, n, rg, lf);
        update(1, 1, n, i, cur);
      } else if (l <= i && i <= r) {
        if (i - l < 1)
          continue;
        int lf = max(i - l, 1);
        ll cur = get(1, 1, n, 1, lf);
        update(1, 1, n, i, cur);
      }
    }
  }
  cout << get(1, 1, n, n, n);
}


#include <bits/stdc++.h>
#define pb push_back
#define SZ(x) ((int)(x.size()))
#define FOR(i, s, n) for (ll i = (s); (i) < (n); ++i)
#define FORD(i, s, l) for (ll i = (s); (i) >= l; --i)
#define F first
#define S second
#define TC                                                                     \\
  int __tc;                                                                    \\
  cin >> __tc;                                                                 \\
  FOR(case_num, 1, __tc + 1)
#define TEST(x, i) ((x) & (1ll << (i)))
#define SET(x, i) ((x) | (1ll << (i)))
#define FLIP(x, i) ((x) ^ (1ll << (i)))
#define CLEAR(x, i) ((x) & ~(1ll << (i)))
const double pi = 4 * atan(1);
using namespace std;
typedef long long ll;

template <typename T> void print_vec(const vector<T> &v) {
  for (int i = 0; i < SZ(v); i++) {
    if (i)
      cout << " ";
    cout << v[i];
  }
  cout << "\\n";
}

inline ll floorDiv(ll x, ll y) {
  ll d = x / y;
  ll r = x % y;
  return r ? (d - ((x < 0) ^ (y < 0))) : d;
}

ll ceilDiv(ll x, ll y) { return -floorDiv(-x, y); }

bool predicate(ll mid) { return mid > 10; }

ll bin_search(ll lo, ll hi) {
  int sign = lo < hi ? 1 : -1;
  lo *= sign;
  hi *= sign;
  hi++;
  while (lo < hi) {
    ll mid = floorDiv(lo + hi, 2);
    if (!predicate(sign * mid)) {
      lo = mid + 1;
    } else {
      hi = mid;
    }
  }
  return sign * lo;
}
const ll MOD = 998244353;
const int MAXN = 200005;

typedef vector<ll> vll;
typedef vector<int> vi;
#define LSOne(S) ((S) & -(S))

class FenwickTree { // index 0 is not used
private:
  vll ft; // internal FT is an array
public:
  FenwickTree(int m) { ft.assign(m + 1, 0); } // create an empty FT

  ll rsq(int j) { // returns RSQ(1, j)
    ll sum = 0;
    for (; j; j -= LSOne(j))
      sum += ft[j];
    sum %= MOD;
    return sum;
  }

  ll rsq(int i, int j) {
    return (((rsq(j) - rsq(i - 1)) % MOD) + MOD) % MOD;
  } // inc/exclusion

  // updates value of the i-th element by v (v can be +ve/inc or -ve/dec)
  void update(int i, ll v) {
    for (; i < (int)ft.size(); i += LSOne(i))
      ft[i] += v;
    ft[i] %= MOD;
  }
};

class RUPQ { // RUPQ variant
private:
  FenwickTree ft; // internally use PURQ FT
public:
  RUPQ(int m) : ft(FenwickTree(m)) {}
  void range_update(int ui, int uj, ll v) {
    ft.update(ui, v);                         // [ui, ui+1, .., m] +v
    ft.update(uj + 1, -v);                    // [uj+1, uj+2, .., m] -v
  }                                           // [ui, ui+1, .., uj] +v
  ll point_query(int i) { return ft.rsq(i); } // rsq(i) is sufficient
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, k;
  cin >> n >> k;
  vector<pair<int, int>> ranges;
  while (k--) {
    int a, b;
    cin >> a >> b;
    ranges.emplace_back(a, b);
  }
  RUPQ ft(n);
  ft.range_update(1, 1, 1);
  for (int i = 1; i < n; i++) {
    ll v = ft.point_query(i);
    for (auto p : ranges) {
      p.first += i;
      p.second += i;
      p.second = min(p.second, n);
      if (p.first > p.second) {
        continue;
      }
      ft.range_update(p.first, p.second, v);
    }
  }

  cout << ft.point_query(n) << "\\n";
}

#include <bits/stdc++.h>
#define pb push_back
#define SZ(x) ((int)(x.size()))
#define FOR(i, s, n) for (ll i = (s); (i) < (n); ++i)
#define FORD(i, s, l) for (ll i = (s); (i) >= l; --i)
#define F first
#define S second
#define TC                                                                     \\
  int __tc;                                                                    \\
  cin >> __tc;                                                                 \\
  FOR(case_num, 1, __tc + 1)
#define TEST(x, i) ((x) & (1ll << (i)))
#define SET(x, i) ((x) | (1ll << (i)))
#define FLIP(x, i) ((x) ^ (1ll << (i)))
#define CLEAR(x, i) ((x) & ~(1ll << (i)))
const double pi = 4 * atan(1);
using namespace std;
typedef long long ll;

template <typename T> void print_vec(const vector<T> &v) {
  for (int i = 0; i < SZ(v); i++) {
    if (i)
      cout << " ";
    cout << v[i];
  }
  cout << "\\n";
}

inline ll floorDiv(ll x, ll y) {
  ll d = x / y;
  ll r = x % y;
  return r ? (d - ((x < 0) ^ (y < 0))) : d;
}

ll ceilDiv(ll x, ll y) { return -floorDiv(-x, y); }

bool predicate(ll mid) { return mid > 10; }

ll bin_search(ll lo, ll hi) {
  int sign = lo < hi ? 1 : -1;
  lo *= sign;
  hi *= sign;
  hi++;
  while (lo < hi) {
    ll mid = floorDiv(lo + hi, 2);
    if (!predicate(sign * mid)) {
      lo = mid + 1;
    } else {
      hi = mid;
    }
  }
  return sign * lo;
}
const ll MOD = 998244353;
const int MAXN = 200005;

typedef vector<ll> vll;
typedef vector<int> vi;
#define LSOne(S) ((S) & -(S))

class FenwickTree { // index 0 is not used
private:
  vll ft; // internal FT is an array
public:
  FenwickTree(int m) { ft.assign(m + 1, 0); } // create an empty FT

  ll rsq(int j) { // returns RSQ(1, j)
    ll sum = 0;
    for (; j; j -= LSOne(j)) {
      sum += ft[j];
      sum = ((sum % MOD) + MOD) % MOD;
    }
    return sum;
  }

  ll rsq(int i, int j) {
    return (((rsq(j) - rsq(i - 1)) % MOD) + MOD) % MOD;
  } // inc/exclusion

  // updates value of the i-th element by v (v can be +ve/inc or -ve/dec)
  void update(int i, ll v) {
    for (; i < (int)ft.size(); i += LSOne(i)) {
      ft[i] += v;
      ft[i] = ((ft[i] % MOD) + MOD) % MOD;
    }
  }
};

class RUPQ { // RUPQ variant
private:
  FenwickTree ft; // internally use PURQ FT
public:
  RUPQ(int m) : ft(FenwickTree(m)) {}
  void range_update(int ui, int uj, ll v) {
    ft.update(ui, v);                         // [ui, ui+1, .., m] +v
    ft.update(uj + 1, -v);                    // [uj+1, uj+2, .., m] -v
  }                                           // [ui, ui+1, .., uj] +v
  ll point_query(int i) { return ft.rsq(i); } // rsq(i) is sufficient
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, k;
  cin >> n >> k;
  vector<pair<int, int>> ranges;
  while (k--) {
    int a, b;
    cin >> a >> b;
    ranges.emplace_back(a, b);
  }
  RUPQ ft(n);
  ft.range_update(1, 1, 1);
  for (int i = 1; i < n; i++) {
    ll v = ft.point_query(i);
    for (auto p : ranges) {
      p.first += i;
      p.second += i;
      p.second = min(p.second, n);
      if (p.first > p.second) {
        continue;
      }
      ft.range_update(p.first, p.second, v);
    }
  }

  cout << ft.point_query(n) << "\\n";
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define pii pair<int, int>
ll dp[(ll)(2e5 + 2)];
ll MOD = 998244353;
int main() {
  memset(dp, 0, sizeof dp);
  int n, k;
  cin >> n >> k;
  vector<pii> v(k);
  for (int i = 0; i < k; i++) {
    cin >> v[i].first >> v[i].second;
  }
  // int ans=0;
  dp[0] = 1;
  vector<ll> pref(n + 1);
  ll pref_sum = 0;
  for (int i = 0; i < n; i++) {
    dp[i] += pref_sum;
    for (int j = 0; j < k; j++) {
      int L = v[j].first;
      int R = v[j].second;
      if (i + L < n)
        pref[i + L] += dp[i];
      // pref[i+L] = pref[i+L]%MOD;
      if (pref[i + L] > MOD)
        pref[i + L] -= MOD;
      if (i + R + 1 < n) {
        pref[i + R + 1] -= dp[i];
        if (pref[i + R + 1] < 0)
          pref[i + R + 1] += MOD;
      }
    }
    pref_sum += pref[i + 1];
    if (pref_sum > MOD)
      pref_sum -= MOD;
    if (pref_sum < 0)
      pref_sum += MOD;
  }
  cout << dp[n - 1] % MOD << endl;
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define pii pair<int, int>
ll dp[(ll)(2e5 + 2)];
ll MOD = 998244353;
int main() {
  memset(dp, 0, sizeof dp);
  int n, k;
  cin >> n >> k;
  vector<pii> v(k);
  for (int i = 0; i < k; i++) {
    cin >> v[i].first >> v[i].second;
  }
  // int ans=0;
  dp[0] = 1;
  vector<ll> pref(n + 1);
  ll pref_sum = 0;
  for (int i = 0; i < n; i++) {
    dp[i] += pref_sum;
    for (int j = 0; j < k; j++) {
      int L = v[j].first;
      int R = v[j].second;
      if (i + L < n)
        pref[i + L] += dp[i];
      // pref[i+L] = pref[i+L]%MOD;
      if (i + L < n && pref[i + L] > MOD)
        pref[i + L] -= MOD;
      if (i + R + 1 < n) {
        pref[i + R + 1] -= dp[i];
        if (pref[i + R + 1] < 0)
          pref[i + R + 1] += MOD;
      }
    }
    pref_sum += pref[i + 1];
    if (pref_sum > MOD)
      pref_sum -= MOD;
    if (pref_sum < 0)
      pref_sum += MOD;
  }
  cout << dp[n - 1] % MOD << endl;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;

const int mod = 998244353;

int main() {

  int n, k;
  cin >> n >> k;
  vector<int> b(n);
  int p = 0;
  for (int i = 0; i < k; i++) {
    int l, r;
    cin >> l >> r;
    for (int j = l; j <= r; j++)
      b[p++] = j;
  }

  vector<ll> dp(n + 1);
  dp[1] = 1;
  for (int j = 1; j <= n; j++) {
    for (int i = 0; i < p; i++) {
      if (j >= b[i])
        dp[j] = (dp[j] + dp[j - b[i]]) % mod;
    }
  }

  cout << dp[n];

  return 0;
}

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;

const int mod = 998244353;

int main() {

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

  vector<ll> dp(n + 1);
  vector<ll> pre(n + 1);
  dp[1] = 1;
  pre[1] = 1;

  for (int j = 2; j <= n; j++) {
    for (int i = 0; i < k; i++) {
      dp[j] =
          (dp[j] + pre[max(j - l[i], 0)] - pre[max(0, j - r[i] - 1)] + mod) %
          mod;
    }
    pre[j] = (pre[j - 1] + dp[j]) % mod;
  }

  cout << dp[n];

  return 0;
}


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

using namespace std;
using ll = long long;

const ll MOD = 998244353;

int main() {
  ll N, K, L, R;
  cin >> N >> K;
  vector<int> S;
  while (cin >> L >> R) {
    for (int s = L; s <= R; ++s) {
      S.push_back(s);
    }
  }
  sort(begin(S), end(S));
  vector<ll> dp(N + 1);
  dp[1] = 1;
  for (int i = 1; i != N; ++i) {
    if (!dp[i])
      continue;
    for (int s : S) {
      if (i + s > N)
        break;
      dp[i + s] = (dp[i + s] + dp[i]) % MOD;
    }
  }

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

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

using namespace std;

template <std::uint_fast64_t Mod> class ModInt {
  using u64 = std::uint_fast64_t;

public:
  u64 val;

  constexpr ModInt(const u64 x = 0) noexcept : val(x % Mod) {}
  constexpr ModInt operator+(const ModInt rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  constexpr ModInt operator-(const ModInt rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  constexpr ModInt operator*(const ModInt rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  constexpr ModInt operator/(const ModInt rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }
  constexpr ModInt &operator+=(const ModInt rhs) noexcept {
    val += rhs.val;
    if (val >= Mod) {
      val -= Mod;
    }
    return *this;
  }
  constexpr ModInt &operator-=(const ModInt rhs) noexcept {
    if (val < rhs.val) {
      val += Mod;
    }
    val -= rhs.val;
    return *this;
  }
  constexpr ModInt &operator*=(const ModInt rhs) noexcept {
    val = val * rhs.val % Mod;
    return *this;
  }
  constexpr ModInt &operator/=(ModInt rhs) noexcept {
    u64 exp = Mod - 2;
    while (exp) {
      if (exp % 2) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= 2;
    }
    return *this;
  }
};

const long long MOD = 998244353;
using mint = ModInt<MOD>;

int main() {
  int N, K;
  cin >> N >> K;
  vector<pair<int, int>> S(K);
  for (auto &[l, r] : S)
    cin >> l >> r;
  vector<mint> dp(N);
  dp[0] = 1;
  dp[1] -= 1;
  for (int i = 0; i != N; ++i) {
    if (i)
      dp[i] += dp[i - 1];
    for (auto [l, r] : S) {
      if (i + l < N)
        dp[i + l] += dp[i];
      if (i + r + 1 < N)
        dp[i + r + 1] -= dp[i];
    }
  }
  cout << dp[N - 1].val << endl;
}


#pragma warning(disable : 4996)
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <sstream>
#include <string>
#include <vector>

using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 0; i < (n); i++)

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> w;
  ll dp[200005] = {0};
  rep(i, k) {
    int l, r;
    cin >> l >> r;
    for (int i = l; i <= r; i++) {
      w.push_back(i);
      dp[i] = 1;
    }
  }
  int s = w.size();
  rep(i, n) {
    rep(j, s) {
      if (i - w[j] >= 0) {
        dp[i] += dp[i - w[j]];
        dp[i] %= 998244353;
      }
    }
  }

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

  return 0;
}

#pragma warning(disable : 4996)
#include <algorithm>
#include <bitset>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <sstream>
#include <string>
#include <vector>

using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 0; i < (n); i++)

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> l(n), r(n);
  rep(i, k) cin >> l[i] >> r[i];
  vector<ll> dp(n + 1);
  vector<ll> dpsum(n + 1);
  dp[1] = 1;
  dpsum[1] = 1; // dpの累積和
  for (int i = 2; i <= n; i++) {
    rep(j, k) {
      int li = i - r[j];
      int ri = i - l[j];
      if (ri < 0)
        continue;
      li = max(li, 1);
      dp[i] += dpsum[ri] -
               dpsum[li - 1]; // 現在位置iからの差分のdpsumが更新に必要となる
      dp[i] %= 998244353;
      if (dp[i] < 0)
        dp[i] += 998244353;
    }
    dpsum[i] = dpsum[i - 1] + dp[i];
    dpsum[i] %= 998244353;
    if (dpsum[i] < 0)
      dpsum[i] += 998244353;
  }
  cout << dp[n] << endl;

  return 0;
}


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

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> move;
  ll ans[n];
  for (int i = 0; i < k; i++) {
    int l, r;
    cin >> l >> r;
    for (int j = l; j <= r; j++) {
      move.push_back(j);
    }
  }
  for (int i = 0; i < n; i++) {
    ans[i] = 0;
  }
  ll mod = 998244353;
  sort(move.begin(), move.end());
  int size = move.size();
  ans[0] = 1;
  for (int i = 1; i < n; i++) {
    int cou = 0;
    for (int j = 0; j < size; j++) {
      if (i - move[j] < 0) {
        break;
      } else {
        ans[i] += ans[i - move[j]];
        ans[i] %= mod;
      }
    }
  }

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

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

int main() {
  int n, k;
  cin >> n >> k;
  vector<int> move;
  ll ans[n];
  pair<int, int> l[k];
  ll sum[k];
  ll dis[k];
  ll now[k];
  for (int i = 0; i < k; i++) {
    cin >> l[i].first >> l[i].second;
    sum[i] = 0;
    dis[i] = 0;
    now[i] = -1;
  }
  for (int i = 0; i < n; i++) {
    ans[i] = 0;
  }
  ll mod = 998244353;
  sort(l, l + k);

  for (int i = 0; i < k; i++) {
    dis[i] = l[i].second - l[i].first;
  }
  int size = move.size();
  ans[0] = 1;
  for (int i = 1; i < n; i++) {
    for (int j = 0; j < k; j++) {
      if (i - l[j].first < 0) {
        break;
      } else {
        if (now[j] == dis[j]) {
          sum[j] -= ans[i - l[j].second - 1];
          sum[j] += ans[i - l[j].first];
          ans[i] += sum[j];
          ans[i] %= mod;
        } else {
          now[j]++;
          sum[j] += ans[i - l[j].first];
          ans[i] += sum[j];
          ans[i] %= mod;
        }
      }
    }
  }

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


#include <bits/stdc++.h>
#define ll long long
using namespace std;
typedef pair<int, int> P;
typedef pair<ll, ll> LP;

// 定数
// 円周率
const double pi = 3.141592653589793238462643383279;
// 天井
const int INF = 1000000000;         // = 10^9
const ll LINF = 100000000000000000; // = 10^17
// ABC文字列
const string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZABC";
const string abc = "abcdefghijklmnopqrstuvwxyzabc";
// よくあるmodくん
const ll MOD = 1000000007; // = 10^9 + 7
// 前処理テーブルの大きさ指定
const int MAX = 1200000; // = 10^6 + 2*(10^5)
// ちなみに、1024MBで持てる最大長の配列は10^8程度

// データ構造
// 隣接リスト用構造体（有向グラフ向け）
struct edge {
  ll to;   // E.toでその辺の終点へアクセスできる。
  ll cost; // e.costでその辺の重みにアクセスできる。
};
// Union_Find木
struct UnionFind {
  vector<int> UF;   // UF.at(i) : iの親の番号
  vector<int> SIZE; // SIZE.at(root(i)) : iと連結されてる要素の数
  UnionFind(int N) : UF(N), SIZE(N, 1) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++) {
      UF.at(i) = i;
    }
  }
  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (UF.at(x) == x) {
      return x;
    }
    return UF.at(x) = root(UF.at(x));
  }
  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry) {
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    }
    // xとyの根が同じでない(=同じ木にない)時：小さい方の根を大きい方の根につける。
    if (SIZE.at(rx) < SIZE.at(ry)) {
      UF.at(rx) = ry;
      SIZE.at(ry) += SIZE.at(rx);
      SIZE.at(rx) = 0;
    } else {
      UF.at(ry) = rx;
      SIZE.at(rx) += SIZE.at(ry);
      SIZE.at(ry) = 0;
    }
  }
  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す。
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
  int size(int x) { // xと連結されてる要素の数を返す。
    return SIZE.at(root(x));
  }
};

// 関数 (計算量)
// ctoi (O(1))
int ctoi(char c) {
  if (c == '0')
    return 0;
  if (c == '1')
    return 1;
  if (c == '2')
    return 2;
  if (c == '3')
    return 3;
  if (c == '4')
    return 4;
  if (c == '5')
    return 5;
  if (c == '6')
    return 6;
  if (c == '7')
    return 7;
  if (c == '8')
    return 8;
  if (c == '9')
    return 9;
  return -1;
}
// to_char (O(1))
char to_char(int i) {
  if (i == 0)
    return '0';
  if (i == 1)
    return '1';
  if (i == 2)
    return '2';
  if (i == 3)
    return '3';
  if (i == 4)
    return '4';
  if (i == 5)
    return '5';
  if (i == 6)
    return '6';
  if (i == 7)
    return '7';
  if (i == 8)
    return '8';
  if (i == 9)
    return '9';
  return ' ';
}

// メイン処理
int main() {
  cout << fixed << setprecision(16); // 精度向上
  // ここまでテンプレ
  int N;
  cin >> N;
  int K;
  cin >> K;
  vector<int> M;
  for (int i = 0; i < K; i++) {
    int L, R;
    cin >> L >> R;
    for (int j = L; j <= R; j++) {
      M.push_back(j);
    }
  }
  sort(M.begin(), M.end());
  vector<int> DP(N, 0);
  DP.at(0) = 1;
  for (int i = 1; i < N; i++) {
    for (int j = 0; j < int(M.size()); j++) {
      if (M.at(j) <= i) {
        DP.at(i) += DP.at(i - M.at(j));
        DP.at(i) %= 998244353;
      } else {
        break;
      }
    }
  }
  cout << DP.at(N - 1) << endl;
}

#include <bits/stdc++.h>
#define ll long long
using namespace std;
typedef pair<int, int> P;
typedef pair<ll, ll> LP;

// 定数
// 円周率
const double pi = 3.141592653589793238462643383279;
// 天井
const int INF = 1000000000;         // = 10^9
const ll LINF = 100000000000000000; // = 10^17
// ABC文字列
const string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZABC";
const string abc = "abcdefghijklmnopqrstuvwxyzabc";
// よくあるmodくん
const ll MOD = 1000000007; // = 10^9 + 7
// 前処理テーブルの大きさ指定
const int MAX = 1200000; // = 10^6 + 2*(10^5)
// ちなみに、1024MBで持てる最大長の配列は10^8程度

// データ構造
// 隣接リスト用構造体（有向グラフ向け）
struct edge {
  ll to;   // E.toでその辺の終点へアクセスできる。
  ll cost; // e.costでその辺の重みにアクセスできる。
};
// Union_Find木
struct UnionFind {
  vector<int> UF;   // UF.at(i) : iの親の番号
  vector<int> SIZE; // SIZE.at(root(i)) : iと連結されてる要素の数
  UnionFind(int N) : UF(N), SIZE(N, 1) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < N; i++) {
      UF.at(i) = i;
    }
  }
  int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (UF.at(x) == x) {
      return x;
    }
    return UF.at(x) = root(UF.at(x));
  }
  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry) {
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    }
    // xとyの根が同じでない(=同じ木にない)時：小さい方の根を大きい方の根につける。
    if (SIZE.at(rx) < SIZE.at(ry)) {
      UF.at(rx) = ry;
      SIZE.at(ry) += SIZE.at(rx);
      SIZE.at(rx) = 0;
    } else {
      UF.at(ry) = rx;
      SIZE.at(rx) += SIZE.at(ry);
      SIZE.at(ry) = 0;
    }
  }
  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す。
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
  int size(int x) { // xと連結されてる要素の数を返す。
    return SIZE.at(root(x));
  }
};

// 関数 (計算量)
// ctoi (O(1))
int ctoi(char c) {
  if (c == '0')
    return 0;
  if (c == '1')
    return 1;
  if (c == '2')
    return 2;
  if (c == '3')
    return 3;
  if (c == '4')
    return 4;
  if (c == '5')
    return 5;
  if (c == '6')
    return 6;
  if (c == '7')
    return 7;
  if (c == '8')
    return 8;
  if (c == '9')
    return 9;
  return -1;
}
// to_char (O(1))
char to_char(int i) {
  if (i == 0)
    return '0';
  if (i == 1)
    return '1';
  if (i == 2)
    return '2';
  if (i == 3)
    return '3';
  if (i == 4)
    return '4';
  if (i == 5)
    return '5';
  if (i == 6)
    return '6';
  if (i == 7)
    return '7';
  if (i == 8)
    return '8';
  if (i == 9)
    return '9';
  return ' ';
}

// メイン処理
int main() {
  cout << fixed << setprecision(16); // 精度向上
  // ここまでテンプレ
  int N;
  cin >> N;
  int K;
  cin >> K;
  vector<vector<int>> M(K, vector<int>(2));
  for (int i = 0; i < K; i++) {
    cin >> M.at(i).at(0) >> M.at(i).at(1);
  }
  vector<ll> DP(N + 1, 0);
  DP.at(0) = 1;
  DP.at(1) = -1;
  for (int i = 0; i < N; i++) {
    DP.at(i) %= 998244353;
    for (int j = 0; j < K; j++) {
      if (i + M.at(j).at(0) < N) {
        DP.at(i + M.at(j).at(0)) += DP.at(i);
        DP.at(min(i + M.at(j).at(1) + 1, N)) -= DP.at(i);
      }
    }
    DP.at(i + 1) += DP.at(i);
  }
  DP.at(N - 1) += 998244353;
  DP.at(N - 1) %= 998244353;
  cout << DP.at(N - 1) << endl;
}


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

int main() {
  long long n, k, i, j, mod = 998244353;
  cin >> n >> k;

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

  vector<long long> ans(n + 1 + 100000, 0), cur(n + 1 + 100000, 0);
  long long l, r, res;

  res = 1;
  for (i = 1; i < n; i++) {
    for (j = 0; j < k; j++) {
      l = d[j].first;
      r = d[j].second + 1;
      cur[i + l] += res;
      cur[i + r] -= res;
    }
    ans[i + 1] = (ans[i] + cur[i + 1]) % mod;
    res = (ans[i] + cur[i + 1]) % mod;
  }

  ans[n] %= mod;
  if (ans[n] < 0) {
    ans[n] += mod;
  }
  cout << ans[n] << endl;
  return 0;
}

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

int main() {
  long long n, k, i, j, mod = 998244353;
  cin >> n >> k;

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

  vector<long long> ans(n + 1 + 100000, 0), cur(n + 1 + 100000, 0);
  long long l, r, res;

  res = 1;
  for (i = 1; i < n; i++) {
    for (j = 0; j < k; j++) {
      l = d[j].first;
      r = d[j].second + 1;
      if (i + l > n) {
        l = n + 1 - i;
      }
      if (i + r > n) {
        r = n + 1 - i;
      }
      cur[i + l] += res;
      cur[i + r] -= res;
    }
    ans[i + 1] = (ans[i] + cur[i + 1]) % mod;
    res = (ans[i] + cur[i + 1]) % mod;
  }

  ans[n] %= mod;
  if (ans[n] < 0) {
    ans[n] += mod;
  }
  cout << ans[n] << endl;
  return 0;
}


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

#define REP(i, n) for (int i = 0; i < n; i++)
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()

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

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vl = vector<ll>;
using Pi = pair<int, int>;
using Pl = pair<ll, ll>;
using vpi = vector<Pi>;
using vpl = vector<Pl>;

#define debug(arr) cout << #arr << " = " << arr << '\\n'
#define debug2(a, b)                                                           \\
  cout << "[" << #a << "," << #b << "] = "                                     \\
       << "[" << a << "," << b << "]" << '\\n'
template <class T> ostream &operator<<(ostream &out, const vector<T> &arr) {
  cout << "{";
  for (int i = 0; i < arr.size(); i++)
    cout << (!i ? "" : ", ") << arr[i];
  cout << "}";
  return out;
}
template <class T>
ostream &operator<<(ostream &out, const vector<vector<T>> &arr) {
  cout << "{\\n";
  for (auto &vec : arr)
    cout << "  " << vec << ",\\n";
  cout << "}";
  return out;
}
template <class S, class T>
ostream &operator<<(ostream &out, const pair<S, T> &p) {
  cout << "{" << p.first << "," << p.second << "}" << '\\n';
  return out;
}
template <class T> istream &operator>>(istream &in, vector<T> &arr) {
  for (auto &i : arr)
    cin >> i;
  return in;
}

/////////////////////////////////////////////////////////////////////////
#define MOD 998244353
template <int mod> struct Modint {
  long long x; // typedef long long ll;
  Modint(long long x = 0) : x((x % mod + mod) % mod) {}
  Modint &operator+=(const Modint a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  Modint &operator-=(const Modint a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }
  Modint &operator*=(const Modint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  Modint operator+(const Modint a) const {
    Modint res(*this);
    return res += a;
  }
  Modint operator-(const Modint a) const {
    Modint res(*this);
    return res -= a;
  }
  Modint operator*(const Modint a) const {
    Modint res(*this);
    return res *= a;
  }
  Modint pow(ll t) const {
    if (!t)
      return 1;
    Modint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }
  // for prime mod
  Modint inv() const { return pow(mod - 2); }
  Modint &operator/=(const Modint a) { return (*this) *= a.inv(); }
};
using mint = Modint<MOD>;

template <class T> class RangeSumQuery {
private:
  vector<T> dat;
  int n;
  T INF;

public:
  RangeSumQuery(int n_) {
    INF = 0;
    n = 1;
    while (n < n_)
      n *= 2;
    dat.assign(2 * n - 1, INF);
  }
  void update(int k, T a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = dat[k * 2 + 1] + dat[k * 2 + 2];
    }
  }
  T query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return INF;
    if (a <= l && r <= b)
      return dat[k];
    else {
      T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return vl + vr;
    }
  }
  T query(int a, int b) { return query(a, b, 0, 0, n); }
};

mint dp[100010];
int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  // cout << fixed << setprecision(20);

  int n, k;
  cin >> n >> k;
  RangeSumQuery<mint> ST(n + 1);
  vector<Pi> range(k);
  REP(i, k) { cin >> range[i].first >> range[i].second; }
  sort(all(range));

  dp[0] = 1;
  ST.update(0, 1);
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      int l = i - range[j].second;
      int r = i - range[j].first + 1;
      if (r < 0)
        continue;
      dp[i] += ST.query(max(0, l), r);
      ST.update(i, dp[i]);
    }
  }

  cout << dp[n - 1].x << '\\n';

  return 0;
}

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

#define REP(i, n) for (int i = 0; i < n; i++)
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()

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

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vl = vector<ll>;
using Pi = pair<int, int>;
using Pl = pair<ll, ll>;
using vpi = vector<Pi>;
using vpl = vector<Pl>;

#define debug(arr) cout << #arr << " = " << arr << '\\n'
#define debug2(a, b)                                                           \\
  cout << "[" << #a << "," << #b << "] = "                                     \\
       << "[" << a << "," << b << "]" << '\\n'
template <class T> ostream &operator<<(ostream &out, const vector<T> &arr) {
  cout << "{";
  for (int i = 0; i < arr.size(); i++)
    cout << (!i ? "" : ", ") << arr[i];
  cout << "}";
  return out;
}
template <class T>
ostream &operator<<(ostream &out, const vector<vector<T>> &arr) {
  cout << "{\\n";
  for (auto &vec : arr)
    cout << "  " << vec << ",\\n";
  cout << "}";
  return out;
}
template <class S, class T>
ostream &operator<<(ostream &out, const pair<S, T> &p) {
  cout << "{" << p.first << "," << p.second << "}" << '\\n';
  return out;
}
template <class T> istream &operator>>(istream &in, vector<T> &arr) {
  for (auto &i : arr)
    cin >> i;
  return in;
}

/////////////////////////////////////////////////////////////////////////
#define MOD 998244353
template <int mod> struct Modint {
  long long x; // typedef long long ll;
  Modint(long long x = 0) : x((x % mod + mod) % mod) {}
  Modint &operator+=(const Modint a) {
    if ((x += a.x) >= mod)
      x -= mod;
    return *this;
  }
  Modint &operator-=(const Modint a) {
    if ((x += mod - a.x) >= mod)
      x -= mod;
    return *this;
  }
  Modint &operator*=(const Modint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  Modint operator+(const Modint a) const {
    Modint res(*this);
    return res += a;
  }
  Modint operator-(const Modint a) const {
    Modint res(*this);
    return res -= a;
  }
  Modint operator*(const Modint a) const {
    Modint res(*this);
    return res *= a;
  }
  Modint pow(ll t) const {
    if (!t)
      return 1;
    Modint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }
  // for prime mod
  Modint inv() const { return pow(mod - 2); }
  Modint &operator/=(const Modint a) { return (*this) *= a.inv(); }
};
using mint = Modint<MOD>;

template <class T> class RangeSumQuery {
private:
  vector<T> dat;
  int n;
  T INF;

public:
  RangeSumQuery(int n_) {
    INF = 0;
    n = 1;
    while (n < n_)
      n *= 2;
    dat.assign(2 * n - 1, INF);
  }
  void update(int k, T a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = dat[k * 2 + 1] + dat[k * 2 + 2];
    }
  }
  T query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return INF;
    if (a <= l && r <= b)
      return dat[k];
    else {
      T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return vl + vr;
    }
  }
  T query(int a, int b) { return query(a, b, 0, 0, n); }
};

mint dp[200010];
int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  // cout << fixed << setprecision(20);

  int n, k;
  cin >> n >> k;
  RangeSumQuery<mint> ST(n + 1);
  vector<Pi> range(k);
  REP(i, k) { cin >> range[i].first >> range[i].second; }
  sort(all(range));

  dp[0] = 1;
  ST.update(0, 1);
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < k; j++) {
      int l = i - range[j].second;
      int r = i - range[j].first + 1;
      if (r < 0)
        continue;
      dp[i] += ST.query(max(0, l), r);
      ST.update(i, dp[i]);
    }
  }

  cout << dp[n - 1].x << '\\n';

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
#define fi first
#define se second
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
#define pb push_back
#define faster                                                                 \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);
#define mem(a, v) memset(a, v, sizeof(a))
const ll INF = 1e18;
const int mod = 998244353;
const int iinf = 1e9 + 10;
const int xd[4] = {1, 0, -1, 0}, yd[4] = {0, 1, 0, -1};
const int mxN = 2e5;
ll dp[mxN + 1];
int main() {
  faster int n, k;
  cin >> n >> k;
  vector<int> v;
  while (k--) {
    int a, b;
    cin >> a >> b;
    for (int i = a; i <= b; i++) {
      if (i <= n - 1)
        v.pb(i);
    }
  }
  dp[0] = 1;
  for (int i = 0; i <= n - 1; i++) {
    for (int j = 0; j < sz(v); j++) {
      if (i - v[j] >= 0) {
        dp[i] = (dp[i] + dp[i - v[j]]) % mod;
      }
    }
  }
  cout << dp[n - 1];
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
#define fi first
#define se second
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
#define pb push_back
#define faster                                                                 \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);
#define mem(a, v) memset(a, v, sizeof(a))
const ll INF = 1e18;
const int mod = 998244353;
const int iinf = 1e9 + 10;
const int xd[4] = {1, 0, -1, 0}, yd[4] = {0, 1, 0, -1};
const int mxN = 2e5;
ll dp[mxN + 1], c[10], dp1[mxN + 1];
pii a[mxN + 1];
ll g(int l, int r) {
  // cout<<"r="<<r<<" "<<dp1[r]<<"\\n";
  // cout<<"l-1="<<l-1<<" "<<dp1[l-1]<<"\\n";
  if (l <= 0)
    l = 0;
  return ((dp1[r] - dp1[l - 1]) % mod + mod) % mod;
}
int main() {
  faster int n, k;
  cin >> n >> k;
  for (int i = 0; i < k; i++)
    cin >> a[i].fi >> a[i].se;
  dp[0] = 1;
  dp1[0] = 1;
  for (int i = 1; i <= n - 1; i++) {
    for (int j = 0; j < k; j++) {
      dp[i] = (dp[i] + g(i - a[j].se, i - a[j].fi)) % mod;
    }
    dp1[i] = (dp1[i - 1] + dp[i]) % mod;
  }
  cout << dp[n - 1];
}


/*
    हॉंजी । की हाल चाल?
    बड़ीया सब?
*/

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

#define ff first
#define ss second
#define int long long
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define vi vector<int>
#define mii unordered_map<int, int>
#define setbits(x) __builtin_popcountll(x)
#define zrobits(x) __builtin_ctzll(x)
#define MOD 998244353
#define inf 1e18
#define ps(x, y) fixed << setprecision(y) << x
#define w(x)                                                                   \\
  int x;                                                                       \\
  cin >> x;                                                                    \\
  while (x--)
#define EPS 1e-9

void gogeta() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
}

int MAX = 2 * 100000 + 5;
vector<pii> v(15);
vector<int> memo(MAX, -1);

bool isValid(int i) {
  for (auto x : v) {
    if (i >= x.ff && i <= x.ss)
      return true;
  }
  return false;
}

int util(int i, int n) {
  if (i > n)
    return 0;
  if (i == n)
    return 1;
  if (memo[i] != -1)
    return memo[i];

  int ans = 0;
  for (int d = 1; d <= n - i; d++) {
    if (isValid(d))
      ans = (ans + util(i + d, n)) % MOD;
  }
  return memo[i] = ans;
}

int32_t main() {
  gogeta();
  int n, k;
  cin >> n >> k;
  for (int i = 0; i < k; i++) {
    cin >> v[i].ff >> v[i].ss;
  }
  memo.resize(MAX, -1);
  cout << util(1, n) << endl;
}

/*
    हॉंजी । की हाल चाल?
    बड़ीया सब?
*/

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

#define ff first
#define ss second
#define int long long
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define vi vector<int>
#define mii unordered_map<int, int>
#define setbits(x) __builtin_popcountll(x)
#define zrobits(x) __builtin_ctzll(x)
#define MOD 998244353
#define inf 1e18
#define ps(x, y) fixed << setprecision(y) << x
#define w(x)                                                                   \\
  int x;                                                                       \\
  cin >> x;                                                                    \\
  while (x--)
#define EPS 1e-9

void gogeta() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
}

int MAX = 2 * 100000 + 5;

int32_t main() {
  gogeta();
  int n, k;
  cin >> n >> k;
  vector<pii> v(k);
  for (int i = 0; i < k; i++) {
    cin >> v[i].ff >> v[i].ss;
  }
  vector<int> dp(n + 2, 0);
  dp[n] = 1;
  vector<int> pre(n + 2, 0);
  pre[n] = 1;
  for (int i = n - 1; i >= 1; i--) {
    for (auto x : v) {
      if (i + x.ff <= n)
        dp[i] = (dp[i] + pre[i + x.ff] - pre[min(n, i + x.ss) + 1]) % MOD;
    }
    pre[i] = (dp[i] + pre[i + 1]) % MOD;
  }
  cout << (dp[1] + MOD) % MOD << endl;
}


#include "bits/stdc++.h"

using namespace std;
using ll = long long;
ll mod = 998244353;
ll dp[200005];
vector<ll> vt;
int main() {
#ifdef LOCAL
  freopen("in1.txt", "r", stdin);
  freopen("out1.txt", "w", stdout);
#endif

  ll n;
  cin >> n;
  dp[1] = 1;
  ll num;
  cin >> num;
  for (ll i = 0; i < num; ++i) {
    ll l, r;
    scanf("%lld %lld", &l, &r);
    for (ll j = l; j <= r; ++j) {
      vt.push_back(j);
    }
  }
  sort(vt.begin(), vt.end());
  for (ll i = 1; i < n; ++i) {
    for (ll j : vt) {
      if (i + j > n) {
        break;
      }
      dp[i + j] += dp[i];
      dp[i + j] %= mod;
    }
  }
  cout << dp[n] % mod << endl;
  return 0;
}

#include "bits/stdc++.h"

using namespace std;
using ll = long long;
const ll mod = 998244353;
const ll maxn = 2e5 + 10;

struct tnode {
  ll w, l, r, siz, alazy;
  ll sq, mlazy = 1;
} tn[maxn << 2];

ll n, m;

ll wt[maxn];

void pushup(ll u) {
  tn[u].w = (tn[u << 1].w + tn[u << 1 | 1].w) % mod;
  tn[u].sq = (tn[u << 1].sq + tn[u << 1 | 1].sq) % mod;
}

void build(ll u, ll l, ll r) {
  tn[u].l = l;
  tn[u].r = r;
  tn[u].siz = r - l + 1;
  if (l == r) {
    tn[u].w = wt[l];
    tn[u].sq = wt[l] * wt[l];
    return;
  }
  ll mid = (l + r) >> 1;
  build(u << 1, l, mid);
  build(u << 1 | 1, mid + 1, r);
  pushup(u);
}

void pushdown(ll u) {
  if (tn[u].alazy != 0 or tn[u].mlazy != 1) {
    tn[u << 1].sq =
        ((tn[u << 1].sq + 2LL * tn[u << 1].w * tn[u].alazy % mod) % mod +
         tn[u].alazy * tn[u].alazy % mod * tn[u << 1].siz % mod) %
        mod;
    tn[u << 1 | 1].sq =
        ((tn[u << 1 | 1].sq + 2LL * tn[u << 1 | 1].w * tn[u].alazy % mod) %
             mod +
         tn[u].alazy * tn[u].alazy % mod * tn[u << 1 | 1].siz % mod) %
        mod;

    tn[u << 1].w = (tn[u << 1].w * tn[u].mlazy % mod +
                    tn[u << 1].siz * tn[u].alazy % mod) %
                   mod;
    tn[u << 1 | 1].w = (tn[u << 1 | 1].w * tn[u].mlazy % mod +
                        tn[u << 1 | 1].siz * tn[u].alazy % mod) %
                       mod;

    tn[u << 1].alazy =
        (tn[u << 1].alazy * tn[u].mlazy % mod + tn[u].alazy) % mod;
    tn[u << 1 | 1].alazy =
        (tn[u << 1 | 1].alazy * tn[u].mlazy % mod + tn[u].alazy) % mod;

    tn[u << 1].mlazy = (tn[u << 1].mlazy * tn[u].mlazy) % mod;
    tn[u << 1 | 1].mlazy = (tn[u << 1 | 1].mlazy * tn[u].mlazy) % mod;

    tn[u].alazy = 0;
    tn[u].mlazy = 1;
  }
}

ll query(ll u, ll l, ll r, ll t) {
  if (l <= tn[u].l and r >= tn[u].r) {
    if (t == 1)
      return tn[u].w;
    if (t == 2)
      return tn[u].sq;
  }

  ll ans = 0;
  pushdown(u);
  ll mid = (tn[u].l + tn[u].r) >> 1;
  if (l <= mid)
    ans = (ans + query(u << 1, l, r, t)) % mod;
  if (r > mid)
    ans = (ans + query(u << 1 | 1, l, r, t)) % mod;
  return ans;
}

void update(ll u, ll l, ll r, ll wa, ll wm) {
  if (l <= tn[u].l and r >= tn[u].r) {
    tn[u].sq = ((tn[u].sq + 2LL * tn[u].w * wa % mod) % mod +
                wa * wa % mod * tn[u].siz % mod) %
               mod;
    tn[u].w = (tn[u].w * wm % mod + tn[u].siz * wa % mod) % mod;

    tn[u].alazy = (tn[u].alazy * wm % mod + wa) % mod;
    tn[u].mlazy = (tn[u].mlazy * wm) % mod;

    return;
  }
  pushdown(u);
  ll mid = (tn[u].l + tn[u].r) >> 1;
  if (l <= mid)
    update(u << 1, l, r, wa, wm);
  if (r > mid)
    update(u << 1 | 1, l, r, wa, wm);
  pushup(u);
}

/*
 * cin>>n>>m;
    for(ll i=1;i<=n;i++){
        cin>>wt[i];
    }

    build(1,1,n);
    while(m--){
        ll t;
        cin>>t;
        switch(t){
            case 1:{
                ll x,y;
                cin>>x>>y;
                cout<<query(1,x,y,1)<<endl;
                break;
            }
            case 2:{
                ll x,y;
                cin>>x>>y;
                cout<<query(1,x,y,2)<<endl;
                break;
            }
            case 3:{
                ll x,y,z;
                cin>>x>>y>>z;
                update(1,x,y,0,z%mod);
                break;
            }
            case 4:{
                ll x,y,z;
                cin>>x>>y>>z;
                update(1,x,y,z%mod,1);
                break;
            }

        }

    }
 */

int main() {
#ifdef LOCAL
  freopen("in1.txt", "r", stdin);
  freopen("out1.txt", "w", stdout);
#endif

  ll k;
  cin >> n >> k;
  wt[1] = 1;
  build(1, 1, n);

  vector<pair<ll, ll>> vt;
  for (int i = 0; i < k; ++i) {
    ll u, v;
    cin >> u >> v;
    vt.emplace_back(u, v);
  }
  sort(vt.begin(), vt.end());
  for (ll i = 1; i < n; ++i) {
    for (auto j : vt) {
      if (i + j.second > n) {
        if (i + j.first <= n) {
          update(1, i + j.first, n, query(1, i, i, 1) % mod, 1);
        }
        break;
      } else {
        update(1, i + j.first, i + j.second, query(1, i, i, 1) % mod, 1);
      }
    }
  }
  cout << query(1, n, n, 1) << endl;
  return 0;
}