#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <functional>
#include <iterator>
#include <numeric>
#include <cstdint>
#include <cmath>
#include <bitset>
#include <string>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <random>
#include <chrono>

#define N_TIMES(i, n)     for ( uint64_t i = 0;     i <  n; ++i )
#define N_TIMES_REV(i, n) for (  int64_t i = n - 1; i >= 0; --i )

template<typename T> using maximum_heap = std::priority_queue<T, std::vector<T>, std::less<T>>;
template<typename T> using minimum_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

template<typename T>
std::istream& operator>>(std::istream &is, std::vector<T> &v)
{
  for (typename std::vector<T>::size_type i = 0; i < v.size(); ++i) {
    is >> v[i];
  }
  return is;
}

const uint64_t MOD = 998244353;

template<typename T, T MOD = 1e+9 + 7>
struct mod_int_base
{
protected:
  T _val;

public:
  mod_int_base(T val = 0) : _val(val % MOD) {}

  T get() const { return _val; }

  mod_int_base<T, MOD> pow(const T &e) const
  {
    if (e <= 1) {
      return (e == 0) ? mod_int_base<T, MOD>(1) : (*this);
    }

    mod_int_base<T, MOD> w = pow(e >> 1);
    mod_int_base<T, MOD> z = w * w;

    if (e % 2 == 1) { z *= (*this); }

    return z;
  }

  mod_int_base<T, MOD> inv() const { return pow(MOD - 2); }

  bool operator==(const T &rhs) const { return _val == (rhs % MOD); }
  bool operator!=(const T &rhs) const { return _val != (rhs % MOD); }
  bool operator< (const T &rhs) const { return _val <  (rhs % MOD); }
  bool operator<=(const T &rhs) const { return _val <= (rhs % MOD); }
  bool operator> (const T &rhs) const { return _val >  (rhs % MOD); }
  bool operator>=(const T &rhs) const { return _val >= (rhs % MOD); }

  bool operator==(const mod_int_base<T, MOD> &rhs) const { return _val == rhs.get(); }
  bool operator!=(const mod_int_base<T, MOD> &rhs) const { return _val != rhs.get(); }
  bool operator< (const mod_int_base<T, MOD> &rhs) const { return _val <  rhs.get(); }
  bool operator<=(const mod_int_base<T, MOD> &rhs) const { return _val <= rhs.get(); }
  bool operator> (const mod_int_base<T, MOD> &rhs) const { return _val >  rhs.get(); }
  bool operator>=(const mod_int_base<T, MOD> &rhs) const { return _val >= rhs.get(); }

  mod_int_base<T, MOD> operator+(const T &rhs) const {
    return mod_int_base<T, MOD>((_val + (rhs % MOD)) % MOD);
  }
  mod_int_base<T, MOD> operator-(const T &rhs) const {
    return mod_int_base<T, MOD>((_val + (MOD - (rhs % MOD))) % MOD);
  }
  mod_int_base<T, MOD> operator*(const T &rhs) const {
    return mod_int_base<T, MOD>((_val * (rhs % MOD)) % MOD);
  }
  mod_int_base<T, MOD> operator/(const T &rhs) const {
    return mod_int_base<T, MOD>((_val * mod_int_base<T, MOD>(rhs).inv().get()) % MOD);
  }
  mod_int_base<T, MOD> operator+(const mod_int_base<T, MOD> &rhs) const {
    return mod_int_base<T, MOD>((_val + rhs.get()) % MOD);
  }
  mod_int_base<T, MOD> operator-(const mod_int_base<T, MOD> &rhs) const {
    return mod_int_base<T, MOD>((_val + (MOD - rhs.get())) % MOD);
  }
  mod_int_base<T, MOD> operator*(const mod_int_base<T, MOD> &rhs) const {
    return mod_int_base<T, MOD>((_val * rhs.get()) % MOD);
  }
  mod_int_base<T, MOD> operator/(const mod_int_base<T, MOD> &rhs) const {
    return mod_int_base<T, MOD>((_val * rhs.inv().get()) % MOD);
  }

