#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <iterator>
#include <cassert>
#include <numeric>
#include <functional>
#include <time.h>

#pragma warning(disable:4996) 

typedef long long ll;
typedef unsigned long long ull;
#define MIN(a, b) ((a)>(b)? (b): (a))
#define MAX(a, b) ((a)<(b)? (b): (a))
#define LINF  9223300000000000000
#define LINF2 1223300000000000000
#define LINF3 1000000000000
#define INF 2140000000
//const long long MOD = 1000000007;
const long long MOD = 998244353;

using namespace std;


const long long INF2 = (((ll)1 << 31) - 1);

template<class T> class SegTree   // 0-indexed
{
private:
    int n;             // 葉の数
    vector<T> data;    // ノードの値を持つ配列
    vector<T> lazy;    // 遅延評価を持つ配列

    T def;                // 初期値かつ単位元

    T operation(T a, T b)    // 区間クエリで使う処理
    {
        //return min(a, b);   // 区間minクエリ
        return (a + b)%MOD;           // 区間和クエリ
    }

    T update(T a, T b)      // 点更新で使う処理
    {
        //return a+b;   // 加算の場合
        return b;       // 更新の場合
    }

    void eval(int k, int l, int r)   // ノードkについて遅延評価を行う
    {
        if (lazy[k] != 0) {
            data[k] += lazy[k];
            if (r - l > 1) {
                lazy[2 * k + 1] += lazy[k] / 2;
                lazy[2 * k + 2] += lazy[k] / 2;
            }
            lazy[k] = 0;
        }
        return;
    }

    void _add(int a, int b, T x, int k, int l, int r) {
        if (r < 0) r = n;
        eval(k, l, r);   // k 番目のノードに対して遅延評価を行う

        if (b <= l || r <= a) return;   // 範囲外なら何もしない

        // 完全に被覆しているならば、遅延配列に値を入れた後に評価
        if (a <= l && r <= b) {
            lazy[k] += (r - l) * x;
            eval(k, l, r);
        }

        // そうでないならば、子ノードの値を再帰的に計算して、
        // 計算済みの値をもらってくる
        else {
            _add(a, b, x, 2 * k + 1, l, (l + r) / 2);
            _add(a, b, x, 2 * k + 2, (l + r) / 2, r);
            data[k] = data[2 * k + 1] + data[2 * k + 2];
        }
    }

    // 区間[a,b)の総和。ノードk=[l,r)に着目している。
    T _query(int a, int b, int k, int l, int r) {
        if (r <= a || b <= l) return def; // 交差しない

        eval(k, l, r);
        if (a <= l && r <= b)
            return data[k]; // a,l,r,bの順で完全に含まれる
        else {
            T c1 = _query(a, b, 2 * k + 1, l, (l + r) / 2); // 左の子
            T c2 = _query(a, b, 2 * k + 2, (l + r) / 2, r); // 右の子
            return operation(c1, c2);
        }
    }

public:
    SegTree(int _n) {     // _n:必要サイズ
        //def = INF2;        // 初期値かつ単位元（minのときINF2)
        def = 0;             // 初期値かつ単位元（和のとき0)
        n = 1;
        while (n < _n) n *= 2;
        data = vector<T>(2 * n - 1, def);
        lazy = vector<T>(2 * n - 1, 0);
    }

    // 場所i(0-indexed)の値をxで更新
    void change(int i, T x) {
        i += n - 1;
        data[i] = update(data[i], x);
        while (i > 0) {
            i = (i - 1) / 2;
            data[i] = operation(data[i * 2 + 1], data[i * 2 + 2]);
        }
    }

    // 区間更新
    void add(int a, int b, T x) {
        return _add(a, b, x, 0, 0, n);
    }

    // [a, b)の区間クエリを実行
    T query(int a, int b) {
        return _query(a, b, 0, 0, n);
    }

    // 添字でアクセス
    T operator[](int i) {
        return data[i + n - 1];
    }
};

void solve()
{
    int n, K;
    scanf("%d%d", &n, &K);
    vector<int> l(K), r(K);
    int i, j;
    for (i = 0; i < K; i++) {
        scanf("%d%d", &l[i], &r[i]); 
    }
    SegTree<ll> S(n);
    S.add(0, 1, 1);
    for (i = 0; i < n-1; i++) {
#ifdef _ADEBUG
        {
            int k;
            for (k = 0; k < n; k++) {
                printf("[%d]%lld", k, S.query(k, k + 1));
            }
            printf("\n");
        }
#endif
        ll val = S.query(i, i+1);
        for (j = 0; j < K; j++) {
            int tmp0 = i + l[j];
            if (tmp0 > n - 1) continue;
            int tmp1 = MIN(i + r[j], n-1);
            S.add(tmp0, tmp1+1, val);
        }
    }

    {
        ll val = S.query(n - 1, n);
        printf("%lld\n", val);
    }
    return;
}

int main()
{
#if 1
    solve();
#else
    int T;
    scanf("%d", &T);
    int t;
    for (t = 0; t < T; t++) {
        //printf("Case #%d: ", t + 1);
        solve();
    }
#endif
    return 0;
}



Measured memory_bytes: 10972