#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define ALL(v) (v).begin(), (v).end()
using ll = long long;
constexpr int INF = 1e9;
constexpr long long LINF = 1e18;
constexpr long long MOD = 998244353;

template <int MOD = 1000000007>
struct Mint {
    int x;

    Mint() : x(0) {}
    Mint(long long t) {
        x = t % MOD;
        if (x < 0) x += MOD;
    }

    Mint pow(int n) {
        Mint res(1), t(x);
        while (n > 0) {
            if (n & 1) res *= t;
            t *= t;
            n >>= 1;
        }
        return res;
    }

    Mint inv() const {
        int a = x, b = MOD, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            a -= t * b;
            swap(a, b);
            u -= t * v;
            swap(u, v);
        }
        return Mint(u);
    }

    Mint &operator+=(Mint a) {
        x += a.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }

    Mint &operator-=(Mint a) {
        x += MOD - a.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }

    Mint &operator*=(Mint a) {
        x = int(1LL * x * a.x % MOD);
        return *this;
    }

    Mint &operator/=(Mint a) {
        return (*this) *= a.inv();
    }

    Mint operator+(Mint a) const {
        return Mint(x) += a;
    }
    Mint operator-(Mint a) const {
        return Mint(x) -= a;
    }
    Mint operator*(Mint a) const {
        return Mint(x) *= a;
    }
    Mint operator/(Mint a) const {
        return Mint(x) /= a;
    }

    Mint operator-() const {
        return Mint(-x);
    }

    bool operator==(const Mint a) {
        return x == a.x;
    }
    bool operator!=(const Mint a) {
        return x != a.x;
    }
    bool operator<(const Mint a) {
        return x < a.x;
    }

    friend ostream &operator<<(ostream &os, const Mint &a) {
        return os << a.x;
    }

    friend istream &operator>>(istream &is, Mint &a) {
        int t;
        is >> t;
        a = Mint<MOD>(t);
        return (is);
    }
};

template <typename Operator>
struct LazySegmentTree {
    using NodeType = typename Operator::NodeType;
    using LazyType = typename Operator::LazyType;
    int n;
    int length;
    int height;
    vector<NodeType> node;
    vector<LazyType> lazy;
    vector<pair<int, int>> range;

    void propagate(int k) {
        if (lazy[k] == Operator::unitlazy) return;
        node[k] = Operator::funcMerge(node[k], lazy[k],
                                      range[k].second - range[k].first);
        if (k < length)
            lazy[2 * k + 0] = Operator::funcLazy(lazy[2 * k + 0], lazy[k]);
        if (k < length)
            lazy[2 * k + 1] = Operator::funcLazy(lazy[2 * k + 1], lazy[k]);
        lazy[k] = Operator::unitlazy;
    }

    LazySegmentTree(const int n) : n(n) {
        length = 1;
        height = 0;
        while (length < n) length *= 2, height++;
        node.resize(2 * length, Operator::unitnode);
        lazy.resize(2 * length, Operator::unitlazy);
        range.resize(2 * length);
        for (int i = length - 1; i >= 0; i--)
            node[i] =
                Operator::funcNode(node[(i << 1) + 0], node[(i << 1) + 1]);
        for (int i = 0; i < length; i++)
            range[i + length] = make_pair(i, i + 1);
        for (int i = length - 1; i >= 0; --i)
            range[i] = make_pair(range[(i << 1) + 0].first,
                                 range[(i << 1) + 1].second);
    }

    LazySegmentTree(const int n, const NodeType init) : n(n) {
        length = 1;
        height = 0;
        while (length < n) length *= 2, height++;
        node.resize(2 * length, Operator::unitnode);
        lazy.resize(2 * length, Operator::unitlazy);
        range.resize(2 * length);
        for (int i = 0; i < n; i++) node[i + length] = init;
        for (int i = length - 1; i >= 0; i--)
            node[i] =
                Operator::funcNode(node[(i << 1) + 0], node[(i << 1) + 1]);
        for (int i = 0; i < length; i++)
            range[i + length] = make_pair(i, i + 1);
        for (int i = length - 1; i >= 0; --i)
            range[i] = make_pair(range[(i << 1) + 0].first,
                                 range[(i << 1) + 1].second);
    }

    LazySegmentTree(const vector<NodeType>& vec) : n(vec.size()) {
        length = 1;
        height = 0;
        while (length < n) length *= 2, height++;
        node.resize(2 * length, Operator::unitnode);
        lazy.resize(2 * length, Operator::unitlazy);
        range.resize(2 * length);
        for (int i = 0; i < vec.size(); i++) node[i + length] = vec[i];
        for (int i = length - 1; i >= 0; i--)
            node[i] =
                Operator::funcNode(node[(i << 1) + 0], node[(i << 1) + 1]);
        for (int i = 0; i < length; i++)
            range[i + length] = make_pair(i, i + 1);
        for (int i = length - 1; i >= 0; --i)
            range[i] = make_pair(range[(i << 1) + 0].first,
                                 range[(i << 1) + 1].second);
    }

