Problem: Problem Statement

Mr. Takatsuki, who is planning to participate in the Aizu training camp, has a poor house and always tries to save as much paper as possible. She decided to play a ghost leg with other participants to decide the team for the Aizu training camp.

How to make Amidakuji for this training camp is as follows. First, write N vertical bars in parallel on the paper. Then, write the M horizontal bars in order from the top so that they are perpendicular to the vertical bars and the heights of the horizontal bars are all different. For example, the Amida of Sample Input 1 is as shown in Fig. 1.

Here, Mr. Takatsuki, a little dissatisfied expression. It's a waste of paper to write a ghost leg so vertically. You should be able to compress the height more. So, I want her to solve the problem of height compression of Amidakuji shown below.

First, the height of the Amidakuji is the value obtained by counting the horizontal bars that exist at the same height together as the height 1 and counting this to the bottom horizontal bar. Here, it is assumed that each horizontal bar can be freely moved up and down in order to perform height compression. However, it is not permissible to remove or add horizontal bars. The Amidakuji after height compression must meet the following conditions.

* The end points of the horizontal bar do not touch the end points of other horizontal bars.
* The result of tracing the Amidakuji after compression and the result of tracing the Amidakuji before compression match.



FIG. 2 is a compressed version of FIG. The "horizontal bar connecting vertical bars 1 and 2" moves to the top and becomes the same height as the "horizontal bar connecting vertical bars 4 and 5", and these two are height 1. After that, the "horizontal bar connecting the vertical bars 3 and 4" and the "horizontal bar connecting the vertical bars 2 and 3" have different heights, and the total height is 3.

<image>

Compress the height of the given Amidakuji and output the compressed height.

Constraints

* 2 <= N <= 8
* 1 <= M <= 8
* 1 <= ai <= N --1

Input

Each data set is input in the following format.


N M
a1
a2
...
aM


All inputs are integers. N indicates the number of vertical bars and M indicates the number of horizontal bars. Then, the information of the horizontal bar is input over M lines. ai indicates that the i-th horizontal bar connects the vertical bar ai and the vertical bar to the right of it. The i-th horizontal bar exists above the i + 1-th horizontal bar.

Output

Outputs the height of the compressed Amidakuji in one line.

Examples

Input

5 4
4
3
1
2


Output

3


Input

4 3
1
2
3


Output

3

Solution (in CPP):

Solution:
/*
 * 2516.cc: Amidakuji
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 8;
const int MAX_M = 8;

/* typedef */

typedef unsigned int uint;

/* global variables */

int n, m;
int minh = MAX_M;
uint gl;

/* subroutines */

inline uint getn(uint n, int i) {
  return (n >> (4 * i)) & 0xf;
}

inline uint resetn(uint n, int i) {
  return n & ~(0xfU << (4 * i));
}

inline uint setn(uint n, int i, int v) {
  return resetn(n, i) | ((v & 0xf) << (4 * i));
}

inline uint swapn(uint n, int i, int j) {
  uint vi = getn(n, i);
  uint vj = getn(n, j);
  return setn(setn(n, i, vj), j, vi);
}

void rec(uint cs, uint an, uint hs, int h) {
  if (an == 0) {
    if (cs == gl && minh > h) minh = h;
    return;
  }
  if (h >= minh) return;

  for (int i = 0; i < n - 1; i++) {
    int ai = getn(an, i);
    if (ai > 0) {
      int h0 = max(getn(hs, i), getn(hs, i + 1)) + 1;
      uint hs0 = setn(setn(hs, i, h0), i + 1, h0);
      uint an0 = setn(an, i, ai - 1);
      uint cs0 = swapn(cs, i, i + 1);
      rec(cs0, an0, hs0, (h0 > h) ? h0 : h);
    }
  }
}

/* main */

int main() {
  cin >> n >> m;

  uint st = 0, an = 0;
  for (int i = 0; i < n; i++) st = setn(st, i, i);
  gl = st;
  
  for (int i = 0; i < m; i++) {
    int ai;
    cin >> ai;
    ai--;

    an = setn(an, ai, getn(an, ai) + 1);
    gl = swapn(gl, ai, ai + 1);
  }
  //printf("st=%x, gl=%x, an=%x\n", st, gl, an);

  rec(st, an, 0, 0);
  printf("%d\n", minh);
  return 0;
}