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:

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define all(a) (a).begin(),(a).end()
#define vi vector<int>
#define pb push_back
#define INF 999999999

//int upper(int dif,int m){
//	int ret = dif;
//	while(ret<=m)ret+=dif;
//	return ret;
//}
//
//int lower(int dif,int m){
//	int ret = dif;
//	while(ret<m)ret+=dif;
//	return ret;
//}
//
//int under(int dif,int m){
//	int ret=dif;
//	while(ret+dif<=m)ret+=dif;
//	return ret;
//}
//int n,m;
//
//bool isRef(int time,int dif,int ndif){
//	int ntime;
//	if(dif<=ndif)ntime = lower(ndif,time);
//	else		ntime = upper(ndif,time);
//	if(ntime>m)return false;
//	else return true;
//}
//
//int main(){
//	while(cin>>n>>m){
//		vector<pair<pii,int>> vec;
//		int ans=-1;
//		if(n==0&&m==0)break;
//		vector<int> v(n);
//		rep(i,n)cin>>v[i];
//		
//		int pos = -1, time = INF, dif = INF;
//		for(int i=0;i<n;i++){
//			if(i==0 || isRef( time,dif,v[i] )){
//				pos = i+1;
//				time = under(v[i],m);
//				dif = v[i];
//				vec.pb(make_pair(pii(time,dif),pos));
//			}
//			else{
//				int ntime;
//				if(dif<=v[i])ntime = lower(v[i],time);
//				else		ntime = upper(v[i],time);
//				if(ntime>m){ans = i+1;break;}
//				vec.pb(make_pair(pii(ntime,v[i]),pos));
//			}
//		}
//		rep(i,vec.size())cout<<vec[i].first.first<<" "<<vec[i].first.second<<" "<<vec[i].second<<endl;
//		if(ans!=-1)cout<<ans<<endl;
//		else{
//			sort(all(vec));
//			if(vec[0].first==vec[1].first)cout<<n<<endl;
//			else cout<<vec[0].second+1<<endl;
//		}
//	}
//}



//int main(){
//	int n, m, p, result = 0;
//	int field[10] = {0};
//	
//	cin >> n >> m;
//	
//	for(int i=0; i < m; i++){
//		cin >> p;
//		int q = max(field[p]+1,field[p+1]+1);
//		field[p]=q; field[p+1]=q;
//		result = max(result, q);
//	}
//	cout << result << endl;
//}

int result[10];

int solve(vector<int> field){
	int r[10];
	for(int i=0; i < 10; i++) r[i] = i;
	
	for(int i=0; i < field.size(); i++){
		swap(r[field[i]], r[field[i]+1]);
	}
	
	bool ok = true;
	for(int i=0; i < 10; i++) if(r[i] != result[i]){ ok = false; break;}
	if(! ok) return 100000;
	
	
	
	bool f[15][15];
	for(int i=0; i < 15; i++) for(int j=0; j < 15; j++) f[i][j] = false;
	
	for(int i=0; i < field.size(); i++){
		f[i+1][field[i]] = true;
	}
	
	
	bool change = false;
	while(1){
		change = false;
		for(int i=1; i < 10; i++){
			for(int j=1; j < 10; j++){
				if(!f[i][j] || i == 1) continue;
				bool ok = true;
				for(int k=-1; k <= 1; k++){
					if(f[i-1][j+k] == 1){ok = false;}
				}
				if(ok){change = true; f[i][j] = false; f[i-1][j] = true;}
				
			}
			
		}
		if(!change) break;
	}
	int ans = 0;
	
	for(int i=0; i < 10; i++){
		for(int j=0; j < 10; j++){
			if(f[i][j]) ans = max(ans, i);
		}
	}
	return ans;
}

int main(){
	int n, m;
	vector<int> field;
	
	cin >> n >> m;
	
	int p;

	for(int i=0; i < 10; i++) result[i] = i;
	for(int i=0; i < m; i++){
		cin >> p;
		field.push_back(p);
		swap(result[p], result[p+1]);
	}
	sort(field.begin(), field.end());
	
	int ans = 100000;
	
	do{
		ans = min(ans, solve(field));
	}while(next_permutation(field.begin(), field.end()));
	
	cout << ans << endl;
}