#if loc||local
#define _GLIBCXX_DEBUG
#endif

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

#define rep(i,n) for(ll i=0;i<ll(n);++i)
#define repr(i,n) for(ll i=ll(n);i-->0;)
using ll = int_fast64_t;
using pll = pair<ll,ll>;
constexpr ll INF = 1LL<<60;
constexpr ll MOD = 1e9+7;
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(a>b){a=b;return 1;}return 0;}
#if loc||local
template<class T>void dump(T&& t){cerr<<t<<endl;}
template<class T,class... Ts> void dump(T&& h, Ts&&... t){cerr<<h<<", ";dump(forward<Ts>(t)...);}
#else
void dump(){}
template<class T,class... Ts> void dump(T&& h, Ts&&... t){}
#endif
template<class T> istream &operator>>(istream&is,vector<T>&v){for(auto &elemnt:v)is>>elemnt;return is;}
template<class T,class U> istream &operator>>(istream&is,pair<T,U>&p){is>>p.first>>p.second;return is;}
template<class T> ostream &operator<<(ostream& os,vector<T>const& v){for(auto const& vi:v)os<<vi<<" ";return os;}
template<class T,class U> ostream &operator<<(ostream& os,pair<T,U>const& p){os<<p.first<<","<<p.second;return os;}
template<class T>vector<T> vec(size_t a){return vector<T>(a);}
template<class T, class... Ts>auto vec(size_t a, Ts... ts){return vector<decltype(vec<T>(ts...))>(a, vec<T>(ts...));}

template<class T,class F>
struct segment_tree{
  std::vector<T> data;
  int n;F f;T identity;
  segment_tree(){}
  segment_tree(int sz,T ide,F _f):f(_f),identity(ide){
    n=1;while(n<sz)n<<=1;
    data.resize(2*n,identity);
  }
  segment_tree(std::vector<T> const& v,T ide,F _f):f(_f),identity(ide){
    build(v);
  }
  void build(std::vector<T> const& v){
    int sz=v.size();
    n=1;while(n<sz)n<<=1;
    data.resize(2*n,identity);
    for(int i=0;i<sz;++i)data[i+n]=v[i];
    for(int i=n-1;i>0;--i)data[i]=f(data[i<<1|0],data[i<<1|1]);
  }
  void set(int i,T x){
    i+=n;data[i]=x;
    while(i,i>>=1)data[i]=f(data[i<<1|0],data[i<<1|1]);
  }
  T fold(int l,int r)const{
    l+=n,r+=n;
    T fold_l=identity,fold_r=identity;
    while(l<r){
      if(l&1)fold_l=f(fold_l,data[l++]);
      if(r&1)fold_r=f(data[--r],fold_r);
      l>>=1,r>>=1;
    }
    return f(fold_l,fold_r);
  }
  T operator[](int i)const{return data[i+n];}
  template<class Cond>int bserch(int l,Cond& cond){
    l+=n;T x=identity;
    do{
      while(!l&1)l>>=1;if(cond(f(x,data[l]))){
        while(l<n){l<<=1;if(!cond(f(x,data[l])))x=f(x,data[l++]);}
        return l-n;
      }x=f(x,data[l++]);
    }while((l&-l)!=l);
    return -1;
  }
};
template<class T,class F>
auto make_segtree(int n,T ide,F f){
  return segment_tree<T,F>(n,ide,f);
}
template<class T,class F>
auto make_segtree(std::vector<T>const& v,T ide,F f){
  return segment_tree<T,F>(v,ide,f);
}
struct union_find{
  size_t n;
  std::vector<int> par;
  size_t group;
  union_find(){}
  union_find(size_t _n):n(_n),group(_n){
    par.resize(n,-1);
  }
  void reset(size_t _n){
    n = _n;
    group = n;
    par.clear();
    par.resize(n,-1);
  }
  int root(int k){
    if(par[k]<0)return k;
    return par[k] = root(par[k]);
  }
  int size(int k){
    k = root(k);
    return -par[k];
  }
  int operator[](int k){
    return size(k);
  }
  bool unite(int a,int b){
    a = root(a);
    b = root(b);
    if(a==b)return false;
    if(size(a)<size(b))std::swap(a,b);
    group--;
    par[a] += par[b];
    par[b] = a;
    return true;
  }
  bool operator()(int a,int b){
    return unite(a,b);
  }
  bool same(int a,int b){
    return root(a) == root(b);
  }
};
namespace ate{
  template<int64_t p>
  struct F_p{
    using value_type = int64_t;
    static constexpr inline value_type get_mod(){return p;}

