Go: package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
)

const (
	initialBufSize = 10000000
	maxBufSize     = 100000000
)

var sc *bufio.Scanner

func initScanner(r io.Reader) *bufio.Scanner {
	buf := make([]byte, initialBufSize)

	sc := bufio.NewScanner(r)
	sc.Buffer(buf, maxBufSize)
	sc.Split(bufio.ScanWords) // bufio.ScanLines
	return sc
}

func main() {
	sc = initScanner(os.Stdin)
	resolve()
}

func nextInt(sc *bufio.Scanner) int {
	sc.Scan()
	a, _ := strconv.Atoi(sc.Text())
	return int(a)
}
func nextString(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

func nextIntSlice(sc *bufio.Scanner, n int) (a []int) {
	a = make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = nextInt(sc)
	}
	return a
}

var dp [][]int

func initDP(n int) {
	dp = make([][]int, n+1)
	for i := 0; i < len(dp); i++ {
		dp[i] = make([]int, n+1)
		for j := 0; j < len(dp[0]); j++ {
			dp[i][j] = -1
		}
	}
}

func resolve() {
	ans := []int{}
	for true {
		n := nextInt(sc)
		if n == 0 {
			break
		}
		as := nextIntSlice(sc, n)
		initDP(n)
		_rec(as, n, 0, n)
		ans = append(ans, dp[0][n])
	}
	for _, v := range ans {
		fmt.Println(v)
	}
	return
}

func _rec(as []int, n, l, r int) int {
	if dp[l][r] > -1 {
		return dp[l][r]
	}
	if r-l == 1 { // prevent to hit daruma
		dp[l][r] = 0
		return dp[l][r]
	}
	if r-l == 2 {
		if abs(as[l]-as[r-1]) <= 1 {
			dp[l][r] = 2
		} else {
			dp[l][r] = 0
		}
		return dp[l][r]
	}
	if abs(as[l]-as[r-1]) <= 1 {
		v := _rec(as, n, l+1, r-1)
		// if we can remove internal blocks
		if (r - 1 - (l + 1)) == v {
			dp[l][r] = v + 2
			return dp[l][r]
		} else {
			dp[l][r] = v
		}
	}
	for i := l + 1; i < r; i++ {
		v := _rec(as, n, l, i) + _rec(as, n, i, r)
		if dp[l][r] < v {
			dp[l][r] = v
		}
	}
	return dp[l][r]
}

func abs(v int) int {
	if v < 0 {
		return -v
	}
	return v
}

C++: #include<bits/stdc++.h>
using namespace std;
#define REP(i,n) for(long long i=0;i<n;i++)
#define REP1(i,n) for(long long i=1;i<=n;i++)
#define PER(i,n) for(long long i=((n)-1);i>=0;i--)
#define PER1(i,n) for(long long i=(n);i>0;i--)
#define REP2D(i,j,w,h) for(long long i=0;i<h;i++) for(long long j=0;j<w;j++)
#define FOR(i,a,b) for(long long i=(a);i<(b);i++)
#define FORE(i,a,b) for(long long i=(a);i<=(b);i++)
#define ITE(arr) for(auto ite=(arr).begin();ite!=(arr).end();++ite)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
#define YNPRT(b) cout<<((b)?"Yes":"No")<<endl
#define REV(arr) reverse(ALL(arr))
#define PRT(a) cout<<a<<endl;
#define PRTLST(arr,num) REP(_i,num) cout<<_i<<" - "<<arr[_i]<<endl;
#define PRTLST2(arr2,d1,d2) REP(_i,d1) REP(_j,d2) cout<<_i<<","<<_j<<" : "<<arr2[_i][_j]<<endl;
#define PRTLST2D(arr2,d1,d2) do{cout<<"L\t";REP(_i,d2) cout<<_i<<"\t"; cout<<endl; REP(_i,d1){cout<<_i<<"\t";REP(_j,d2){cout<<arr2[_i][_j]<<"\t";}cout<<endl;}}while(0);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int INF_INT = 2147483647;
const ll INF_LL = 9223372036854775807LL;
const ull INF_ULL = 18446744073709551615Ull;
const ll P = 92540646808111039LL;
const int Move[4][2] = {-1,0,1,0,0,1,0,-1};
const int Move_[8][2] = {-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1};

//---------------------
#define MAXN 300
//---------------------


template<typename T>
ostream& operator<<(ostream& os,const vector<T>& v) {os<<"{"; ITE(v) os << *ite << " ";os<<"}";return os;}

ll n,w[MAXN];
ll dpmem[MAXN][MAXN];
vector<ll> idtomove[MAXN];


bool init(){
	n=0;
	ZERO(w);
	MINUS(dpmem);
	REP(i,MAXN) idtomove[i].clear();
	cin>>n;
	if(n<=0) return false;
	REP2D(i,j,n,n) if(i>=j) dpmem[i][j]=0;
	REP(i,n) cin>>w[i];
	REP(i,n){
		for(int j=i+1;j<n;j++){
			if(abs(w[j]-w[i])<=1.1) idtomove[i].push_back(j);
		}
	}
	return true;
}

