#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;
typedef long long ll;
#define rep(i, n) for(ll i = 0, i##_len = (n); i < i##_len; i++)
#define reps(i, s, n) for(ll i = (s), i##_len = (n); i < i##_len; i++)
#define rrep(i, n) for(ll i = (n) - 1; i >= 0; i--)
#define rreps(i, e, n) for(ll i = (n) - 1; i >= (e); i--)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) ((ll)(x).size())
#define len(x) ((ll)(x).length())
#define endl "\n"
template<class T> void chmax(T &a, const T b){ a = max(a, b); }
template<class T> void chmin(T &a, const T b){ a = min(a, b); }

template<class T, class E>
struct LazySegmentTree {
private:
    int n;
    vector<T> node;
    vector<E> lazy;
    vector<bool> updated;
    T def;
    function<T(T,T)> out;
    function<T(T,E,int)> app;
    function<E(E,E)> lop;
    
    void propagate(int k, E x) {
        if (updated[k]) {
            lazy[k] = lop(lazy[k], x);
        }
        else {
            lazy[k] = x;
            updated[k] = true;
        }
    }
    
    void evaluate(int k, int l, int r) {
        if (updated[k]) {
            node[k] = app(node[k], lazy[k], r - l);
            if ((r - l) > 1) {
                propagate(k * 2 + 1, lazy[k]);
                propagate(k * 2 + 2, lazy[k]);
            }
            updated[k] = false;
        }
    }
    
public:
    LazySegmentTree() {}
    LazySegmentTree(const vector<T> &v, T _def, function<E(E,E)> _lop, function<T(T,E,int)> _app, function<T(T,T)> _out) {
        def = _def; out = _out; app = _app; lop = _lop;
        int vl = (int)v.size();
        n = 1; while(n < vl) n *= 2;
        node.resize(2 * n - 1, def);
        lazy.resize(2 * n - 1);
        updated.resize(2 * n - 1, false);
        for(int i = 0; i < vl; i++) node[i + n - 1] = v[i];
        for(int i = n - 2; i >= 0; i--) node[i] = out(node[i * 2 + 1], node[i * 2 + 2]);
    }
    
    void update(int a, int b, E x, int k = 0, int l = 0, int r = -1) {
        if (r < 0) r = n;
        evaluate(k, l, r);
        if((b <= l) || (r <= a)) return;
        if((a <= l) && (r <= b)) {
            propagate(k, x);
            evaluate(k, l, r);
        }
        else {
            update(a, b, x, 2 * k + 1, l, (l + r) / 2);
            update(a, b, x, 2 * k + 2, (l + r) / 2, r);
            node[k] = out(node[2 * k + 1], node[2 * k + 2]);
        }
    }
    
    T query(int a, int b, int k = 0, int l = 0, int r = -1) {
        if (r < 0) r = n;
        evaluate(k, l, r);
        if ((b <= l) || (r <= a)) return def;
        if ((a <= l) && (r <= b)) return node[k];
        T vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
        T vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
        return out(vl, vr);
    }
};

struct mint {
    constexpr static int mod = 998244353;
    long long x;
    mint(long long x = 0) : x((x % mod + mod) % mod) {}
    mint operator-() const { return mint(-x); }
    mint& operator+=(const mint a) {
        if ((x += a.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator-=(const mint a) {
        if ((x += mod - a.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this; }
    mint operator+(const mint a) const { return mint(*this) += a; }
    mint operator-(const mint a) const { return mint(*this) -= a; }
    mint operator*(const mint a) const { return mint(*this) *= a; }
    mint pow(long long t) const {
        if (!t) return 1;
        mint a = pow(t >> 1);
        a *= a;
        if (t & 1) a *= *this;
        return a;
    }
    mint inv() const { return pow(mod - 2); }
    mint& operator/=(const mint a) { return *this *= a.inv(); }
    mint operator/(const mint a) const { return mint(*this) /= a; }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    // ifstream in("input.txt");
    // cin.rdbuf(in.rdbuf());
    ll n, k;
    cin >> n >> k;
    vector<pair<ll, ll>> lr(k);
    rep(i, k) cin >> lr[i].first >> lr[i].second;
    auto lop = [](mint a, mint b){ return a + b; };
    auto app = [](mint a, mint b, mint c){ return a + b * c; };
    auto out = [](mint a, mint b){ return a + b; };
    LazySegmentTree<mint, mint> lst(vector<mint>(n, 0), 0, lop, app, out);
    lst.update(0, 1, 1);
    rep(i, n) {
        mint v = lst.query(i, i + 1);
        rep(j, k) {
            ll l = i + lr[j].first;
            ll r = min(n, i + lr[j].second + 1);
            if (l >= n) continue;
            lst.update(l, r, v);
        }
    }
    cout << lst.query(n - 1, n).x << endl;
    return 0;
}


Measured memory_bytes: 12968