  mod_int_base<T, MOD>& operator+=(const T &rhs) {
    _val = (_val + (rhs % MOD)) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator-=(const T &rhs) {
    _val = (_val + (MOD - (rhs % MOD))) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator*=(const T &rhs) {
    _val = (_val * (rhs % MOD)) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator/=(const T &rhs) {
    _val = (_val * mod_int_base<T, MOD>(rhs).inv().get()) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator+=(const mod_int_base<T, MOD> &rhs) {
    _val = (_val + rhs.get()) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator-=(const mod_int_base<T, MOD> &rhs) {
    _val = (_val + (MOD - rhs.get())) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator*=(const mod_int_base<T, MOD> &rhs) {
    _val = (_val * rhs.get()) % MOD;
    return *this;
  }
  mod_int_base<T, MOD>& operator/=(const mod_int_base<T, MOD> &rhs) {
    _val = (_val * rhs.inv().get()) % MOD;
    return *this;
  }
};

template<uint64_t MOD = 1e+9 + 7>
struct mod_uint64_t_base : public mod_int_base<uint64_t, MOD>
{
public:
  mod_uint64_t_base(uint64_t n = 0) : mod_int_base<uint64_t, MOD>(n) {}
  mod_uint64_t_base(const mod_int_base<uint64_t, MOD> &n) : mod_int_base<uint64_t, MOD>(n) {}  

  operator uint64_t () const { return this->get(); }
};

using m_uint64_t = mod_uint64_t_base<MOD>;

std::istream& operator>>(std::istream& is, m_uint64_t &v)
{
  uint64_t u;
  is >> u;
  v = m_uint64_t(u);
  return is;
}

std::ostream& operator<<(std::ostream& os, const m_uint64_t &v)
{
  os << v.get();
  return os;
}

template<typename INDEX_TYPE, typename VALUE_TYPE, const VALUE_TYPE &Undefined = 0, class Add = std::plus<VALUE_TYPE>>
class RangeAddQueryBase {
private:
  std::vector<VALUE_TYPE> segment_tree;
  INDEX_TYPE N, M;

  INDEX_TYPE _upper_bound_by_power_of_2(INDEX_TYPE n) const
  {
    return 1 << static_cast<INDEX_TYPE>(
      ::ceill(::log2l(static_cast<long double>(n)))
    );
  }

  VALUE_TYPE _build_segment_tree(const std::vector<VALUE_TYPE> &a, INDEX_TYPE i = 0)
  {
    if (i >= (M << 1)) {
      return Undefined;
    }

    segment_tree[i] = Undefined;

    _build_segment_tree(a, 2 * i + 1);
    _build_segment_tree(a, 2 * i + 2);

    return segment_tree[i];
  }

  void _lazy_update(INDEX_TYPE i)
  {
    if (segment_tree[i] != Undefined && i < M - 1) {
      segment_tree[2 * i + 1] = Add()(segment_tree[2 * i + 1], segment_tree[i]);
      segment_tree[2 * i + 2] = Add()(segment_tree[2 * i + 2], segment_tree[i]);
      segment_tree[i] = Undefined;
    }
  }

  bool _add(INDEX_TYPE left, INDEX_TYPE right, VALUE_TYPE value, INDEX_TYPE lb, INDEX_TYPE ub, INDEX_TYPE i)
  {
    _lazy_update(i);

    if (ub <= left || right <= lb) {
      return false;
    }

    if (left <= lb && ub <= right) {
      segment_tree[i] = Add()(segment_tree[i], value);
      _lazy_update(i);
      return true;
    }

    INDEX_TYPE mid = (lb + ub) / 2;
    bool f = _add(left, right, value, lb,  mid, 2 * i + 1);
    bool g = _add(left, right, value, mid,  ub, 2 * i + 2);
    return f || g;
  }

  VALUE_TYPE _get(INDEX_TYPE index, INDEX_TYPE lb, INDEX_TYPE ub, INDEX_TYPE i)
  {
    _lazy_update(i);

    if (ub - lb <= 1) {
      return segment_tree[i];
    }

    INDEX_TYPE mid = (lb + ub) / 2;
    if (index < mid) {
      return _get(index, lb,  mid, 2 * i + 1);
    } else {
      return _get(index, mid,  ub, 2 * i + 2);
    }
  }

public:
  RangeAddQueryBase(const std::vector<VALUE_TYPE> &a)
  {
    N = a.size();
    M = _upper_bound_by_power_of_2(N);

    segment_tree = std::vector<VALUE_TYPE>(M << 1, Undefined);

    for (INDEX_TYPE n = 0; n < N; ++n) {
      segment_tree[n + (M - 1)] = a[n];
    }

    _build_segment_tree(a);
  }

  bool add(INDEX_TYPE left, INDEX_TYPE right, VALUE_TYPE value)
  {
    return _add(left, right, value, 0, M, 0);
  }

  VALUE_TYPE get(INDEX_TYPE index)
  {
    return _get(index, 0, M, 0);
  }
};

const m_uint64_t Undefined = 0;

using RangeAddQuery = RangeAddQueryBase<uint64_t, m_uint64_t, Undefined>;

using namespace std;

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

  map<uint64_t, uint64_t> X;
  N_TIMES(k, K) {
    uint64_t L, R;
    cin >> L >> R;

    X[L] = R;
  }

  RangeAddQuery dp( vector<m_uint64_t>(N + 1, 0) );
  dp.add(0, 1, 1);
  N_TIMES(n, N) {
    for (const auto &ps : X) {
      dp.add(min(N, n + ps.first), min(N, n + ps.second + 1), dp.get(n));
    }
  }
  cout << dp.get(N - 1) << endl;

  return 0;
}

Measured memory_bytes: 9160