bool canberemoved(ll a,ll b){
	return abs(w[a]-w[b])<=1.1;
}

ll dp(ll l,ll r){
  	if(l>=n || r>=n || l<0 || r<0) return 0;
  	if(dpmem[l][r]>=0) return dpmem[l][r];
  	ll ret=-1;
	if(r-l==1){
		if(canberemoved(l,r)) ret=dpmem[l][r]=2;
		else ret=0;
	}
	else{
		ITE(idtomove[l]) if(*ite<=r && dp(l+1,(*ite)-1)==((*ite)-l-1)) ret=max(ret,(*ite)-l+1+dp((*ite)+1,r));
		ret=max(ret,dp(l+1,r));
	}
	return dpmem[l][r]=ret;
}

int main(){
	while(init()){
		cout<<dp(0,n-1)<<endl;
		//PRTLST2D(dpmem,n,n);
	}
	return 0;
}

C++: #include <iostream>
#include <cmath>
#define INF 1e+9
using namespace std;

int main(){
	int n;
	while(cin >> n,n){
		int a[300],dp2[301] = {};
		bool dp1[301][301] = {};
		for(int i = 0;i < n;i++){
			cin >> a[i];
			dp1[i][i] = true;
		}
		for(int i = 2;i <= n;i += 2){
			for(int j = 0;j + i <= n;j++){
				for(int k = 0;k <= i;k++){
					if(dp1[j][j + k] && dp1[j + k][j + i]) dp1[j][j + i] = true;
				}
				if(dp1[j + 1][j + i - 1] && abs(a[j] - a[j + i - 1]) <= 1) dp1[j][j + i] = true;
			}
		}
		for(int i = 1;i <= n;i++){
			dp2[i] = dp2[i - 1] + 1;
			for(int j = 0;j <= i;j++){
				if(dp1[j][i]) dp2[i] = min(dp2[i],dp2[j]);
			}
		}
		cout << n - dp2[n] << endl;
	}
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main(){
	while(1){
		int n;
		cin >> n;
		if(n==0) break;
		
		vector<int> w(n+1);
		for(int i=0; i<n; i++){
			cin >> w[i];
		}
		if(n%2!=0){
			w[n]=-1;
			n++;
		}
		
		vector<vector<int> > dp(n+1, vector<int>(n+1, 0));
		for(int i=2; i<=n; i++){
			for(int j=0; j+i<=n; j++){
				for(int k=2; k<i-1; k++){
					dp[j][i] = max(dp[j][i], dp[j][k] +dp[j+k][i-k]);
				}
				if(dp[j+1][i-2]==i-2 && abs(w[j]-w[j+i-1])<=1){
					dp[j][i] = i;
				}
			}
		}
		cout << dp[0][n] << endl;
	} 
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <algorithm>

using namespace std;


int n;
vector<int> w;

enum MEMO {
  NOT_CHECKED,
  TRUE,
  FALSE
};


MEMO memo[301][301];

MEMO rec(int l, int r) {
  if (r - l == 1) {
    if (abs(w[r] - w[l]) <= 1) {
      return memo[l][r] = TRUE;
    } else {
      return memo[l][r] = FALSE;
    }
  }

  if (r == l) {
    return memo[l][r] = FALSE;
  }

  if (l > r) {
    return memo[l][r] = TRUE;
  }

  if (memo[l][r] != NOT_CHECKED) {
    return memo[l][r];
  }

  if (abs(w[l] - w[r]) <= 1) {
    for (int i = l + 2; i < r; i++) {
      int temp1 = rec(l + 1, i);
      int temp2 = rec(i + 1, r - 1);
      if (temp1 == TRUE && temp2 == TRUE) {
        return memo[l][r] = TRUE;
      }
    }
  }

  for (int i = l + 1; i < r; i++) {
    int temp1 = rec(l, i);
    int temp2 = rec(l + 1, r);
    if (temp1 == TRUE && temp2 == TRUE) {
      return memo[l][r] = TRUE;
    }
  }

  return memo[l][r] = FALSE;
}

int main() {
  while (true) {
    cin >> n;
    if (n == 0) {
      break;
    }
    w.resize(n);

    for (int i = 0; i < n; i++) {
      cin >> w[i];
    }

    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        memo[i][j] = NOT_CHECKED;
      }
    }

    rec(0, n - 1);

    int dp[301] = { 0 };
    for (int i = 1; i < n; i++) {
      dp[i] = dp[i - 1];
      if (memo[0][i] == TRUE) {
        dp[i] = i + 1;
        continue;
      }
      for (int j = 1; j < i; j++) {
        if (memo[j][i] == TRUE) {
          dp[i] = max(dp[i], dp[j - 1] + (i - j + 1));
        }
      }
    }

    int ans = dp[n - 1];
    cout << ans << endl;
  }

  return 0;
}