#include <bits/stdc++.h>

#ifdef DEBUG
#define PRINT(x)\
    cout<<"func "<<__func__<<": line "<<__LINE__<<": "<<#x<<" = "<<(x)<<endl;
#define PRINTA(a,first,last)\
    cout<<"func "<<__func__<<": line "<<__LINE__<<": "<<#a<<"["<<(first)<<", "<<(last)<<")"<<endl;\
    for (int _i=(first);_i<(last);++_i){cout<<#a<<"["<<_i<<"] = "<<(a)[_i]<<endl;}
#define PRINTI(a,i)\
    cout<<"func "<<__func__<<": line "<<__LINE__<<": "<<#a<<"["<<#i<<"] = "<<#a<<"["<<(i)<<"] = "<<(a)[i]<<endl;
#define dprintf(...) printf(__VA_ARGS__)
#else
#define PRINT(x)
#define PRINTA(a,first,last)
#define PRINTI(a,i)
#define dprintf(...)
#endif

#define FOR(i,a,b) for (int i=(a);i<(b);++i)
#define RFOR(i,a,b) for (int i=(b)-1;i>=(a);--i)
#define REP(i,n) for (int i=0;i<(n);++i)
#define RREP(i,n) for (int i=(n)-1;i>=0;--i)
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define MOD 998244353

using namespace std;

using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;

template <class T, class U> void amax(T& x, U y) {if (x < y) x = y;}
template <class T, class U> void amin(T& x, U y) {if (x > y) x = y;}

template <class T, class U>
std::ostream& operator<<(std::ostream &os, const std::pair<T, U> &p) {
	os << "(" << p.first << ", " << p.second << ")";
	return os;
}
 
template <class T>
std::ostream& operator<<(std::ostream &os, const std::vector<T> &v) {
    os << "[";
	for (int i = 0; i < v.size(); ++i) {
        if (i) {
            if (i % 5 == 0) {
                os << ",\n ";
            } else {
                os << ", ";
            }
        }
		os << v[i];
	}
	os << "]";
	return os;
}

template <class T>
using vec2 = vector<vector<T>>;

template <class T>
using vec3 = vector<vector<vector<T>>>;

template <class T>
vec2<T> vec2_init(int n0, int n1, T x = 0) {
    return vec2<T>(n0, vector<T>(n1, x));
}

template <class T>
vec3<T> vec3_init(int n0, int n1, int n2, T x = 0) {
    return vec3<T>(n0, vec2_init(n1, n2, x));
}

/*
 *           U P
 *           - x
 *            ^
 *            |
 * LEFT -y <--+--> +y RIGHT
 *            |
 *            v
 *           + x
 *         D O W N
 */

const int dx[] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[] = {0, 1, 0, -1, 1, 1, -1, -1};

enum {
    DOWN,
    RIGHT,
    UP,
    LEFT,
};

constexpr double inf = numeric_limits<double>::infinity();

template <class T, T M>
class modulo {
public:
    T data;

    modulo(T data = 0) {
        T r = data % M;
        if (r < 0) {
            r += M;
        }
        this->data = r;
    }

    modulo operator+(const modulo &x) const {
        return modulo(data + x.data);
    }

    modulo operator-(const modulo &x) const {
        return modulo(data + (M - x.data));
    }

    modulo operator*(const modulo &x) const {
        return modulo(data * x.data);
    }

    modulo operator/(const modulo &x) const {
        return modulo(data * x.inv().data);
    }

    modulo operator+=(const modulo &x) {
        return data = (data + x.data) % M;
    }

    modulo operator-=(const modulo &x) {
        return data = (data + (M - x.data)) % M;
    }

    modulo operator*=(const modulo &x) {
        return data = (data * x.data) % M;
    }

    modulo operator/=(const modulo &x) {
        return data = (data * x.inv().data) % M;
    }

    modulo inv() const {
        return _pow(M - 2);
    }

    template <class Integer>
    modulo operator^(Integer n) const {
        if (n >= 0) {
            return _pow(n);
        } else {
            return _pow(M - 1 - (-n) % (M - 1));
        }
    }

    friend std::ostream& operator<<(std::ostream &os, const modulo &x) {
        os << x.data;
        return os;
    }

private:
    template <class NonNegativeInteger>
    modulo _pow(NonNegativeInteger n) const {
        modulo result(1);
        modulo x(*this);
        while (n) {
            if (n & 1) {
                result *= x;
            }
            x *= x;
            n >>= 1;
        }
        return result;
    }
};

template <class T, T M>
struct combinatorics {

    using Mod = modulo<T, M>;

    T N;
    std::vector<Mod> factorial;
    std::vector<Mod> inv_factorial;

    combinatorics(T N) : N(N), factorial(N + 1), inv_factorial(N + 1) {
        factorial[0] = 1;
        for (T i = 1; i <= N; ++i) {
            factorial[i] = factorial[i - 1] * i;
        }
        inv_factorial[N] = factorial[N].inv();
        for (T i = N; i >= 1; --i) {
            inv_factorial[i - 1] = inv_factorial[i] * i;
        }
    }

    Mod P(T n, T k) {
        if (0 <= k && k <= n) {
            return factorial[n] * inv_factorial[n - k];
        } else {
            return 0;
        }
    }

    Mod C(T n, T k) {
        if (0 <= k && k <= n) {
            return factorial[n] * inv_factorial[k] * inv_factorial[n - k];
        } else {
            return 0;
        }
    }

    Mod H(T n, T k) {
        if (n == 0 && k == 0) {
            return 1;
        } else {
            return C(n + k - 1, k);
        }
    }
};

unsigned long long clp(unsigned long long x) {
    x -= 1;
    x = x | (x >>  1);
    x = x | (x >>  2);
    x = x | (x >>  4);
    x = x | (x >>  8);
    x = x | (x >> 16);
    x = x | (x >> 32);
    return x + 1;
}

// a[0], a[1], ... , a[n - 1] is a given array of length n.
// T is the type of elements of array a.
// UNIT is a element such that for any element x, f(x, UNIT) == x.
// e.g. f(x, y) = sum(x, y), UNIT = 0.
// e.g. f(x, y) = min(x, y), UNIT = INFINITY.
template <class T>
class segment_tree {
private:
    const size_t n;
    const std::function<T(const T&, const T&)> f;
    const T UNIT;
    std::vector<T> a;
public:
    segment_tree(size_t size, std::function<T(const T&, const T&)> f, T UNIT) : n(clp(size)), UNIT(UNIT), f(f) {
        a.resize(2 * n - 1, UNIT);
    }

    template <class Iterator>
    segment_tree(Iterator first, Iterator last, std::function<T(const T&, const T&)> f, T UNIT) : n(clp(std::distance(first, last))), f(f), UNIT(UNIT) {
        size_t size = std::distance(first, last);
        a.resize(2 * n - 1, UNIT);
        for (size_t i = n - 1; first != last; ++i) {
            a[i] = *(first++);
        }
        for (int i = n - 2; i >= 0; --i) {
            a[i] = f(a[2 * i + 1], a[2 * i + 2]);
        }
    }

    void update(size_t i, const T &x) {
        i += n - 1;
        a[i] = x;
        while (i) {
            i = (i - 1) / 2;
            a[i] = f(a[2 * i + 1], a[2 * i + 2]);
        }
    }

    T query(size_t query_first, size_t query_last, size_t k = 0, size_t node_first = 0, size_t node_last = 0) const {
        if (k == 0) {
            node_last = n;
        }
        if (node_last <= query_first || query_last <= node_first) {
            return UNIT;
        }
        if (query_first <= node_first && node_last <= query_last) {
            return a[k];
        } else {
            size_t node_mid = (node_first + node_last) / 2;
            T vl = query(query_first, query_last, k * 2 + 1, node_first, node_mid);
            T vr = query(query_first, query_last, k * 2 + 2, node_mid, node_last);
            return f(vl, vr);
        }
    }
};

template<class T>
class fenwick_tree {
private:
    const size_t size;
    const std::function<T(T, T)> f;
    const T unit;
    std::vector<T> a;
public:
    fenwick_tree(size_t size, std::function<T(T, T)> f, T unit) : size(size), f(f), unit(unit), a(size, unit) { }

    void update(size_t i, T x) {
        for (size_t j = i; j < size; j |= j + 1) {
            a[j] = f(a[j], x);
        }
    }

    T query(size_t i) const {
        T result = unit;
        for (size_t j = i; j > 0; j = (j & (j + 1))) {
            result = f(result, a[--j]);
        }
        return result;
    }
};

using Mod = modulo<ll, MOD>;

template <class T>
class range_add_sum_query {
private:
    fenwick_tree<T> fenwick_1;
    fenwick_tree<T> fenwick_2;
public:
    range_add_sum_query(size_t n) : fenwick_1(n + 1, [](T x, T y) { return Mod(x + y).data; }, 0),
                                    fenwick_2(n + 1, [](T x, T y) { return Mod(x + y).data; }, 0) { }

    void update(size_t first, size_t last, T x) {
        fenwick_1.update(first, Mod(x).data);
        fenwick_1.update(last, Mod(-x).data);
        fenwick_2.update(first, Mod(first * x).data);
        fenwick_2.update(last, Mod(-last * x).data);
    }

    T query(size_t last) const {
        return (Mod(fenwick_1.query(last) * last) - Mod(fenwick_2.query(last))).data;
    }

    T query(size_t first, size_t last) const {
        return Mod(query(last) - query(first)).data;
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int N, K;
    cin >> N >> K;
    vector<int> L(K), R(K);
    REP(i, K) {
        cin >> L[i] >> R[i];
        //--L[i];
        ++R[i];
    }
    //segment_tree<Mod> st(N, [](Mod x, Mod y) { reutnr
    range_add_sum_query<ll> rasq(N);
    rasq.update(0, 1, 1);
    REP(i, N) {
        ll x = rasq.query(i, i + 1);
        PRINT(x);
        REP(j, K) {
            int l = min(N, i + L[j]);
            int r = min(N, i + R[j]);
            PRINT(l);
            PRINT(r);
            rasq.update(l, r, x);
        }
    }
    ll result = rasq.query(N - 1, N);
    cout << result << endl;

    return 0;
}


Measured memory_bytes: 6376