#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvl = vector<vll>;
const int mod = 998244353;
const int INF = 2e9;
const int MAX = 1e6;
struct unionfind {
  vector<int> parent;
  vector<int> diff_weight;
  unionfind(int n) {
    parent.resize(n, -1);
    diff_weight.resize(n, 0);
  }
  int root(int x) {
    if (parent[x] < 0) return x;
    int r = root(parent[x]);
    diff_weight[x] += diff_weight[parent[x]];
    return parent[x] = r;
  }
  int weight(int x) {
    root(x);
    return diff_weight[x];
  }
  void merge(int x, int y) {
    x = root(x), y = root(y);
    if (x == y) return;
    if (parent[x] > parent[y]) {
      swap(x, y);
    }
    parent[x] += parent[y];
    parent[y] = x;
  }
  void merge(int x, int y, int w) {
    w += weight(x), w -= weight(y);
    x = root(x), y = root(y);
    if (x == y) return;
    if (parent[x] > parent[y]) {
      swap(x, y);
      w *= -1;
    }
    parent[x] += parent[y];
    parent[y] = x;
    diff_weight[y] = w;
  }
  bool common(int x, int y) { return root(x) == root(y); }
  int size(int x) { return -parent[root(x)]; }
  int diff(int x, int y) { return weight(y) - weight(x); }
};
struct edge {
  int from, to, cost;
};
struct graph {
  int n;
  vector<vector<edge>> G;
  vector<bool> visited;
  vector<int> indeg;
  graph(int _n) {
    n = _n;
    G.resize(n);
    visited.resize(n, false);
    indeg.resize(n, 0);
  }
  void add_edge(int from, int to, int cost) {
    G[from].push_back({from, to, cost});
    indeg[to]++;
  }
  void dfs(int s) {
    visited[s] = true;
    for (edge e : G[s]) {
      if (not visited[e.to]) continue;
      dfs(e.to);
    }
  }
  void dfs(int s, int i, int _n) {
    visited[s] = true;
    if (i == _n) return;
    for (edge e : G[s]) {
      if (visited[e.to]) continue;
      dfs(e.to, i + 1, _n);
    }
  }
  void dfs(int cur, int prev, bool &closed) {
    visited[cur] = true;
    for (edge e : G[cur]) {
      if (not visited[e.to]) {
        dfs(e.to, cur, closed);
      } else if (e.to != prev) {
        closed = true;
      }
    }
  }
  void bfs(int s) {
    queue<int> q;
    q.push(s);
    visited[s] = true;
    while (not q.empty()) {
      int cur = q.front();
      for (edge e : G[cur]) {
        if (not visited[e.to]) continue;
        q.push(e.to);
        visited[e.to] = true;
      }
    }
  }
  void dijkstra(int s, vector<int> &dist) {
    using pii = pair<int, int>;
    dist.resize(n, INF);
    dist[s] = 0;
    priority_queue<pii, vector<pii>, greater<pii>> pq;
    pq.push({dist[s], s});
    while (not pq.empty()) {
      int cur = pq.top().second;
      pq.pop();
      for (edge e : G[cur]) {
        if (dist[e.to] > dist[cur] + e.cost) {
          dist[e.to] = dist[cur] + e.cost;
          pq.push({dist[e.to], e.to});
        }
      }
    }
  }
  void bellman_ford(int s, vector<int> &dist, bool &negative) {
    fill(visited.begin(), visited.end(), false);
    dfs(s);
    dist.resize(n, INF);
    dist[s] = 0;
    for (int i = 0; i < n; i++) {
      for (int u = 0; u < n; u++) {
        for (edge e : G[u]) {
          if (not visited[e.to]) continue;
          if (dist[e.to] > dist[u] + e.cost) {
            dist[e.to] = dist[u] + e.cost;
            if (i == n - 1) {
              negative = true;
              return;
            }
          }
        }
      }
    }
  }
  void warshall_floyd(vector<vector<int>> &dist, bool &negative) {
    dist.resize(n, vector<int>(n, INF));
    for (int i = 0; i < n; i++) {
      for (edge e : G[i]) {
        dist[i][e.to] = e.cost;
      }
      dist[i][i] = 0;
    }
    for (int k = 0; k < n; k++) {
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          if (dist[i][k] == INF or dist[k][j] == INF) continue;
          if (dist[i][j] > dist[i][k] + dist[k][j]) {
            dist[i][j] = dist[i][k] + dist[k][j];
          }
          if (i == j and dist[i][j] < 0) {
            negative = true;
            return;
          }
        }
      }
    }
  }
  static bool comp(const edge &e1, const edge &e2) { return e1.cost < e2.cost; }
  void kruskal(vector<edge> &edges, int &sum) {
    unionfind mst(n);
    sort(edges.begin(), edges.end(), comp);
    int m = edges.size();
    sum = 0;
    for (int i = 0; i < m; i++) {
      edge e = edges[i];
      if (not mst.common(e.from, e.to)) {
        mst.merge(e.from, e.to);
        sum += e.cost;
      }
    }
  }
  void topological(vector<int> &t) {
    queue<int> q;
    for (int i = 0; i < n; i++) {
      if (indeg[i] == 0) {
        q.push(i);
      }
    }
    while (not q.empty()) {
      int cur = q.front();
      q.pop();
      t.push_back(cur);
      for (edge e : G[cur]) {
        indeg[e.to]--;
        if (indeg[e.to] == 0) {
          q.push(e.to);
        }
      }
    }
  }
};
template <typename T>
struct cusum {
  int n;
  vector<T> s;
  cusum(vector<T> &a) {
    n = a.size();
    s.resize(n + 1);
    s[0] = 0;
    for (int i = 1; i <= n; i++) {
      s[i] = s[i - 1] + a[i - 1];
    }
  }
  T sum(int a, int b) { return s[b] - s[a]; }
};
template <typename T>
struct BIT {
  int MAX;
  vector<T> bit;
  BIT(int n) {
    MAX = n;
    bit.resize(MAX + 1, 0);
  }
  void add(int i, int x) {
    while (i <= MAX) {
      bit[i] += x;
      i += i & -i;
    }
  }
  T sum(int i) {
    T s = 0;
    while (i > 0) {
      s += bit[i];
      i -= i & -i;
    }
    return s;
  }
  T rsq(int a, int b) { return sum(b) - sum(a - 1); }
};
template <typename T>
bool is_prime(T x) {
  if (x < 2) return false;
  for (T i = 2; i * i <= x; i++) {
    if (x % i == 0) return false;
  }
  return true;
}
template <typename T>
void prime_fact(T x, vector<T> &factor) {
  for (T i = 2; i * i <= x; i++) {
    while (x % i == 0) {
      factor.push_back(i);
      x /= i;
    }
  }
  if (x != 1) {
    factor.push_back(x);
  }
}
struct erat {
  int MAX;
  vector<int> seive;
  erat(int n) {
    MAX = n;
    seive.resize(MAX + 1);
    for (int i = 0; i <= MAX; i++) {
      seive[i] = i;
    }
    for (int i = 2; i <= MAX; i++) {
      if (seive[i] == i) {
        for (int j = i + i; j <= MAX; j += i) {
          seive[j] = i;
        }
      }
    }
  }
  void fact(int x, vector<int> &factor) {
    if (x < 2) return;
    while (x > 1 and x % seive[x] == 0) {
      factor.push_back(seive[x]);
      x /= seive[x];
    }
    reverse(factor.begin(), factor.end());
  }
  bool is_prime(int x) {
    if (x >= 2 and seive[x] == x) return true;
    return false;
  }
};
template <typename T>
T gcd(T a, T b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
template <typename T>
T gcd(vector<T> &a) {
  int n = (int)a.size();
  T r;
  for (int i = 0; i < n; i++) {
    if (i == 0) r = a[i];
    r = gcd(r, a[i]);
  }
  return r;
}
template <typename T>
T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
template <typename T>
T lcm(vector<T> &a) {
  int n = (int)a.size();
  T r = 1;
  for (int i = 0; i < n; i++) {
    r = lcm(r, a[i]);
  }
  return r;
}
template <typename T>
T digit_sum(T n) {
  T sum = 0;
  while (n > 0) {
    sum += n % 10;
    n /= 10;
  }
  return sum;
}
template <typename T>
T digit_sum(string s) {
  int n = (int)s.size();
  T sum = 0;
  for (int i = 0; i < n; i++) {
    sum += s[i] - '0';
  }
  return sum;
}
int eular(int n) {
  int p = n;
  for (int i = 2; i * i <= n; i++) {
    if (n % i == 0) {
      p -= p / i;
      while (n % i == 0) n /= i;
    }
  }
  if (n > 1) p -= p / n;
  return p;
}
template <typename T>
bool is_triangle(T a, T b, T c) {
  if (a + b > c && b + c > a && c + a > b)
    return true;
  else
    return false;
}
template <typename T>
struct combination {
  int MAX;
  vector<T> f;
  vector<vector<T>> dp;
  combination(int _n) {
    MAX = _n;
    f.resize(MAX + 1, 0);
    for (int i = 0; i <= MAX; i++) {
      if (i == 0)
        f[i] = 1;
      else
        f[i] = i * f[i - 1] % mod;
    }
    dp.resize(MAX + 1, vector<T>(MAX + 1, 0));
  }
  T power(int m, int n) {
    if (n == 0) return 1;
    if (n % 2 == 1) return m * power(m, n - 1) % mod;
    T r = power(m, n / 2);
    return r * r % mod;
  }
  T inv(int a, int b) { return a * power(b, mod - 2) % mod; }
  T fact(int n) { return f[n]; }
  T perm(int n, int r) {
    if (n < r) return 0;
    return inv(fact(n), fact(n - r));
  }
  T comb(int n, int r) {
    if (n < r) return 0;
    return inv(perm(n, r), fact(r));
  }
  T pie(int n, int k) {
    T s = 0;
    for (int i = 0; i < k; i++) {
      s += power(-1, i) * comb(k, i) * power(k - i, n);
      s %= mod;
      if (s < 0) s += mod;
    }
    return s;
  }
  T part(int n, int k) {
    if (n < 0) return 0;
    if (n == 0 || k == 1) return dp[n][k] = 1;
    if (dp[n][k] != 0) return dp[n][k];
    return dp[n][k] = (part(n, k - 1) + part(n - k, k)) % mod;
  }
  T stir(int n, int k) {
    if (n < k || (n > 0 && k == 0)) return 0;
    if (n == k || k == 1) return dp[n][k] = 1;
    if (dp[n][k] != 0) return dp[n][k];
    return dp[n][k] = (stir(n - 1, k - 1) + k * stir(n - 1, k)) % mod;
  }
  T bell(int n, int k) {
    T s = 0;
    for (int i = 0; i <= k; i++) {
      s += stir(n, i);
      s %= mod;
    }
    return s;
  }
};
vector<int> s;
vector<ll> dp(200001);
ll rec(int i) {
  if (i < 1) return 0;
  if (dp[i] != 0) return dp[i];
  if (i == 1) return dp[i] = 1;
  ll r = 0;
  for (int x = 0; x < (int)s.size(); x++) {
    if (i - s[x] < 1) break;
    r += rec(i - s[x]);
    r %= mod;
  }
  return dp[i] = r;
}
int main() {
  int n, k;
  cin >> n >> k;
  for (int i = 0; i < k; i++) {
    int l, r;
    cin >> l >> r;
    for (int j = l; j <= r; j++) {
      s.push_back(j);
    }
  }
  sort(s.begin(), s.end());
  cout << rec(n) << endl;
}
