#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<sstream>
#include<iomanip>
#include<limits>
#include<deque>
#include<map>
#include<list>
#include<set>
#include <unordered_set>
#include<vector>
#include<cmath>
#include<cstdio>
#include<memory>
#include<bitset>
#include<stack>
#include<functional>
#include<queue>
#include<regex>
#include<time.h>
#include<type_traits>

using namespace std;


#define YES cout<<"YES"<<endl
#define NO cout<<"NO"<<endl
#define Yes cout<<"Yes"<<endl
#define No cout<<"No"<<endl
#define yes cout<<"yes"<<endl
#define no cout<<"no"<<endl

#define Tof(x) (x) ? Yes : No
#define TOF(x) (x) ? YES : NO
#define tof(x) (x) ? yes : no

using ll = long long;

constexpr ll MOD = 1000000007;
constexpr ll INF = 1050000000;
constexpr long long LONGINF = 1005000000000000000;



/*for文でx,yを上下左右確認するやつだよ。正直使いづらいよ。

int dy[] = { 0, 1, 0, -1 };
int dx[] = { 1, 0, -1, 0 };


for (int i = 0; i < 4; i++) {
	int ny = y + dy[i];
	int nx = x + dx[i];
}

*/


/*繰り返し二乗法だよ。modもとってくれるよ。n^kをmodで割った余りでやってくれるよ。

ll POW_MOD(ll n, ll k, ll mod) {
	ll r = 1;

	for (; k > 0; k >>= 1) {
		if (k & 1) {
			r = (r * n) % mod;
		}
		n = (n * n) % mod;
	}
	return r;
}

*/



/*まだ使えないテクニックのメモだよ。

for (int bit = 0; bit < (1<<n); ++bit)//bit全探索用のfor文だよ

*/

class UnionFind {
private:
	std::vector<int> parent;
	std::vector<int> height;
	std::vector<int> m_size;

public:
	UnionFind(int size_) : parent(size_), height(size_, 0), m_size(size_, 1) {
		for (int i = 0; i < size_; ++i) parent[i] = i;
	}
	void init(int size_) {
		parent.resize(size_);
		height.resize(size_, 0);
		m_size.resize(size_, 1);
		for (int i = 0; i < size_; ++i) parent[i] = i;
	}
	int find(int x) {
		if (parent[x] == x) return x;
		return parent[x] = find(parent[x]);
	}
	void unite(int x, int y) {
		x = find(x);
		y = find(y);
		if (x == y) return;
		int t = size(x) + size(y);
		m_size[x] = m_size[y] = t;
		if (height[x] < height[y]) parent[x] = y;
		else parent[y] = x;
		if (height[x] == height[y]) ++height[x];
	}
	bool same(int x, int y) {
		return find(x) == find(y);
	}
	int size(int x) {
		if (parent[x] == x) return m_size[x];
		return size(parent[x] = find(parent[x]));
	}
};

int GCD(int a, int b) {
	while (b) {
		int tmp = a % b;
		a = b;
		b = tmp;
	}
	return a;
}

int main() {
	int dp[310][310];
	bool take[310][310];

	while (1) {
		int n; cin >> n;
		int w[310];
		if (n == 0) { return 0; }
		for (int i = 0; i < n; i++) {
			cin >> w[i];
		}

		memset(take, false,sizeof(take));
		memset(dp, 0, sizeof(dp));

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n - i; j++) {
				int len = i + 1;
				int s = j;
				int t = j + i;
				for (int k = s; k < t; k++) {
					if (take[s][k] && take[k + 1][t]) { take[s][t] = true; }
				}
				if (len == 2) {
					if (abs(w[s] - w[t]) < 2) { take[s][t] = true; }
				}
				if (take[s][t]) {
					int x = s - 1;
					int y = t + 1;
					while (1) {
						if (x < 0 || x >= n || y < 0 || y >= n) { break; }
						if (abs(w[x] - w[y]) >= 2) { break; }
						take[x][y] = true;
						x--; y++;
					}
				}
			}
		}

		for (int i = 0; i < n; i++) {
			for (int j = i + 1; j < n; j++) {
				if (take[i][j]) { dp[i][j] = j - i + 1; }
			}
		}

		for (int i = 0; i < n; i++) {
			for (int j = i; j < n; j++) {
				for (int k = i; k < j; k++) {
					dp[i][j] = max(dp[i][j], dp[i][k] + dp[k + 1][j]);
				}
			}
		}

		cout << dp[0][n - 1] << endl;

	}

	return 0;
}



Measured memory_bytes: 3544