Problem:
Loading

Aizu Ocean Transport Company (AOTC) accepted a new shipping order. The pieces of the cargo included in this order all have the same square footprint (2m x 2m). The cargo room has a rectangular storage space of 4m width with various longitudinal extents. Each pieces of cargo must be placed in alignment with partition boundaries which form a 1m x 1m square grid. A straddling arrangement with a neighboring partition (for example, protrusion by 50 cm) is not allowed. Neither an angled layout nor stacked placement are allowed. Note also that there may be some partitions on which any cargo loading is prohibited.

AOTC wishes to use the currently available ship for this consignment and needs to know how many pieces of cargo it can accommodate.

Make a program to report the maximum cargo capacity of the cargo space given the following information: the depth (m) of the cargo space and the loading-inhibited partitions.

Input

The input is given in the following format.

H N
x_1 y_1
x_2 y_2
:
x_N y_N

The first line provides the longitudinal depth H (2 ≤ H ≤ 104) of the cargo space in meters and the number of load-inhibited partitions N (0 ≤ N ≤ 4 × 104). Each of the subsequent N lines defines the position of the i-th load-inhibited partition x_i (0 ≤ x_i ≤ 3) and y_i (0 ≤ y_i ≤ H-1) in integers, where x = 0 and y = 0 indicate the bottom-left corner partition. A load-inhibited partition appears only once in the list.

Output

Output the maximum number of cargo pieces loaded into the cargo space.

Sample Input 1

5 3
0 1
1 2
3 3

Sample Output 1

2

Input example 1 corresponds to the cargo layout shown in the left-most figure.

Sample Input 2

6 4
0 2
1 3
3 4
0 5

Sample Output 2

4

Solution in C# (judge verdict: Accepted)

using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using static System.Math;

class P
{
    static bool[][] bits =
    {
        new bool[]{ false,false,false },
        new bool[]{ false,false,true },
        new bool[]{ false,true,false },
        new bool[]{ false,true,true },
        new bool[]{ true,false,false },
        new bool[]{ true,false,true },
        new bool[]{ true,true,false },
        new bool[]{ true,true,true }
    };
    static int[] bitCount = { 0, 1, 1, 2, 1, 2, 2, 3 };
    static int[][] transition =
    {
        new int[]{0,1,2,4,5 },//0
        new int[]{0,4 },//1
        new int[]{0},//2
        new int[]{},//3
        new int[]{0,1},//4
        new int[]{0},//5
        new int[]{},//6
        new int[]{}//7
    };
    static bool[][] canPlaceCarry = null;
    static void Main()
    {
        int[] hn = Console.ReadLine().Split().Select(int.Parse).ToArray();
        int[][] dp = Enumerable.Repeat(0, hn[0]).Select(_ => new int[8]).ToArray();
        canPlaceCarry = Enumerable.Repeat(0, hn[0] - 1).Select(_ => new bool[3] { true, true, true }).ToArray();
        for (int i = 0; i < hn[1]; i++)
        {
            int[] xy = Console.ReadLine().Split().Select(int.Parse).ToArray();
            setFalse(xy[0], (hn[0] - 1) - xy[1]);
        }
        for (int i = 1; i < hn[0]; i++)
        {
            for (int j = 0; j < 8; j++)
            {
                //移る先を列挙
                foreach (var trans in transition[j])
                {
                    for (int k = 0; k < 3; k++)
                    {
                        if (bits[trans][k] && !canPlaceCarry[i - 1][k]) goto elop;
                    }
                    dp[i][trans] = Max(dp[i][trans], dp[i - 1][j] + bitCount[trans]);
                    elop:;
                }
            }
        }
        Console.WriteLine(dp.Last().Max());
    }
    static void setFalse(int x,int y)
    {
        if (y != 0)
        {
            if (x != 0)
            {
                canPlaceCarry[y - 1][x - 1] = false;
            }
            if (x < 3)
            {
                canPlaceCarry[y - 1][x] = false;
            }
        }
        if (y < canPlaceCarry.Length)
        {
            if (x != 0)
            {
                canPlaceCarry[y][x - 1] = false;
            }
            if (x < 3)
            {
                canPlaceCarry[y][x] = false;
            }
        }
    }
}