    value_type value;

    constexpr F_p():value(value_type{}){}
    template<class T>constexpr F_p(T v):value(static_cast<value_type>(v<0?v%p+p:v%p)){}
  // operator +, -, *, /, ^ 
    constexpr F_p operator + (const F_p& other)const{
      return F_p(*this) += other;
    }
    constexpr F_p operator - (const F_p& other)const{
      return F_p(*this) -= other;
    }
    constexpr F_p operator * (const F_p& other)const{
      return F_p(*this) *= other;
    }
    constexpr F_p operator / (const F_p& other)const{
      return F_p(*this) /= other;
    }
    template<class T> constexpr F_p operator ^ (const T other)const{
      return F_p(*this) ^= other;
    }
    constexpr F_p &operator += (const F_p& other){
      value+=other.value;
      if(value>p)value-=p;
      return *this;
    }
    constexpr F_p &operator -= (const F_p& other){
      value-=other.value;
      if(value<0)value+=p;
      return *this;
    }
    constexpr F_p &operator *= (const F_p& other){
      value*=other.value;
      if(value>p)value%=p;
      return *this;
    }
    constexpr F_p &operator /= (const F_p& other){
      value*=other.inverse();
      if(value>p)value%=p;
      return *this;
    }
    template<class T>
    constexpr F_p &operator ^= (const T n){
      value = mpow(n).value;
      return *this;
    }
  // ext_gcd,inverse,mpow 
    static constexpr value_type ext_gcd(value_type a,value_type b,value_type& x,value_type& y){
      if(b==0){x=1,y=0;return a;}
      value_type d=ext_gcd(b,a%b,y,x);
      y-=a/b*x;return d;
    }
    constexpr value_type inverse()const{
      value_type x,y;
      ext_gcd(value,p,x,y);
      return x<0?x%p+p:x%p;
    }
    template<class T>
    static constexpr value_type inverse(T val){
      value_type x,y;
      ext_gcd(val,p,x,y);
      return x<0?x%p+p:x%p;
    }
    template<class T>
    constexpr F_p mpow(T n)const{
      F_p res(1),vn(*this);
      while(n){
        if(n&1)res*=vn;
        vn*=vn;
        n>>=1;
      }
      return res;
    }
    template<class T,class U>
    static constexpr T mpow(T a,U b){
      F_p x(a);
      return static_cast<T>(x.mpow(b).value);
    }
  // operator iostream 
    constexpr friend std::istream &operator >> (std::istream& is,F_p& fp){
      is>>fp.value;
      return is;
    }constexpr friend std::ostream &operator << (std::ostream& os,const F_p& fp){
      os<<fp.value;
      return os;
    }
  //operator bool
    constexpr bool operator == (const F_p& other)const{
      return value == other.value;
    }
  };
}
using mint = ate::F_p<(int)998244353>;

signed main(){

  ll n,k;
  cin>>n>>k;
  vector<pll> sect(k);
  cin>>sect;
  sort(begin(sect),end(sect));

  vector<mint> dp(n+1);
  dp[1] = 1;
  for(int i=1;i<n;++i){
    rep(j,size(sect)){
      auto&[l,r]=sect[j];
      if(i+l>n){
        sect.pop_back();
        break;
      }
      for(int to=i+l;to<=i+r;++to){
        if(to>n){
          r=to;
          break;
        }
        dp[to]+=dp[i];
      }
    }
  }
  cout<<(dp[n])<<endl;


}