//セグ木基本
#include "bits/stdc++.h"
using namespace std;
#define REP(i, n) for(ll i = 0;i < n;i++)
#define ll long long
#define MOD 998244353LL
using vi = vector<ll>;
using vvi = vector<vi>;
const ll llMAX=9223372036854775807LL; 
const ll llMIN=-9223372036854775808LL;

ll n,k;

class SegTree
{
  public:
  ll n2,ln2;//2のべき乗になる数でn以上の数//n2のlog2値
  vector<ll> data;//●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
  vector<int> indexdata;
  SegTree(){}
  void Init(ll inn){
    ln2=ceil(log2(inn));
    n2=1<<ln2;
    data.resize(n2*2);
    indexdata.resize(n2*2);
    for(ll i=0;i<n2*2;i++)
      data[i]=Initval();//●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
    for(int i=0;i<n2;i++)
      indexdata[i+n2]=i;
    
  }
  //配列内初期化●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
  ll Initval(){
    return 0;
  }
  //min関数的な
  //●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
  ll SGTfunc(ll d0,ll d1){
    return d0+d1;
  }
  //データをセットして内部更新 O(logn)
  void Updata(ll posi,ll d)
  {
    ll myi=posi+n2;
    data[myi]=d;//葉
    for(ll i=0;i<ln2;i++){//中間要素
      myi/=2;
      data[myi]=SGTfunc(data[myi*2],data[myi*2+1]);
      if (data[myi*2]==data[myi]){
        indexdata[myi]=indexdata[myi*2];
      }else{
        indexdata[myi]=indexdata[myi*2+1];
      }
    }
  }
  void Delete(ll posi)//1要素削除して初期化
  {
    Updata(posi,Initval());
  }

  //lを含むrを含まないところまでの区間
  ll GetMin(ll l,ll r)
  {
    l=max(l,0LL);
    r=max(r,0LL);
    ll ret=0;//ここは比較するならMAXかMINを、合計するなら0を●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
    ll l_=l;
    ll r_=r;
    for(ll i=0;(l_+r_)>0;i++){
      ll offset=1<<(ln2-i);
      if (r_%2==1){
          if (r_-1>=l_){
            ret=SGTfunc(ret,data[offset+r_-1]);
            r_--;
          }
      }
      if (l_%2==1){
          if (l_<r_){
            ret=SGTfunc(ret,data[offset+l_]);
            l_++;
          }
      }
      r_>>=1;
      l_>>=1;
    }
    return ret;
  }
  ll GetAll()//0～最後の要素まで
  {
    return GetMin(0,n2);
  }
  
  //lを含むrを含まないところまでの区間で_最小_の値をもつindexを返す
  int GetMinIndex(ll l,ll r)
  {
    int retindex=l;
    ll ret=data[l+n2];//ここは比較するならMAXかMINを、合計するなら0を●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
    ll l_=l;
    ll r_=r;
    for(ll i=0;(l_+r_)>0;i++){
      ll offset=1<<(ln2-i);
      if (r_%2==1){
          if (r_-1>=l_){
            ll ret_tmp=SGTfunc(ret,data[offset+r_-1]);
            if (ret!=ret_tmp){
              retindex=indexdata[offset+r_-1];
              ret=ret_tmp;
            }
            r_--;
          }
      }
      if (l_%2==1){
          if (l_<r_){
            ll ret_tmp=SGTfunc(ret,data[offset+l_]);
            if (ret!=ret_tmp){
              retindex=indexdata[offset+l_];
              ret=ret_tmp;
            }
            l_++;
          }
      }
      r_>>=1;
      l_>>=1;
    }
    return retindex;
  }
  int GetAllIndex()//0～最後の要素まで
  {
    return GetMinIndex(0,n2);
  }
};




int main(){
  ll ans=0;
  cin>>n>>k;
  vi R(k),L(k);
  REP(i,k){
    cin>>L[i]>>R[i];
  }
  vi dp(n);
  dp[0]=1;


  SegTree segtree;
  segtree.Init(n);

  segtree.Updata(0,1);

  for(ll i=1;i<n;i++){
    
    for(ll j=0;j<k;j++){
      ll val=segtree.GetMin(i-R[j],i-L[j]+1);
      dp[i]+=val;
    }
    dp[i]=dp[i]%MOD;
    segtree.Updata(i,dp[i]);
  }
  
  cout<<dp[n-1]<<endl;
  return 0;
}

Measured memory_bytes: 11184