#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;

#define LEN(x) (int)x.size()
#define ALL(x) x.begin(), x.end()

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int,int>;
using vpii = vector<pii>;

template<typename T, typename M = __gnu_pbds::null_type>
using ordered_set = __gnu_pbds::tree<T, M, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;

template<typename T>
const T INF = (is_same<T, int>::value ? 1e9 : 1e18);
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

inline int fcmp(double x, double y)
{ return (x < y + EPS ? (x < y - EPS ? -1 : 0) : 1);}

template<class base_t>
base_t inverse(base_t a, base_t m)
{
    base_t x = 0, y = 1;
    while(a > 0)
    {
        base_t t = m / a;
        m -= t * a; swap(a, m);
        x -= t * y; swap(x, y);
    }
    assert(m == 1);
    return x;
}

template<class base_t>
struct modular
{
    using mod_t = modular<base_t>;
    base_t val;
    static base_t mod;

    template<class T>
    inline base_t normalize(T n)
    {
        if(n >= mod || n < -mod)
            n = (T)(n % mod);
        if(n < 0)
            n = (T)(n + mod);
        return (base_t)n;
    }

    modular(){ val = 0;}
    template<class T> modular(T x = 0) { val = normalize(x);}
    template<class T> explicit operator T() { return static_cast<T>(val);}
    const base_t operator ()() const { return val;}

    mod_t operator + (const mod_t& o)
    {
        base_t a = val + o(); if(a >= mod) a -= mod; return mod_t(a);
    }
    mod_t operator - (const mod_t& o)
    {
        base_t a = val - o(); if(a < 0) a += mod; return mod_t(a);
    }
    mod_t operator * (const mod_t& o)
    {
        if(is_same<base_t, int>::value)
            return normalize((ll)val * (ll)o());
        if(is_same<base_t, ll>::value)
        {
            ll x = (ll)((long double)val * o() / mod);
            ll y = (ll)((long double)val * o() - x * mod);
            return y;
        }
        assert(true);
    }
    mod_t operator / (const mod_t& o) { return *this * inverse(o(), mod);}

    mod_t& operator += (const mod_t& o) { return *this = *this + o;}
    mod_t& operator -= (const mod_t& o)	{ return *this = *this - o;}
    mod_t& operator *= (const mod_t& o)	{ return *this = *this * o;}
    mod_t& operator /= (const mod_t& o)	{ return *this = *this / o;}

    template<class T>
    mod_t& operator += (const T& o) { return *this = *this + mod_t(o);}
    template<class T>
    mod_t& operator -= (const T& o) { return *this = *this - mod_t(o);}
    template<class T>
    mod_t& operator *= (const T& o) { return *this = *this * mod_t(o);}
    template<class T>
    mod_t& operator /= (const T& o) { return *this = *this / mod_t(o);}
    
    mod_t& operator ++ () { return *this += 1;}
    mod_t& operator -- () { return *this -= 1;}
    mod_t operator ++ (int) { mod_t old(val); *this += 1; return old;}
    mod_t operator -- (int) { mod_t old(val); *this -= 1; return old;}

    bool operator == (const mod_t& o) { return val == o();}
    bool operator != (const mod_t& o) { return val != o();}
    bool operator < (const mod_t& o) { return val < o();}
    bool operator > (const mod_t& o) { return val > o();}
    bool operator <= (const mod_t& o) { return val <= o();}
    bool operator >= (const mod_t& o) { return val >= o();}

    friend istream& operator >> (istream& in, mod_t& o)
    {
        ll x; in >> x; o = mod_t(x); return in;
    }

    friend ostream& operator << (ostream& out, const mod_t& o)
    {
        out << o(); return out;
    }
};

template<class T, class base_t>
modular<base_t> operator + (T a, const modular<base_t>& b) { return modular<base_t>(a) + b;}
template<class T, class base_t>
modular<base_t> operator - (T a, const modular<base_t>& b) { return modular<base_t>(a) - b;}
template<class T, class base_t>
modular<base_t> operator * (T a, const modular<base_t>& b) { return modular<base_t>(a) * b;}
template<class T, class base_t>
modular<base_t> operator / (T a, const modular<base_t>& b) { return modular<base_t>(a) / b;}

