#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using ld = long double;
using vld = std::vector<ld>;
using vvld = std::vector<vld>;
using vvvld = std::vector<vvld>;
using bl = bool;
using vbl = std::vector<bl>;
using vvbl = std::vector<vbl>;
using vvvbl = std::vector<vvbl>;
using ss = string;
using vss = std::vector<ss>;
template <class T>
void printsp(vector<T> v, size_t w = 3) {
  for (auto(a) : v) {
    cerr << setw(w) << a << " ";
  }
  cerr << endl;
}
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
void bye(T a) {
  cout << a << '\n';
  exit(0);
}
template <class T1, class T2>
void bye(T1 a, T2 b) {
  cout << a << " " << b << '\n';
  exit(0);
}
template <class T1, class T2, class T3>
void bye(T1 a, T2 b, T3 c) {
  cout << a << " " << b << " " << c << '\n';
  exit(0);
}
template <class T>
void bye(vector<T> A) {
  for (ll(i) = 0; (i) < (ll)((ll)A.size()); (i)++) {
    cout << A[i];
    if (i != (ll)A.size() - 1) {
      cout << " ";
    }
  }
  cout << endl;
  exit(0);
}
template <typename T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (T &x : vec) is >> x;
  return is;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, pair<T, U> &pair_var) {
  os << "(" << pair_var.first << ", " << pair_var.second << ")";
  return os;
}
ostream &operator<<(ostream &os, const vector<string> &vec) {
  ll N = to_string((ll)vec.size()).length();
  string head;
  for (ll(i) = 0; (i) < (ll)(N + 2); (i)++) {
    head += "-";
  }
  for (ll(i) = 0; (i) < (ll)(40); (i)++) {
    head += to_string(i % 10);
  }
  os << setw(N) << head << endl;
  for (ll i = 0; i < (ll)vec.size(); i++) {
    os << setw(N) << i << ": " << vec[i] << endl;
  }
  return os;
}
ostream &operator<<(ostream &os, const vector<ll> &vec) {
  ll N = to_string((ll)vec.size()).length();
  for (ll i = 0; i < (ll)vec.size(); i++) {
    os << setw(N) << i << ": " << vec[i] << endl;
  }
  return os;
}
ostream &operator<<(ostream &os, const vector<ld> &vec) {
  ll N = to_string((ll)vec.size()).length();
  for (ll i = 0; i < (ll)vec.size(); i++) {
    os << setw(N) << i << ": " << vec[i] << endl;
  }
  return os;
}
ostream &operator<<(ostream &os, const vector<vector<ll>> &mat) {
  ll keta = 1;
  for (ll(i) = 0; (i) < (ll)(mat.size()); (i)++) {
    for (ll(j) = 0; (j) < (ll)(mat[i].size()); (j)++) {
      ll x = mat[i][j];
      chmax(keta, (ll)to_string(x).length());
    }
  }
  ll N = to_string((ll)mat.size()).length();
  for (ll(i) = 0; (i) < (ll)(mat.size()); (i)++) {
    os << setw(N) << i << ": ";
    for (ll(j) = 0; (j) < (ll)(mat[i].size()); (j)++) {
      ll x = mat[i][j];
      os << setw(keta + 1) << x;
    }
    os << endl;
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &vec) {
  for (ll i = 0; i < (ll)vec.size(); i++) {
    os << setw(5) << vec[i];
  }
  os << endl;
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, map<T, U> &map_var) {
  os << "{";
  for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
    os << *itr;
    itr++;
    if (itr != map_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, set<T> &set_var) {
  os << "{";
  for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
    os << *itr;
    itr++;
    if (itr != set_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
void dump_func() { cerr << endl; }
template <class Head, class... Tail>
void dump_func(Head &&head, Tail &&...tail) {
  cerr << ("\033[36m");
  cerr << head;
  if (sizeof...(Tail) > 0) {
    cerr << ", ";
  }
  dump_func(std::move(tail)...);
  cerr << "\033[m";
}
struct Fast {
  Fast() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(std::numeric_limits<double>::max_digits10);
  }
} fast;
inline vll cinvll(ll N, ll minus = 0) {
  vll A(N);
  for (ll(i) = 0; (i) < (ll)(N); (i)++) {
    cin >> A[i];
    A[i] -= minus;
  }
  return move(A);
}
inline vvll zerosll(ll H, ll W, ll val = 0) {
  vvll A(H, vll(W, val));
  return move(A);
}
inline vvvll zerosll3(ll H, ll W, ll C, ll val = 0) {
  vvvll A(H, vvll(W, vll(C, val)));
  return move(A);
}
vvll cinvll2(ll H, ll W, ll bias = 0) {
  vvll A = zerosll(H, W);
  for (ll(i) = 0; (i) < (ll)(H); (i)++) {
    for (ll(j) = 0; (j) < (ll)(W); (j)++) {
      cin >> A[i][j];
      A[i][j] += bias;
    }
  }
  return move(A);
}
tuple<vll, vll> aho2(ll N) {
  vll A(N), B(N);
  for (ll(i) = 0; (i) < (ll)(N); (i)++) {
    cin >> A[i] >> B[i];
  }
  return (make_tuple(A, B));
}
template <class T = ll>
inline vector<T> cinv(ll N, T val = 0) {
  vector<T> v(N);
  for (ll(i) = 0; (i) < (ll)(N); (i)++) {
    cin >> v[i];
    v[i] += val;
  }
  return move(v);
}
template <class T = ll>
inline vector<vector<T>> zeros(ll H, ll W, T val = 0) {
  vector<vector<T>> A(H, vector<T>(W, val));
  return move(A);
}
template <class T = ll>
inline vector<vector<vector<T>>> zeros3(ll H, ll W, ll C, T val = 0) {
  vector<vector<vector<T>>> A(H, vector<vector<T>>(W, vector<T>(C, val)));
  return move(A);
}
template <typename TTT>
vector<ll> arg_sort(const vector<TTT> &A, bool ascend = true) {
  vector<ll> index(A.size());
  iota(index.begin(), index.end(), 0);
  if (ascend) {
    std::sort(index.begin(), index.end(),
              [&A](TTT i1, TTT i2) { return A[i1] < A[i2]; });
  } else {
    std::sort(index.begin(), index.end(),
              [&A](TTT i1, TTT i2) { return A[i1] > A[i2]; });
  }
  return index;
}
template <typename TTT>
vector<TTT> permute(vector<TTT> src, vll idx) {
  vector<TTT> dst(src.size());
  for (ll(i) = 0; (i) < (ll)(src.size()); (i)++) {
    dst[i] = src[idx[i]];
  }
  return move(dst);
}
ll powll(ll a, ll b) {
  ll c = 1LL;
  for (ll(i) = 0; (i) < (ll)(b); (i)++) {
    c *= a;
  }
  return c;
}
void funcA() {
  ss S;
  cin >> S;
  if (S[S.length() - 1] == 's') {
    bye(S + "es");
  }
  bye(S + "s");
}
void funcB() {
  ll N;
  cin >> N;
  ll cnt = 0;
  vll Z(N);
  for (ll(i) = 0; (i) < (ll)(N); (i)++) {
    ll a, b;
    cin >> a >> b;
    if (a == b) {
      Z[i] = 1;
    }
  }
  for (ll(i) = 0; (i) < (ll)(N - 2); (i)++) {
    if (Z[i] == 1 and Z[i + 1] == 1 and Z[i + 2] == 1) {
      bye("Yes");
    }
  }
  bye("No");
}
void funcC() {
  ll N;
  cin >> N;
  ll cnt = 0;
  for (ll(a) = 1; (a) < (ll)(N + 1); (a)++) {
    for (ll(b) = 1; (b) < (ll)(N + 1); (b)++) {
      ll n = a * b;
      if (N - n >= 1) {
        cnt++;
      } else {
        break;
      }
    }
  }
  bye(cnt);
}
void func() {
  ll N, K;
  cin >> N >> K;
  ll MOD = 998244353;
  vvll LR = zeros(K, 2);
  for (ll(i) = 0; (i) < (ll)(K); (i)++) {
    cin >> LR[i][0];
    cin >> LR[i][1];
    LR[i][0];
    LR[i][1];
  }
  vll imos(N + 1, 0);
  vll cnts(N + 1, 0);
  cnts[0] = 0;
  for (ll(i) = 0; (i) < (ll)(N); (i)++) {
    for (ll(k) = 0; (k) < (ll)(K); (k)++) {
      ll l = LR[k][0];
      ll r = LR[k][1];
      ll cnt = cnts[i];
      if (i == 0) {
        cnt = 1;
      }
      imos[i + l] += cnt;
      imos[i + l] %= MOD;
      if (i + r + 1 <= N) {
        imos[i + r + 1] -= cnt;
        imos[i + r + 1] %= MOD;
      }
      cnts[i + 1] = cnts[i] + imos[i + 1];
      cnts[i + 1] %= MOD;
    }
  };
  for (ll(i) = 0; (i) < (ll)(N); (i)++) {
    imos[i + 1] = imos[i + 1] + imos[i];
  };
  ll ans = cnts[N - 1] % MOD;
  if (ans < 0) {
    ans += MOD;
  }
  bye(ans);
}
int main() {
  ;
  func();
  return 0;
}
