fun readInts(): List<Int> = readLine()!!.split(" ").map { it.toInt() }

const val MAX_H = 100000

fun main(args: Array<String>) {
    val (h, n) = readInts()

    val blocked = IntArray(MAX_H)
    repeat(n) {
        val (x, y) = readInts()
        blocked[y] = blocked[y] or (1 shl x)
    }

    //置き方パターン
    val locate = listOf(0b0000, 0b0011, 0b0110, 0b1100, 0b1111)
    //荷物を置けた数
    val point = listOf(0, 1, 1, 1, 2)
    //一行4マスなので4bit分の障害物のパターンがある
    val howManyPatterns = 1 shl 4
    val patternRange = 0 until howManyPatterns

    //dpテーブル
    var now = IntArray(howManyPatterns) { 0 }
    var next = IntArray(howManyPatterns) { 0 }

    for (obstacle in patternRange) {
        now[obstacle] = if ((obstacle and blocked[0]) > 0) -1 else 0
    }
    for (i in 0 until h - 1) {
        next.fill(-1)
        for (obstacle in patternRange) {
            //そうはなり得ない障害物の配置の時は無視
            if (now[obstacle] == -1) continue
            //置けるパターンを試していく
            for (k in locate.indices) {
                //1行目に置いても障害物と被らないか
                val check0 = (blocked[i] and locate[k]) == 0
                //2行目に置いても障害物と被らないか
                val check1 = (blocked[i + 1] and locate[k]) == 0
                //置いても前の状態と被らないか
                val check2 = (obstacle and locate[k]) == 0
                if (check0 && check1 && check2) {
                    //置ける場合
                    val pattern = blocked[i + 1] or locate[k]
                    next[pattern] = Math.max(now[obstacle] + point[k], next[pattern])
                }
            }
        }
        val tmp = now
        now = next
        next = tmp
    }

    println(now.max()!!)
}
