let MOD = 998244353

let (N, K) = getIntPair()
var moveSets = [ClosedRange<Int>]()
for _ in 0..<K {
    let (L, R) = getIntPair()
    moveSets.append(L...R)
}

var ft = FenwickTree(count: N+1+1)
ft.update(at: 1, adding: 1)
ft.update(at: 2, adding: -1)

for i in 1 ..< N {
    let x = ft.query(range: 1 ..< i+1) % MOD
    for r in moveSets {
        var (l, r) = (r.lowerBound, r.upperBound)
        l += i
        r = min(r + i, N)
        if l > r { continue }
        ft.update(at: l, adding: x)
        ft.update(at: r+1, adding: -x)
    }
}

print(ft.query(range: 1 ..< N+1) % MOD)



//=============================================================================
// MARK: - FenwickTree.swift
// code section by Barry Fam

struct FenwickTree<Element> {
    let count: Int
    private let zeroValue: Element
    private var tree: UnsafeMutablePointer<Element>
    private let combine: (Element, _ adding: Element) -> Element
    private let inverse: (Element, _ removing: Element) -> Element

    init(count: Int,
         zeroValue: Element,
         addBy combine: @escaping (Element, _ adding: Element) -> Element,
         removeBy inverse: @escaping (Element, _ removing: Element) -> Element
    ){
        tree = UnsafeMutablePointer<Element>.allocate(capacity: count)
        tree.initialize(repeating: zeroValue, count: count)
        self.count = count
        self.zeroValue = zeroValue
        self.combine = combine
        self.inverse = inverse
    }

    mutating func update(at i: Int, adding value: Element) {
        assert(0 <= i && i < count)
        var i = i
        if i == 0 {
            tree[0] = combine(tree[0], value)
            return
        }
        repeat {
            tree[i] = combine(tree[i], value)
            i += i & -i  // increment LSB
        } while i < count
    }
    func query(range r: Range<Int>) -> Element {
        assert(0 <= r.lowerBound && r.upperBound <= count)
        assert(r.count >= 1)
        var i = r.upperBound - 1
        var j = r.lowerBound - 1
        var sigma = zeroValue
        if j < 0 {
            sigma = combine(sigma, tree[0])
            j = 0
        }
        while i > j {
            sigma = combine(sigma, tree[i])
            i &= i-1  // decrement LSB
        }
        while j > i {
            sigma = inverse(sigma, tree[j])
            j &= j-1  // decrement LSB
        }
        return sigma
    }
}

extension FenwickTree where Element == Int {
    init(count: Int) {
        self.init(count: count, zeroValue: 0, addBy: (+), removeBy: (-))
    }
}

//=============================================================================
// MARK: - contestIO.swift
// code section by Barry Fam

#if os(Linux)
import Glibc
#else
import Darwin.C
#endif

struct IO {
    static var INPUT = stdin
    fileprivate static var buffer: UnsafeMutablePointer<CChar>?
    fileprivate static var bufferCapacity: Int32 = 0
}

fileprivate func getsToBuffer(size: Int32) -> UnsafeMutablePointer<CChar> {
    if IO.bufferCapacity < size {
        IO.buffer?.deallocate()
        IO.buffer = UnsafeMutablePointer.allocate(capacity: Int(size))
        IO.bufferCapacity = size
    }
    return fgets(IO.buffer!, size, IO.INPUT)
}
fileprivate func getIntFromBuffer(_ ptr: inout UnsafeMutablePointer<CChar>) -> Int {
    var minus = false
    var x: Int?
    while true {
        switch ptr.pointee {
        case 0x2D:
            assert(!minus && x == nil)
            minus = true
        case let d where 0x30...0x39 ~= d:
            x = (x ?? 0)*10 + Int(d)-0x30
        default:
            if x != nil { return minus ? -x! : x! }
            assert(ptr.pointee == 0x20)
        }
        ptr += 1
    }
}

func getString(maxLength: Int) -> String {
    var s = String(cString: getsToBuffer(size: Int32(maxLength + 3)))
    if s.last == "\n" { s.removeLast() }
    if s.last == "\r" { s.removeLast() }
    return s
}
func getStringAsArray(maxLength: Int) -> [UInt8] {
    let ptr = getsToBuffer(size: Int32(maxLength + 3))
    var s = [UInt8]()
    for ptr in ptr ..< ptr + maxLength {
        let c = UInt8(ptr.pointee)
        if c == 0x00 || c == 0x0A || c == 0x0D { break }
        s.append(c)
    }
    return s
}
func getInt() -> Int {
    var xPtr = getsToBuffer(size: 24)
    return getIntFromBuffer(&xPtr)
}
func getIntPair() -> (Int, Int) {
    var xPtr = getsToBuffer(size: 2*24)
    let x1 = getIntFromBuffer(&xPtr)
    let x2 = getIntFromBuffer(&xPtr)
    return (x1, x2)
}
func getIntTriplet() -> (Int, Int, Int) {
    var xPtr = getsToBuffer(size: 3*24)
    let x1 = getIntFromBuffer(&xPtr)
    let x2 = getIntFromBuffer(&xPtr)
    let x3 = getIntFromBuffer(&xPtr)
    return (x1, x2, x3)
}
func getIntQuadruplet() -> (Int, Int, Int, Int) {
    var xPtr = getsToBuffer(size: 4*24)
    let x1 = getIntFromBuffer(&xPtr)
    let x2 = getIntFromBuffer(&xPtr)
    let x3 = getIntFromBuffer(&xPtr)
    let x4 = getIntFromBuffer(&xPtr)
    return (x1, x2, x3, x4)
}
func getIntQuintuplet() -> (Int, Int, Int, Int, Int) {
    var xPtr = getsToBuffer(size: 5*24)
    let x1 = getIntFromBuffer(&xPtr)
    let x2 = getIntFromBuffer(&xPtr)
    let x3 = getIntFromBuffer(&xPtr)
    let x4 = getIntFromBuffer(&xPtr)
    let x5 = getIntFromBuffer(&xPtr)
    return (x1, x2, x3, x4, x5)
}
func getIntSextuplet() -> (Int, Int, Int, Int, Int, Int) {
    var xPtr = getsToBuffer(size: 6*24)
    let x1 = getIntFromBuffer(&xPtr)
    let x2 = getIntFromBuffer(&xPtr)
    let x3 = getIntFromBuffer(&xPtr)
    let x4 = getIntFromBuffer(&xPtr)
    let x5 = getIntFromBuffer(&xPtr)
    let x6 = getIntFromBuffer(&xPtr)
    return (x1, x2, x3, x4, x5, x6)
}
func getInts(count: Int) -> [Int] {
    var xPtr = getsToBuffer(size: Int32(count) * 24)
    var a = [Int]()
    a.reserveCapacity(count)
    for _ in 0..<count { a.append(getIntFromBuffer(&xPtr)) }
    return a
}


Measured memory_bytes: 9076