    // update[a,b)
    void update(int a, int b, LazyType x) {
        int l = a + length, r = b + length - 1;
        for (int i = height; 0 < i; --i) propagate(l >> i), propagate(r >> i);
        for (r++; l < r; l >>= 1, r >>= 1) {
            if (l & 1)
                lazy[l] = Operator::funcLazy(lazy[l], x), propagate(l), l++;
            if (r & 1)
                --r, lazy[r] = Operator::funcLazy(lazy[r], x), propagate(r);
        }
        l = a + length, r = b + length - 1;
        while ((l >>= 1), (r >>= 1), l) {
            if (lazy[l] == Operator::unitlazy)
                node[l] = Operator::funcNode(
                    Operator::funcMerge(
                        node[(l << 1) + 0], lazy[(l << 1) + 0],
                        range[(l << 1) + 0].second - range[(l << 1) + 0].first),
                    Operator::funcMerge(node[(l << 1) + 1], lazy[(l << 1) + 1],
                                        range[(l << 1) + 1].second -
                                            range[(l << 1) + 1].first));
            if (lazy[r] == Operator::unitlazy)
                node[r] = Operator::funcNode(
                    Operator::funcMerge(
                        node[(r << 1) + 0], lazy[(r << 1) + 0],
                        range[(r << 1) + 0].second - range[(r << 1) + 0].first),
                    Operator::funcMerge(node[(r << 1) + 1], lazy[(r << 1) + 1],
                                        range[(r << 1) + 1].second -
                                            range[(r << 1) + 1].first));
        }
    }

    // get [a,b)
    NodeType get(int a, int b) {
        int l = a + length, r = b + length - 1;
        for (int i = height; 0 < i; --i) propagate(l >> i), propagate(r >> i);
        NodeType vl = Operator::unitnode, vr = Operator::unitnode;
        for (r++; l < r; l >>= 1, r >>= 1) {
            if (l & 1)
                vl = Operator::funcNode(
                    vl, Operator::funcMerge(node[l], lazy[l],
                                            range[l].second - range[l].first)),
                l++;
            if (r & 1)
                r--, vr = Operator::funcNode(
                         Operator::funcMerge(node[r], lazy[r],
                                             range[r].second - range[r].first),
                         vr);
        }
        return Operator::funcNode(vl, vr);
    }

    void print() {
        for (int i = 0; i < n; i++) cout << get(i, i + 1) << " ";
        cout << endl;
    }
};

template <typename T, typename U>
struct RangeMinRangeAdd {
    using NodeType = T;
    using LazyType = U;
    static constexpr NodeType unitnode = 1e9;
    static constexpr LazyType unitlazy = 0;
    static constexpr NodeType funcNode(NodeType l, NodeType r) {
        return min(l, r);
    }
    static constexpr LazyType funcLazy(LazyType l, LazyType r) {
        return l + r;
    }
    static constexpr NodeType funcMerge(NodeType l, LazyType r, int len) {
        return l + r;
    }
};

/*
    unitlazyは更新され得ない値にする必要がある
*/
template <typename T, typename U>
struct RangeSumRangeUpdate {
    using NodeType = T;
    using LazyType = U;
    static constexpr NodeType unitnode = 0;
    static constexpr LazyType unitlazy = -1e9 - 1;
    static constexpr NodeType funcNode(NodeType l, NodeType r) {
        return l + r;
    }
    static constexpr LazyType funcLazy(LazyType l, LazyType r) {
        return r;
    }
    static constexpr NodeType funcMerge(NodeType l, LazyType r, int len) {
        return r != -1e9 - 1 ? r * len : l;
    }
};

template <typename T, typename U>
struct RangeSumRangeAdd {
    using NodeType = T;
    using LazyType = U;
    static constexpr NodeType unitnode = T(0);
    static constexpr LazyType unitlazy = U(0);
    static constexpr NodeType funcNode(NodeType l, LazyType r) {
        return (l + r) % MOD;
    }
    static constexpr LazyType funcLazy(LazyType l, LazyType r) {
        return (l + r) % MOD;
    }
    static constexpr NodeType funcMerge(NodeType l, LazyType r, int len) {
        return (l + (r * len) % MOD) % MOD;
    }
};

signed main() {
    int n, k;
    cin >> n >> k;
    int l[k], r[k];
    rep(i, k) {
        cin >> l[i] >> r[i];
    }
    LazySegmentTree<RangeSumRangeAdd<ll, ll>> dp(n + 2);
    dp.update(1, 2, 1);
    for (int i = 0; i < n; i++){
        rep(j, k) {
            dp.update(min(n + 1, i + l[j]), min(n + 2, i + r[j] + 1), dp.get(i, i + 1));
        }
    }
    cout << dp.get(n, n + 1) << endl;
    return 0;
}

Measured memory_bytes: 15664