template<class T, class base_t>
bool operator == (T a, const modular<base_t>& b) { return a == b();}
template<class T, class base_t>
bool operator != (T a, const modular<base_t>& b) { return a != b();}
template<class T, class base_t>
bool operator < (T a, const modular<base_t>& b) { return a < b();}
template<class T, class base_t>
bool operator <= (T a, const modular<base_t>& b) { return a <= b();}
template<class T, class base_t>
bool operator > (T a, const modular<base_t>& b) { return a > b();}
template<class T, class base_t>
bool operator >= (T a, const modular<base_t>& b) { return a >= b();}

// template<class T>
// T& md = modular<T>::mod;

template<class T>
T modular<T>::mod(998244353);

struct node
{
    bool dirty = false;

    modular<int> val = 0, lazy = 0;

    node(){}

    template<class base_t>
    node(const base_t& x)
    {
        val = x;
    }

    node(const node& l, const node& r)
    {
        val = l.val + r.val;
    }

    node& operator += (const node& p)
    {
        lazy += p.lazy;
        dirty = true;
        return *this;
    }

    void apply()
    {
        val += lazy;
        lazy = 0;
        dirty = false;
    }
};

template<class node_t>
class segtree
{
private:
    inline int left(int root){ return 2 * root;}
    inline int right(int root){ return 2 * root + 1;}

    vector<node_t> t;
    int n;

    template<class base_t>
    void build(int root, int l, int r, const vector<base_t>& v)
    {
        if(l == r)
        {
            t[root] = node_t(v[l]);
            return;
        }

        int mid = (l + r) / 2;
        build(left(root), l, mid, v);
        build(right(root), mid + 1, r, v);
        t[root] = node_t(t[left(root)], t[right(root)]);
    }

    void build(int root, int l, int r)
    {
        if(l == r)
        {
            t[root] = node_t(0);
            return;
        }

        int mid = (l + r) / 2;
        build(left(root), l, mid);
        build(right(root), mid + 1, r);
        t[root] = node_t(t[left(root)], t[right(root)]);
    }
        
    node_t query(int root, int l, int r, int ql, int qr)
    {
        if(l > qr || r < ql)
            return node_t();
    
        push(root, l, r);

        if(l >= ql && r <= qr)
            return t[root];
        
        int mid = (l + r) / 2;
        node_t a = query(left(root), l, mid, ql, qr);
        node_t b = query(right(root), mid + 1, r, ql, qr);
        return node_t(a, b);
    }
    
    void update(int root, int l, int r, int ql, int qr, const node_t& v)
    {
        push(root, l, r);

        if(l > qr || r < ql) return;

        if(l >= ql && r <= qr)
        {
            t[root] += v;
            push(root, l, r);
            return;
        }
        
        int mid = (l + r) / 2;
        update(left(root), l, mid, ql, qr, v);
        update(right(root), mid + 1, r, ql, qr, v);
        t[root] = node_t(t[left(root)], t[right(root)]);
    }

    inline void push(int root, int l, int r)
    {
        if(t[root].dirty)
        {
            if(l != r)
            {
                t[left(root)] += t[root];
                t[right(root)] += t[root];
            }
            t[root].apply();
        }
    }

public:
    segtree(int _n = 1) : n(_n)
    {
        t.resize(4 * n);
        build(1, 0, n - 1);
    }

    template<class base_t>
    segtree(const vector<base_t>& v) : n(LEN(v))
    {
        t.resize(4 * n);
        build(1, 0, n - 1, v);
    }

    void update(int l, int r, const node_t& v)
    {
        update(1, 0, n - 1, l, r, v);
    }

    void update(int p, const node_t& v)
    {
        update(1, 0, n - 1, p, p, v);
    }

    node_t query(int l, int r)
    {
        return query(1, 0, n - 1, l, r);
    }
    
    node_t query(int p)
    {
        return query(1, 0, n - 1, p, p);
    }
};

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.precision(10);
    
    int n, k;
    cin >> n >> k;
    vpii s(k);
    for(auto& [x, y] : s) cin >> x >> y;
    segtree<node> seg(n);
    node up;
    up.lazy = 1;
    seg.update(0, up);
    for(int i = 1; i < n; i++)
    {
        up.lazy = 0;
        for(auto [l, r] : s)
            up.lazy += seg.query(i - r, i - l).val;
        seg.update(i, up);
    }
    cout << seg.query(n - 1).val << endl;

    return 0;
}

Measured memory_bytes: 12664