#include <bits/stdc++.h>

using namespace std;

#define LL long long

const int MX = 200 + 23;
const LL MOD = 1e9 + 7;

struct VECTOR{
	LL x ,y;
	VECTOR(LL X = 0 ,LL Y = 0){x = X ,y = Y;}
	VECTOR operator +(const VECTOR &B)const{return VECTOR(x + B.x ,y + B.y);}
	VECTOR operator -(const VECTOR &B)const{return VECTOR(x - B.x ,y - B.y);}
	LL operator *(const VECTOR &B)const{return x * B.y - y * B.x;}
	bool operator ==(const VECTOR &B)const{return x == B.x && y == B.y;}
	void Read(){cin >> x >> y;}
}P[MX];

struct SEG{
	VECTOR st ,d;
	SEG(){st = d = VECTOR(0 ,0);}
	SEG(VECTOR __st ,VECTOR __ed){
		st = __st ,d = __ed - __st;
	};
	void turn(){
		st = st + d;
		d = VECTOR(0 ,0) - d;
	}
};

int sgn(LL x){
	if(!x) return 0;
	return x > 0 ? 1 : -1;
}

bool PingXing(VECTOR A ,VECTOR B){
	return A.x * B.y - A.y * B.x == 0;
}

bool online(SEG a ,VECTOR b){
	// 询问点 b 是否在 a 上（含边缘）
	bool xless = b.x < a.st.x && b.x < (a.st + a.d).x;
	bool xmore = b.x > a.st.x && b.x > (a.st + a.d).x;
	bool yless = b.y < a.st.y && b.y < (a.st + a.d).y;
	bool ymore = b.y > a.st.y && b.y > (a.st + a.d).y;
	return (xless + xmore + yless + ymore) == 0;
}

int ok(SEG a ,SEG b){
	// 0 绝对不行
	// 1 共点
	// 2 绝对可以
	LL test1 = sgn(a.d * (b.st - a.st)) * sgn(a.d * (b.st + b.d - a.st));
	LL test2 = sgn(b.d * (a.st - b.st)) * sgn(b.d * (a.st + a.d - b.st));
	if(test1 > 0 || test2 > 0){
		// 连交点都没有
		return 2;
	}
	if(PingXing(a.d ,b.d)){
		// 有交点且平行就是共线
		if(online(a ,b.st) || online(a ,b.st + b.d)
		|| online(b ,a.st) || online(b ,a.st + a.d)){
			// 二者有交
			if(sgn(a.d.x) != sgn(b.d.x) || sgn(a.d.y) != sgn(b.d.y)){
				b.turn();
			}
			if(a.st + a.d == b.st || b.st + b.d == a.st)
				return 1;
			return 0;
		}

		return 2;
	}
	return (test1 <= 0 && test2 <= 0);
}

LL fad;
int n;
int check(int l ,int r)
	SEG Main(P[l] ,P[r]);
	if(fad > 0){
		if(Main.d * (P[l + 1] - P[l]) > 0){
			if(l == 0 && r == n - 1);
			else return 0;
		}
	}
	else{
		if(Main.d * (P[l + 1] - P[l]) < 0) return 0;
	}
	int neg = 0 ,pos = 0;
	for(int i = 0 ; i < n ; ++i){
		if(i == l || i == r) continue;
		SEG now(P[l] ,P[i]);
		if(Main.d * now.d == 0) continue;
		if(Main.d * now.d > 0) ++pos;
		else ++neg;
	}
	if(!neg || !pos){
		if(r == (l + n - 1) % n){
			;
		}
		else return 0;
	}
	for(int i = 0 ; i < n ; ++i){
		SEG t(P[i] ,P[(i + 1) % n]);
		int judge = ok(Main ,t);
		if(i == r && ((i + 1) % n == l)) continue;
		if(judge == 0) return 0;
		if(judge == 1){
			if(i == l || (i + 1) % n == l || i == r || (i + 1) % n == r){
				continue;
			}
			return 0;
		}
	}
	return 1;
}

LL dp[MX][MX];

void test(){
	int n; cin >> n;
	while(n--){
		int x ,y;
		cin >> x >> y;
		printf("(%d,%d)\n" ,x ,y);
	}
	SEG a(VECTOR(1 ,0) ,VECTOR(-1 ,0)) ,b(VECTOR(0 ,0) ,VECTOR(1 ,0));
	cout << ok(a ,b) <<endl;
	return ;
}

int main(){
	// test();
	cin >> n;
	for(int i = 0 ; i < n ; ++i){
		P[i].Read();
	}
	for(int i = 0 ; i < n ; ++i){
		fad += P[i] * P[(i + 1) % n];
	}
	// fad 为正数说明是顺时针给出
	for(int i = 1 ; i < n ; ++i){
		dp[i - 1][i] = 1;
	}
	for(int len = 2 ; len <= n ; ++len){
		for(int st = 0 ; st + len < n ; ++st){
			int ed = st + len;
			if(!check(st ,ed)){
				// printf("[%d ,%d] is bad!\n" ,st ,ed);

				continue;
			}
			for(int k = st + 1 ; k < ed ; ++k){
				dp[st][ed] = (dp[st][ed] + dp[st][k] * dp[k][ed]) % MOD;
		    }
		// 	printf("dp[%d][%d] = %lld\n" ,st ,ed ,dp[st][ed]);
		}
	}
	cout << dp[0][n - 1] << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long

const int MX = 200 + 23;
const LL MOD = 1e9 + 7;

struct VECTOR{
	LL x ,y;
	VECTOR(LL X = 0 ,LL Y = 0){x = X ,y = Y;}
	VECTOR operator +(const VECTOR &B)const{return VECTOR(x + B.x ,y + B.y);}
	VECTOR operator -(const VECTOR &B)const{return VECTOR(x - B.x ,y - B.y);}
	LL operator *(const VECTOR &B)const{return x * B.y - y * B.x;}
	bool operator ==(const VECTOR &B)const{return x == B.x && y == B.y;}
	void Read(){cin >> x >> y;}
}P[MX];

struct SEG{
	VECTOR st ,d;
	SEG(){st = d = VECTOR(0 ,0);}
	SEG(VECTOR __st ,VECTOR __ed){
		st = __st ,d = __ed - __st;
	};
	void turn(){
		st = st + d;
		d = VECTOR(0 ,0) - d;
	}
};

int sgn(LL x){
	if(!x) return 0;
	return x > 0 ? 1 : -1;
}

bool PingXing(VECTOR A ,VECTOR B){
	return A.x * B.y - A.y * B.x == 0;
}

bool online(SEG a ,VECTOR b){
	// 询问点 b 是否在 a 上（含边缘）
	bool xless = b.x < a.st.x && b.x < (a.st + a.d).x;
	bool xmore = b.x > a.st.x && b.x > (a.st + a.d).x;
	bool yless = b.y < a.st.y && b.y < (a.st + a.d).y;
	bool ymore = b.y > a.st.y && b.y > (a.st + a.d).y;
	return (xless + xmore + yless + ymore) == 0;
}

int ok(SEG a ,SEG b){
	// 0 绝对不行
	// 1 共点
	// 2 绝对可以
	LL test1 = sgn(a.d * (b.st - a.st)) * sgn(a.d * (b.st + b.d - a.st));
	LL test2 = sgn(b.d * (a.st - b.st)) * sgn(b.d * (a.st + a.d - b.st));
	if(test1 > 0 || test2 > 0){
		// 连交点都没有
		return 2;
	}
	if(PingXing(a.d ,b.d)){
		// 有交点且平行就是共线
		if(online(a ,b.st) || online(a ,b.st + b.d)
		|| online(b ,a.st) || online(b ,a.st + a.d)){
			// 二者有交
			if(sgn(a.d.x) != sgn(b.d.x) || sgn(a.d.y) != sgn(b.d.y)){
				b.turn();
			}
			if(a.st + a.d == b.st || b.st + b.d == a.st)
				return 1;
			return 0;
		}

		return 2;
	}
	return (test1 <= 0 && test2 <= 0);
}

LL fad;
int n;
int check(int l ,int r){

	SEG Main(P[l] ,P[r]);
	int flg = 0;
	for(int i = l + 1 ; i < r && !flg ; ++i){
		SEG to(P[l] ,P[i]);
		if(fad > 0){
			if(Main.d * to.d < 0){
				flg = 1;
			}
		}
		else{
			if(Main.d * to.d > 0){
				flg = 1;
			}
		}
	}
	if(!flg) return 0;
	int neg = 0 ,pos = 0;
	for(int i = 0 ; i < n ; ++i){
		if(i == l || i == r) continue;
		SEG now(P[l] ,P[i]);
		if(Main.d * now.d == 0) continue;
		if(Main.d * now.d > 0) ++pos;
		else ++neg;
	}
	if(!neg || !pos){
		if(r == (l + n - 1) % n){
			;
		}
		else return 0;
	}
	for(int i = 0 ; i < n ; ++i){
		SEG t(P[i] ,P[(i + 1) % n]);
		int judge = ok(Main ,t);
		if(i == r && ((i + 1) % n == l)) continue;
		if(judge == 0) return 0;
		if(judge == 1){
			if(i == l || (i + 1) % n == l || i == r || (i + 1) % n == r){
				continue;
			}
			return 0;
		}
	}
	return 1;
}

LL dp[MX][MX];

void test(){
	int n; cin >> n;
	while(n--){
		int x ,y;
		cin >> x >> y;
		printf("(%d,%d)\n" ,x ,y);
	}
	SEG a(VECTOR(1 ,0) ,VECTOR(-1 ,0)) ,b(VECTOR(0 ,0) ,VECTOR(1 ,0));
	cout << ok(a ,b) <<endl;
	return ;
}

int main(){
	// test();
	cin >> n;
	for(int i = 0 ; i < n ; ++i){
		P[i].Read();
	}
	for(int i = 0 ; i < n ; ++i){
		fad += P[i] * P[(i + 1) % n];
	}
	// fad 为正数说明是顺时针给出
	for(int i = 1 ; i < n ; ++i){
		dp[i - 1][i] = 1;
	}
	for(int len = 2 ; len <= n ; ++len){
		for(int st = 0 ; st + len < n ; ++st){
			int ed = st + len;
			if(!check(st ,ed)){

				continue;
			}
			for(int k = st + 1 ; k < ed ; ++k){
				dp[st][ed] = (dp[st][ed] + dp[st][k] * dp[k][ed]) % MOD;
			}
		}
	}
	cout << dp[0][n - 1] << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long

const int MX = 200 + 23;
const LL MOD = 1e9 + 7;

struct VECTOR{
	LL x ,y;
	VECTOR(LL X = 0 ,LL Y = 0){x = X ,y = Y;}
	VECTOR operator +(const VECTOR &B)const{return VECTOR(x + B.x ,y + B.y);}
	VECTOR operator -(const VECTOR &B)const{return VECTOR(x - B.x ,y - B.y);}
	LL operator *(const VECTOR &B)const{return x * B.y - y * B.x;}
	bool operator ==(const VECTOR &B)const{return x == B.x && y == B.y;}
	void Read(){cin >> x >> y;}
}P[MX];

struct SEG{
	VECTOR st ,d;
	SEG(){st = d = VECTOR(0 ,0);}
	SEG(VECTOR __st ,VECTOR __ed){
		st = __st ,d = __ed - __st;
	};
	void turn(){
		st = st + d;
		d = VECTOR(0 ,0) - d;
	}
};

int sgn(LL x){
	if(!x) return 0;
	return x > 0 ? 1 : -1;
}

bool PingXing(VECTOR A ,VECTOR B){
	return A.x * B.y - A.y * B.x == 0;
}

bool online(SEG a ,VECTOR b){
	// 询问点 b 是否在 a 上（含边缘）
	bool xless = b.x < a.st.x && b.x < (a.st + a.d).x;
	bool xmore = b.x > a.st.x && b.x > (a.st + a.d).x;
	bool yless = b.y < a.st.y && b.y < (a.st + a.d).y;
	bool ymore = b.y > a.st.y && b.y > (a.st + a.d).y;
	return (xless + xmore + yless + ymore) == 0;
}

int ok(SEG a ,SEG b){
	// 0 绝对不行
	// 1 共点
	// 2 绝对可以
	LL test1 = sgn(a.d * (b.st - a.st)) * sgn(a.d * (b.st + b.d - a.st));
	LL test2 = sgn(b.d * (a.st - b.st)) * sgn(b.d * (a.st + a.d - b.st));
	if(test1 > 0 || test2 > 0){
		// 连交点都没有
		return 2;
	}
	if(PingXing(a.d ,b.d)){
		// 有交点且平行就是共线
		if(online(a ,b.st) || online(a ,b.st + b.d)
		|| online(b ,a.st) || online(b ,a.st + a.d)){
			// 二者有交
			if(sgn(a.d.x) != sgn(b.d.x) || sgn(a.d.y) != sgn(b.d.y)){
				b.turn();
			}
			if(a.st + a.d == b.st || b.st + b.d == a.st)
				return 1;
			return 0;
		}

		return 2;
	}
	return (test1 <= 0 && test2 <= 0);
}

LL fad;
int n;
int check(int l ,int r){

/*	if(l == 0 && r == 5){
		puts("WTf");
	}
	*/
	SEG Main(P[l] ,P[r]);
	if(fad > 0){
		if(Main.d * (P[l + 1] - P[l]) > 0) return 0;
	}
	else{
		if(Main.d * (P[l + 1] - P[l]) < 0) return 0;
	}
	int neg = 0 ,pos = 0;
	for(int i = 0 ; i < n ; ++i){
		if(i == l || i == r) continue;
		SEG now(P[l] ,P[i]);
		if(Main.d * now.d == 0) continue;
		if(Main.d * now.d > 0) ++pos;
		else ++neg;
	}
	if(!neg || !pos){
		if(r == (l + n - 1) % n){
			;
		}
		else return 0;
	}
	for(int i = 0 ; i < n ; ++i){
		SEG t(P[i] ,P[(i + 1) % n]);
		int judge = ok(Main ,t);
		if(i == r && ((i + 1) % n == l)) continue;
		if(judge == 0) return 0;
		if(judge == 1){
			if(i == l || (i + 1) % n == l || i == r || (i + 1) % n == r){
				continue;
			}
			return 0;
		}
	}
	return 1;
}

LL dp[MX][MX];

void test(){
	int n; cin >> n;
	while(n--){
		int x ,y;
		cin >> x >> y;
		printf("(%d,%d)\n" ,x ,y);
	}
	SEG a(VECTOR(1 ,0) ,VECTOR(-1 ,0)) ,b(VECTOR(0 ,0) ,VECTOR(1 ,0));
	cout << ok(a ,b) <<endl;
	return ;
}

int main(){
	// test();
	cin >> n;
	for(int i = 0 ; i < n ; ++i){
		P[i].Read();
	}
	for(int i = 0 ; i < n ; ++i){
		fad += P[i] * P[(i + 1) % n];
	}
	// fad 为正数说明是顺时针给出
	for(int i = 1 ; i < n ; ++i){
		dp[i - 1][i] = 1;
	}
	for(int len = 2 ; len <= n ; ++len){
		for(int st = 0 ; st + len < n ; ++st){
			int ed = st + len;
			if(!check(st ,ed)){
				// printf("[%d ,%d] is bad!\n" ,st ,ed);

				continue;
			}
			for(int k = st + 1 ; k < ed ; ++k){
				dp[st][ed] = (dp[st][ed] + dp[st][k] * dp[k][ed]) % MOD;
			}
			// printf("dp[%d][%d] = %lld\n" ,st ,ed ,dp[st][ed]);
		}
	}
	cout << dp[0][n - 1] << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long

const int MX = 200 + 23;
const LL MOD = 1e9 + 7;

struct VECTOR{
	LL x ,y;
	VECTOR(LL X = 0 ,LL Y = 0){x = X ,y = Y;}
	VECTOR operator +(const VECTOR &B)const{return VECTOR(x + B.x ,y + B.y);}
	VECTOR operator -(const VECTOR &B)const{return VECTOR(x - B.x ,y - B.y);}
	LL operator *(const VECTOR &B)const{return x * B.y - y * B.x;}
	bool operator ==(const VECTOR &B)const{return x == B.x && y == B.y;}
	void Read(){cin >> x >> y;}
}P[MX];

struct SEG{
	VECTOR st ,d;
	SEG(){st = d = VECTOR(0 ,0);}
	SEG(VECTOR __st ,VECTOR __ed){
		st = __st ,d = __ed - __st;
	};
	void turn(){
		st = st + d;
		d = VECTOR(0 ,0) - d;
	}
};

int sgn(LL x){
	if(!x) return 0;
	return x > 0 ? 1 : -1;
}

bool PingXing(VECTOR A ,VECTOR B){
	return A.x * B.y - A.y * B.x == 0;
}

bool online(SEG a ,VECTOR b){
	// 询问点 b 是否在 a 上（含边缘）
	bool xless = b.x < a.st.x && b.x < (a.st + a.d).x;
	bool xmore = b.x > a.st.x && b.x > (a.st + a.d).x;
	bool yless = b.y < a.st.y && b.y < (a.st + a.d).y;
	bool ymore = b.y > a.st.y && b.y > (a.st + a.d).y;
	return (xless + xmore + yless + ymore) == 0;
}

int ok(SEG a ,SEG b){
	// 0 绝对不行
	// 1 共点
	// 2 绝对可以
	LL test1 = sgn(a.d * (b.st - a.st)) * sgn(a.d * (b.st + b.d - a.st));
	LL test2 = sgn(b.d * (a.st - b.st)) * sgn(b.d * (a.st + a.d - b.st));
	if(test1 > 0 || test2 > 0){
		// 连交点都没有
		return 2;
	}
	if(PingXing(a.d ,b.d)){
		// 有交点且平行就是共线
		if(online(a ,b.st) || online(a ,b.st + b.d)
		|| online(b ,a.st) || online(b ,a.st + a.d)){
			// 二者有交
			if(sgn(a.d.x) != sgn(b.d.x) || sgn(a.d.y) != sgn(b.d.y)){
				b.turn();
			}
			if(a.st + a.d == b.st || b.st + b.d == a.st)
				return 1;
			return 0;
		}

		return 2;
	}
	return (test1 <= 0 && test2 <= 0);
}

int n;
int check(int l ,int r){

	if(l == 0 && r == 5){
		puts("WTf");
	}
	SEG Main(P[l] ,P[r]);
	if(Main.d * (P[l + 1] - P[l]) > 0) return 0;
	int neg = 0 ,pos = 0;
	for(int i = 0 ; i < n ; ++i){
		if(i == l || i == r) continue;
		SEG now(P[l] ,P[i]);
		if(Main.d * now.d == 0) continue;
		if(Main.d * now.d > 0) ++pos;
		else ++neg;
	}
	if(!neg || !pos){
		if(r == (l + n - 1) % n){
			;
		}
		else return 0;
	}
	for(int i = 0 ; i < n ; ++i){
		SEG t(P[i] ,P[(i + 1) % n]);
		int judge = ok(Main ,t);
		if(i == r && ((i + 1) % n == l)) continue;
		if(judge == 0) return 0;
		if(judge == 1){
			if(i == l || (i + 1) % n == l || i == r || (i + 1) % n == r){
				continue;
			}
			return 0;
		}
	}
	return 1;
}

LL dp[MX][MX];

void test(){
	int n; cin >> n;
	while(n--){
		int x ,y;
		cin >> x >> y;
		printf("(%d,%d)\n" ,x ,y);
	}
	SEG a(VECTOR(1 ,0) ,VECTOR(-1 ,0)) ,b(VECTOR(0 ,0) ,VECTOR(1 ,0));
	cout << ok(a ,b) <<endl;
	return ;
}

int main(){
	// test();
	cin >> n;
	for(int i = 0 ; i < n ; ++i){
		P[i].Read();
	}
	for(int i = 1 ; i < n ; ++i){
		dp[i - 1][i] = 1;
	}
	for(int len = 2 ; len <= n ; ++len){
		for(int st = 0 ; st + len < n ; ++st){
			int ed = st + len;
			if(!check(st ,ed)){
				//printf("[%d ,%d] is bad!\n" ,st ,ed);
				continue;
			}
			for(int k = st + 1 ; k < ed ; ++k){
				dp[st][ed] = (dp[st][ed] + dp[st][k] * dp[k][ed]) % MOD;
			}
		//	printf("dp[%d][%d] = %lld\n" ,st ,ed ,dp[st][ed]);
		}
	}
	cout << dp[0][n - 1] << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long

const int MX = 200 + 23;
const LL MOD = 1e9 + 7;

struct VECTOR{
	LL x ,y;
	VECTOR(LL X = 0 ,LL Y = 0){x = X ,y = Y;}
	VECTOR operator +(const VECTOR &B)const{return VECTOR(x + B.x ,y + B.y);}
	VECTOR operator -(const VECTOR &B)const{return VECTOR(x - B.x ,y - B.y);}
	LL operator *(const VECTOR &B)const{return x * B.y - y * B.x;}
	bool operator ==(const VECTOR &B)const{return x == B.x && y == B.y;}
	void Read(){cin >> x >> y;}
}P[MX];

struct SEG{
	VECTOR st ,d;
	SEG(){st = d = VECTOR(0 ,0);}
	SEG(VECTOR __st ,VECTOR __ed){
		st = __st ,d = __ed - __st;
	};
	void turn(){
		st = st + d;
		d = VECTOR(0 ,0) - d;
	}
};

int sgn(LL x){
	if(!x) return 0;
	return x > 0 ? 1 : -1;
}

bool PingXing(VECTOR A ,VECTOR B){
	return A.x * B.y - A.y * B.x == 0;
}

bool online(SEG a ,VECTOR b){
	// 询问点 b 是否在 a 上（含边缘）
	bool xless = b.x < a.st.x && b.x < (a.st + a.d).x;
	bool xmore = b.x > a.st.x && b.x > (a.st + a.d).x;
	bool yless = b.y < a.st.y && b.y < (a.st + a.d).y;
	bool ymore = b.y > a.st.y && b.y > (a.st + a.d).y;
	return (xless + xmore + yless + ymore) == 0;
}

int ok(SEG a ,SEG b){
	// 0 绝对不行
	// 1 共点
	// 2 绝对可以
	LL test1 = sgn(a.d * (b.st - a.st)) * sgn(a.d * (b.st + b.d - a.st));
	LL test2 = sgn(b.d * (a.st - b.st)) * sgn(b.d * (a.st + a.d - b.st));
	if(test1 > 0 || test2 > 0){
		// 连交点都没有
		return 2;
	}
	if(PingXing(a.d ,b.d)){
		// 有交点且平行就是共线
		if(online(a ,b.st) || online(a ,b.st + b.d)
		|| online(b ,a.st) || online(b ,a.st + a.d)){
			// 二者有交
			if(sgn(a.d.x) != sgn(b.d.x) || sgn(a.d.y) != sgn(b.d.y)){
				b.turn();
			}
			if(a.st + a.d == b.st || b.st + b.d == a.st)
				return 1;
			return 0;
		}

		return 2;
	}
	return (test1 <= 0 && test2 <= 0);
}

LL fad;
int n;
int check(int l ,int r){

	SEG Main(P[l] ,P[r]);
	int flg = 0;
	for(int i = l + 1 ; i < r && !flg ; ++i){
		SEG to(P[l] ,P[i]);
		if(fad > 0){
			if(Main.d * to.d < 0){
				flg = 1;
			}
		}
		else{
			if(Main.d * to.d > 0){
				flg = 1;
			}
		}
	}
	if(!flg) return 0;
	/*
	int neg = 0 ,pos = 0;
	for(int i = 0 ; i < n ; ++i){
		if(i == l || i == r) continue;
		SEG now(P[l] ,P[i]);
		if(Main.d * now.d == 0) continue;
		if(Main.d * now.d > 0) ++pos;
		else ++neg;
	}
	if(!neg || !pos){
		if(r == (l + n - 1) % n){
			;
		}
		else return 0;
	}*/
	for(int i = 0 ; i < n ; ++i){
		SEG t(P[i] ,P[(i + 1) % n]);
		int judge = ok(Main ,t);
		if(i == r && ((i + 1) % n == l)) continue;
		if(judge == 0) return 0;
		if(judge == 1){
			if(i == l || (i + 1) % n == l || i == r || (i + 1) % n == r){
				continue;
			}
			return 0;
		}
	}
	return 1;
}

LL dp[MX][MX];

void test(){
	int n; cin >> n;
	while(n--){
		int x ,y;
		cin >> x >> y;
		printf("(%d,%d)\n" ,x ,y);
	}
	SEG a(VECTOR(1 ,0) ,VECTOR(-1 ,0)) ,b(VECTOR(0 ,0) ,VECTOR(1 ,0));
	cout << ok(a ,b) <<endl;
	return ;
}

int main(){
	// test();
	cin >> n;
	for(int i = 0 ; i < n ; ++i){
		P[i].Read();
	}
	for(int i = 0 ; i < n ; ++i){
		fad += P[i] * P[(i + 1) % n];
	}
	// fad 为正数说明是顺时针给出
	for(int i = 1 ; i < n ; ++i){
		dp[i - 1][i] = 1;
	}
	for(int len = 2 ; len <= n ; ++len){
		for(int st = 0 ; st + len < n ; ++st){
			int ed = st + len;
			if(!check(st ,ed)){
				continue;
			}
			for(int k = st + 1 ; k < ed ; ++k){
				dp[st][ed] = (dp[st][ed] + dp[st][k] * dp[k][ed]) % MOD;
			}
		}
	}
	cout << dp[0][n - 1] << endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll dp[205][205], n;
int main(){
	cin>>n;
	vector<pair<ll, ll> >pt(n);
	for(ll i=0; i<n; i++){
		cin>>pt[i].first>>pt[i].second;
	}
	ll ori=0;
	for(ll i=0; i<n; i++){
		ori+=pt[i].first*pt[(i+1)%n].second
			-pt[i].second*pt[(i+1)%n].first;
	}
//5	cout<<ori<<endl;
	if(ori>0){
		reverse(pt.begin(), pt.end());
//		for(ll i=0; i<n; i++) cout<<pt[i].first<<" "<<pt[i].second<<endl;
	}
	for(ll len=1; len<n; len++){
		for(ll st=0; st<n-len; st++){
			ll l=st, r=st+len;
			if(len==1) dp[l][r]=1ll;
			else{
				dp[l][r]=0;
				for(ll i=l+1; i<r; i++){
					if((pt[i].second-pt[l].second)*(pt[r].first-pt[i].first)
						-(pt[i].first-pt[l].first)*(pt[r].second-pt[i].second)>0){
			//			cout<<l<<" "<<i<<" "<<r<<" yey masuk\n";
						dp[l][r]=(dp[l][r]+(dp[l][i]*dp[i][r])%mod)%mod;
					}
				}
			}
		}
	}
//	for(ll i=0; i<n; i++){
//		for(ll j=0; j<n; j++){
//			cout<<dp[i][j]<<" ";
//	}
//		cout<<endl;
//	}
	cout<<dp[0][n-1]<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll dp[205][205], n;
int main(){
	cin>>n;
	vector<pair<ll, ll> >pt(n);
	for(ll i=0; i<n; i++){
		cin>>pt[i].first>>pt[i].second;
	}
	ll ori=0;
	for(ll i=0; i<n; i++){
		ori+=pt[i].first*pt[(i+1)%n].second
			-pt[i].second*pt[(i+1)%n].first;
	}
	if(ori>0){
		reverse(pt.begin(), pt.end());
//		for(ll i=0; i<n; i++) cout<<pt[i].first<<" "<<pt[i].second<<endl;
	}
	for(ll len=1; len<n; len++){
		for(ll st=0; st<n-len; st++){
			ll l=st, r=st+len;
			if(len<=2) dp[l][r]=1ll;
			else{
				dp[l][r]=0;
				for(ll i=l+1; i<r; i++){
					if((pt[i].second-pt[l].second)*(pt[r].first-pt[i].first)
						-(pt[i].first-pt[l].first)*(pt[r].second-pt[i].second)>0){
				//		cout<<l<<" "<<i<<" "<<r<<" BRUH\n";
						dp[l][r]=(dp[l][r]+dp[l][i]*dp[i][r])%mod;
					}
				}
			}
		}
	}
//	for(ll i=0; i<n; i++){
//		for(ll j=0; j<n; j++){
//			cout<<dp[i][j]<<" ";
//	}
	//	cout<<endl;
//	}
	cout<<dp[0][n-1]<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll dp[205][205], n;
int main(){
	cin>>n;
	vector<pair<ll, ll> >pt(n);
	for(ll i=0; i<n; i++){
		cin>>pt[i].first>>pt[i].second;
	}
	ll ori=0;
	for(ll i=0; i<n; i++){
		ori+=pt[i].first*pt[(i+1)%n].second
			-pt[i].second*pt[(i+1)%n].first;
	}
//5	cout<<ori<<endl;
	if(ori>0){
		reverse(pt.begin(), pt.end());
//		for(ll i=0; i<n; i++) cout<<pt[i].first<<" "<<pt[i].second<<endl;
	}
	for(ll len=1; len<n; len++){
		for(ll st=0; st<n-len; st++){
			ll l=st, r=st+len;
			if(len==1) dp[l][r]=1ll;
			else{
				dp[l][r]=0;
				for(ll i=l+1; i<r; i++){
					ll a=pt[i].first-pt[l].first, b=pt[i].second-pt[l].second;
					ll c=pt[i].first-pt[r].first, d=pt[i].second-pt[r].second;
					if(a*d-b*c>0){
			//			cout<<l<<" "<<i<<" "<<r<<" yey masuk\n";
						dp[l][r]=(dp[l][r]+(dp[l][i]*dp[i][r])%mod)%mod;
					}
				}
			}
		}
	}
//	for(ll i=0; i<n; i++){
//		for(ll j=0; j<n; j++){
//			cout<<dp[i][j]<<" ";
//	}
//		cout<<endl;
//	}
	cout<<dp[0][n-1]<<endl;
	return 0;
}


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<iomanip>
#include<map>
#include<stack>
#include<set>
#include<bitset>
#include<vector>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-6
#define mp make_pair
#define pb push_back
#define de(x) cout<<#x<<":"<<x<<" ";
#define DE(x) cout<<#x<<":"<<x<<endl;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<pii,pii> ppp;
const int maxn=210;
const ll mod=1000000007;
ll read()
{
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct point{ll x,y;};
int n;
point p[maxn];
ll f[maxn][maxn];
ll operator^(point p1,point p2){return p1.x*p2.y-p2.x*p1.y;}
point operator-(point p1,point p2){return (point){p1.x-p2.x,p1.y-p2.y};}
void init()
{
    int i,j;
    ll x=0;
    p[n+1]=p[1];
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)f[i][j]=-1;
    for(i=1;i<=n;i++)f[i][i+1]=1;
    for(i=1;i<=n;i++)x+=p[i]^p[i+1];
    if(x<0)reverse(p+1,p+n+2);
}
ll dfs(int l,int r)
{
    if(f[l][r]!=-1)return f[l][r];
    int i;
    f[l][r]=0;
    for(i=l+1;i<r;i++)
        if(((p[l]-p[r])^(p[i]-p[r]))>0)f[l][r]=(f[l][r]+dfs(l,i)*dfs(i,r)%mod)%mod;
    return f[l][r];
}
int main()
{
    int i,j,k;
    cin>>n;
    for(i=1;i<=n;i++)p[i].x=read(),p[i].y=read();
    init();
    cout<<dfs(1,n)<<endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 205;
const ll M = 1e9+7;

ll dp[N][N];
struct P{
  ll x,y;
  P(){}
  P(ll x,ll y):x(x),y(y){}
} p[N];

inline ll cal(P a,P b){
	return a.x*b.y-a.y*b.x;
}

inline P Pc(P a,P b){
	return P(a.x-b.x,a.y-b.y);
}

inline void re(ll n){
	ll i = 0,j = n-1;
	while(i < j){
		P t = p[i];
		p[i] = p[j];
		p[j] = t;
		i++;
		j--;
	}
	return ;
}

int main() {
  	ll n,sum = 0;
  	scanf("%lld",&n);
  	for(ll i = 0;i < n;++i) scanf("%lld%lld",&p[i].x,&p[i].y);
  	for(ll i = 1;i < n-1;++i) sum += cal(Pc(p[i],p[0]),Pc(p[i+1],p[0]));
  	if (sum < 0) re(n);

  	for(ll i = 0;i < n;++i) dp[i][(i+1)%n] = 1;
  	for(ll l = 2;l <= n;++l){
	    for(ll i = 0;i < n;++i){
	      	ll j = (i+l)%n;
	      	for(ll k = (i+1)%n;k != j;(++k) %= n)
	        if (cal(Pc(p[k],p[i]),Pc(p[j],p[i])) > 0) (dp[i][j]+=dp[i][k]*dp[k][j]) %= M;
	    }
	}
  	printf("%lld\n",dp[0][n - 1]);
  	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 205,P = 1000000007;
using ll = long long;
struct Point {int x,y;};
Point operator+ (const Point &a,const Point &b) {return {a.x + b.x,a.y + b.y};}
Point operator- (const Point &a,const Point &b) {return {a.x - b.x,a.y - b.y};}
ll cross(const Point &a,const Point &b) {return a.x * 1ll * b.y - a.y * 1ll * b.x;}
int n;
ll dp[N][N];Point a[N];
int main ()
{
    ios::sync_with_stdio(false);
    cin >> n;
    for (int i = 1;i <= n;i++) cin >> a[i].x >> a[i].y;
    ll sum = cross(a[n],a[1]);
    for (int i = 1;i < n;i++) sum += cross(a[i],a[i + 1]);
    if (sum < 0) reverse(a + 1,a + n + 1);
    for (int i = 1;i < n;i++) dp[i][i + 1] = 1;
    for (int l = 3;l <= n;l++)
        for (int i = 1;i + l - 1 <= n;i++)
        {
            int j = i + l - 1;
            for (int k = i + 1;k < j;k++)
                if (cross(a[k] - a[i],a[j] - a[k]) > 0)
                    dp[i][j] = (dp[i][j] + dp[i][k] * dp[k][j] % P) % P;
        }
    cout << dp[1][n] << endl;
    return 0;
}//hellobig_tq


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#define inf 200000000
#define maxm 10005
#define maxn 205
#define md 1000000007
using namespace std;
typedef long long int ll;
struct point
{
	ll x,y;
	ll operator * (const point& c) const
	{
		return x*c.y-y*c.x;
	}
	point operator - (const point& c) const
	{
		return (point){x-c.x,y-c.y};
	}
}p[maxn];
int n;
ll dp[maxn][maxn];
int main()
{
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
		{
			scanf("%lld%lld",&p[i].x,&p[i].y);
		}
		ll tmp=p[n]*p[1];
		for(int i=1;i<n;i++)tmp+=p[i]*p[i+1];
		if(tmp<0)
		{
			reverse(p+1,p+n+1);
		}
		for(int i=1;i<n;i++)dp[i][i+1]=1;
		for(int k=2;k<n;k++)
		for(int i=1;i+k<=n;i++)
		for(int j=1;j<k;j++)
		{
			if((p[i+j]-p[i])*(p[i+k]-p[i])>0)
			{
				dp[i][i+k]=(dp[i][i+k]+(dp[i][i+j]*dp[i+j][i+k]))%md;
			}
		}
		printf("%lld\n",dp[1][n]);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const ll maxn = 205;
const ll mod = 1e9 + 7;
int oppo = 1;
ll n;
pair<ll, ll> pp[maxn];
ll dp[maxn][maxn];

struct Poll {
	ll x, y;
};

Poll makep(ll a, ll b){
	Poll x;
	x.x = a;
	x.y = b;

	return x;
}
ll ccw(Poll a, Poll b, Poll c) {
    ll area = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
    return area;
}
ll ccwp(ll a, ll b, ll c){
	return ccw(makep(pp[a].first, pp[a].second), makep(pp[b].first, pp[b].second), makep(pp[c].first, pp[c].second));
}

ll dfs(ll a, ll b){
	if(dp[a][b] == -1){
		ll &res = dp[a][b];

		res = 0;
		if(a > b){
			return res;
		} else if(a + 1 == b){
			res = 1;
			return res;
		}

		for(ll i = a + 1; i < b; i++){
			if(ccwp(a, b, i) * oppo < 0){
				res += dfs(a, i) * dfs(i, b);
				res %= mod;
			}
		}
	}

	return dp[a][b];
}

int main(){
    ios::sync_with_stdio(false);

    cin >> n;

    for(ll i = 0; i < n; i++){
    	cin >> pp[i].second >> pp[i].first;
    }

    for(ll i = 0; i < n; i++){
    	for(ll j = 0; j < n; j++){
    		dp[i][j] = -1;
    	}
    }
    for(ll i = 0; i < n; i++){
    	for(ll j = i + 1; j < n; j++){
    		for(ll k = i + 1; k < j; k++){
    			if(ccwp(i, j, k) > 0){
    				oppo = -1;
    			}
    		}
    	}
    }

    cout << dfs(0, n - 1);

}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const ll maxn = 205;
const ll mod = 1e9 + 7;
int oppo = 1;
ll n;
pair<ll, ll> pp[maxn];
ll dp[maxn][maxn];

struct Poll {
	ll x, y;
};

Poll makep(ll a, ll b){
	Poll x;
	x.x = a;
	x.y = b;

	return x;
}
ll ccw(Poll a, Poll b, Poll c) {
	ll area = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
	return area;
}
ll ccwp(ll a, ll b, ll c){
	return ccw(makep(pp[a].first, pp[a].second), makep(pp[b].first, pp[b].second), makep(pp[c].first, pp[c].second));
}

ll dfs(ll a, ll b){
	if(dp[a][b] == -1){
		ll &res = dp[a][b];

		res = 0;
		if(a > b){
			return res;
		} else if(a + 1 == b){
			res = 1;
			return res;
		}

		for(ll i = a + 1; i < b; i++){
			if(ccwp(a, b, i) * oppo < 0){
				res += dfs(a, i) * dfs(i, b);
				res %= mod;
			}
		}
	}

	return dp[a][b];
}

int main(){
	ios::sync_with_stdio(false);

	cin >> n;

	for(ll i = 0; i < n; i++){
		cin >> pp[i].first >> pp[i].second;
	}

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

	ll area = 0LL;
	for(ll i = 1; i < n - 1; i++){
		area += ccwp(0, i, i + 1);
	}
	if(area < 0){
		oppo = -1;
	}

	cout << dfs(0, n - 1);

}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const ll maxn = 205;
const ll mod = 1e9 + 7;
int oppo = 1;
ll n;
pair<ll, ll> pp[maxn];
ll dp[maxn][maxn];

struct Poll {
	ll x, y;
};

Poll makep(ll a, ll b){
	Poll x;
	x.x = a;
	x.y = b;

	return x;
}
ll ccw(Poll a, Poll b, Poll c) {
	ll area = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
	return area;
}
ll ccwp(ll a, ll b, ll c){
	return ccw(makep(pp[a].first, pp[a].second), makep(pp[b].first, pp[b].second), makep(pp[c].first, pp[c].second));
}

ll dfs(ll a, ll b){
	if(dp[a][b] == -1){
		ll &res = dp[a][b];

		res = 0;
		if(a > b){
			return res;
		} else if(a + 1 == b){
			res = 1;
			return res;
		}

		for(ll i = a + 1; i < b; i++){
			if(ccwp(a, b, i) * oppo < 0){
				res += dfs(a, i) * dfs(i, b);
				res %= mod;
			}
		}
	}

	return dp[a][b];
}

int main(){
	ios::sync_with_stdio(false);

	cin >> n;

	for(ll i = 0; i < n; i++){
		cin >> pp[i].first >> pp[i].second;
	}

	for(ll i = 0; i < n; i++){
		for(ll j = 0; j < n; j++){
			dp[i][j] = -1;
		}
	}
	for(ll i = 0; i < n; i++){
		for(ll j = i + 1; j < n; j++){
			for(ll k = i + 1; k < j; k++){
				if(ccwp(i, j, k) > 0){
					oppo = -1;
				}
			}
		}
	}

	cout << dfs(0, n - 1);

}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const ll maxn = 205;
const ll mod = 1e9 + 7;
ll n;
pair<ll, ll> pp[maxn];
ll dp[maxn][maxn];

struct Poll {
	ll x, y;
};

Poll makep(ll a, ll b){
	Poll x;
	x.x = a;
	x.y = b;

	return x;
}
ll ccw(Poll a, Poll b, Poll c) {
    ll area = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
    return area;
}
ll ccwp(ll a, ll b, ll c){
	return ccw(makep(pp[a].first, pp[a].second), makep(pp[b].first, pp[b].second), makep(pp[c].first, pp[c].second));
}

ll dfs(ll a, ll b){
	if(dp[a][b] == -1){
		ll &res = dp[a][b];

		res = 0;
		if(a > b){
			return res;
		} else if(a + 1 == b){
			res = 1;
			return res;
		}

		for(ll i = a + 1; i < b; i++){
			if(ccwp(a, b, i) > 0){
				res += dfs(a, i) * dfs(i, b);
				res %= mod;
			}
		}
	}

	return dp[a][b];
}

int main(){
    ios::sync_with_stdio(false);

    cin >> n;

    for(ll i = 0; i < n; i++){
    	cin >> pp[i].second >> pp[i].first;
    }

    for(ll i = 1; i < n - 1; i++){
    	if(ccwp(0, 1, i) < 0){
    		reverse(pp, pp + n);
    		break;
    	}
    }
    for(ll i = 0; i < n; i++){
    	for(ll j = 0; j < n; j++){
    		dp[i][j] = -1;
    	}
    }

    cout << dfs(0, n - 1);

}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int maxn = 205;
const ll mod = 1e9 + 7;
int n;
pair<int, int> pp[maxn]	;
ll dp[maxn][maxn];

struct Point {
	int x, y;
};

Point makep(int a, int b){
	Point x;
	x.x = a;
	x.y = b;

	return x;
}
ll ccw(Point a, Point b, Point c) {
    int area = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
    return area;
}
ll ccwp(int a, int b, int c){
	return ccw(makep(pp[a].first, pp[a].second), makep(pp[b].first, pp[b].second), makep(pp[c].first, pp[c].second));
}

ll dfs(ll a, ll b){
	if(dp[a][b] == -1){
		ll &res = dp[a][b];

		res = 0;
		if((a + b != 1)  and ((a + 1) % n == b or (b + 1) % n == a)){
			res = 1;
			return res;
		}

		pair<int, int> edg[n];
		for(int i = 0; i < n; i++){
			if(i != a and i != b and ccwp(a, b, i) > 0){
				edg[i].first = ccwp(a, b, i);
				edg[i].second = i;
			} else {
				edg[i].first = 100000000;
				edg[i].second = -1;
			}
		}
		sort(edg, edg + n);

		int lastgood = -1;
		for(int i = 0; i < n; i++){
			if(edg[i].second == -1){
				continue;
			}

			if(lastgood == -1 or ccwp(a, b, lastgood) <= 0 or ccwp(a, edg[i].second, lastgood) <= 0 or ccwp(edg[i].second, b, lastgood) <= 0){
				res += dfs(edg[i].second, b) * dfs(a, edg[i].second);
				res %= mod;

				lastgood = edg[i].second;
			}
		}
	}

	return dp[a][b];
}
int main(){
    ios::sync_with_stdio(false);

    cin >> n;

    for(int i = 0; i < n; i++){
    	cin >> pp[i].second >> pp[i].first;
    }

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

    cout << dfs(0, 1) + dfs(1, 0);

}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int maxn = 205;
const ll mod = 1e9 + 7;
int n;
pair<int, int> pp[maxn];
ll dp[maxn][maxn];

struct Point {
	int x, y;
};

Point makep(int a, int b){
	Point x;
	x.x = a;
	x.y = b;

	return x;
}
ll ccw(Point a, Point b, Point c) {
    int area = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
    return area;
}
ll ccwp(int a, int b, int c){
	return ccw(makep(pp[a].first, pp[a].second), makep(pp[b].first, pp[b].second), makep(pp[c].first, pp[c].second));
}

ll dfs(ll a, ll b){
	if(dp[a][b] == -1){
		ll &res = dp[a][b];

		res = 0;
		if((a + b != 1) and ((a + 1) % n == b or (b + 1) % n == a)){
			res = 1;
			return res;
		}

		pair<int, int> edg[n];
		for(int i = 0; i < n; i++){
			if(i != a and i != b and ccwp(a, b, i) > 0){
				edg[i].first = ccwp(a, b, i);
				edg[i].second = i;
			} else {
				edg[i].first = 100000000;
				edg[i].second = -1;
			}
		}
		sort(edg, edg + n);

		int lastgood = -1;
		for(int i = 0; i < n; i++){
			if(edg[i].second == -1){
				continue;
			}

			if(lastgood == -1 or ccwp(a, b, lastgood) <= 0 or ccwp(a, edg[i].second, lastgood) <= 0 or ccwp(edg[i].second, b, lastgood) <= 0){
				ll part = dfs(edg[i].second, b);
				part %= mod;
				part *= dfs(a, edg[i].second);
				part %= mod;
				res += part;
				res %= mod;

				lastgood = edg[i].second;
			}
		}
	}

	return dp[a][b];
}

int main(){
    ios::sync_with_stdio(false);

    cin >> n;

    for(int i = 0; i < n; i++){
    	cin >> pp[i].second >> pp[i].first;
    }

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

    cout << dfs(0, 1) + dfs(1, 0);

}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <list>
#include <math.h>
#include <time.h>

using namespace std;

#define ERROR {cout << -1 << endl; return 0;}

int minC = 2;
int maxC = 5;

struct book
{
    int value = -1;
    int begin = -1;
    int end = -1;
    int start = -1;
    int count = 0;
    book *prev = 0;
    book *next = 0;

    bool take_place(book *p, int v)
    {
        prev = p;
        if (prev)
            prev->next = this;
        if (value == -1)
            value = v;
        if (value == 1)
            begin = start = 0;
        if (end - begin >= maxC)
            return false;
        if (value != 1)
        {
            int prev_end = prev->start + prev->count;
            if (end != -1 && prev_end > end)
                return false;
            if (begin != -1 && prev_end > begin)
                return false;
            start = prev_end;
        }
        count = max(minC, end - start + 1);
        if (count > maxC)
        {
            start = end - maxC + 1;
            count = end - start + 1;
            if (!prev->expand(start))
                return false;
        }
        return true;
    }

    bool expand(int p)
    {
        if (p - start > maxC)
        {
            if (!prev || !prev->expand(p - maxC))
                return false;
            start = p - maxC;
        }
        if (next && next->begin != -1 && next->begin < p)
            return false;
        count = p - start;
        return true;
    }
};

int n, t;
map<int, book> d;

#ifdef LOCAL_EXECUTION
#include "local.h"
#endif

int main()
{
    cin >> n;
    d.clear();
    for (int i = 0; i < n; i++)
    {
        cin >> t;
        if (t == 0)
            continue;
        d[t].value = t;
        d[t].count++;
        if (d[t].begin == -1)
            d[t].begin = i;
        d[t].end = i;
    }
    if (!d.empty())
    for (int i = 1; i <= d.rbegin()->first; i++)
        if (!d[i].take_place(i == 1 ? 0 : &d[i-1], i))
            ERROR;
    int end = d.empty() ? 0 : d[d.rbegin()->first].start + d[d.rbegin()->first].count;
    int tail = n - end;
    if (tail > 0)
    {
        if (tail == 1)
        {
            if (!d[d.rbegin()->first].expand(n))
                ERROR;
        }
        else
        {
            int end_val = d.empty() ? 1 : d.rbegin()->first + 1;
            int add = tail / 2;
            for (int i = 0; i < add; i++)
                d[end_val++].count = 2;
            if (tail % 2 == 1)
                d[d.rbegin()->first].count++;
        }
    }
    else if (tail < 0)
        ERROR;

    cout << d.rbegin()->first << endl;
    for (int i = 1; i <= d.rbegin()->first; i++)
    for (int j = 0; j < d[i].count; j++)
        cout << i << " ";

    return 0;
}

#ifdef LOCAL_EXECUTION
PROGRAM_END
}
#endif


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <list>
#include <math.h>
#include <time.h>

using namespace std;

#define ERROR {cout << -1 << endl; return 0;}

int minC = 2;
int maxC = 5;

struct book
{
    int value = -1;
    int begin = -1;
    int end = -1;
    int start = -1;
    int count = 0;
    book *prev = 0;
    book *next = 0;

    bool take_place(book *p, int v)
    {
        prev = p;
        if (prev)
            prev->next = this;
        if (value == -1)
            value = v;
        if (value == 1)
            begin = start = 0;
        if (end - begin >= maxC)
            return false;
        if (value != 1)
        {
            int prev_end = prev->start + prev->count;
            if (end != -1 && prev_end > end)
                return false;
            start = prev_end;
        }
        count = max(minC, end - start + 1);
        if (count > maxC)
        {
            start = end - maxC + 1;
            count = end - start + 1;
            if (!prev->expand(start))
                return false;
        }
        return true;
    }

    bool expand(int p)
    {
        if (p - start > maxC)
        {
            if (!prev || !prev->expand(p - maxC))
                return false;
            start = p - maxC;
        }
        if (next && next->begin != -1 && next->begin < p)
            return false;
        count = p - start;
        return true;
    }
};

int n, t;
map<int, book> d;

#ifdef LOCAL_EXECUTION
#include "local.h"
#endif

int main()
{
    cin >> n;
    d.clear();
    for (int i = 0; i < n; i++)
    {
        cin >> t;
        if (t == 0)
            continue;
        d[t].value = t;
        d[t].count++;
        if (d[t].begin == -1)
            d[t].begin = i;
        d[t].end = i;
    }

    if (!d.empty())
    for (int i = 1; i <= d.rbegin()->first; i++)
        if (!d[i].take_place(i == 1 ? 0 : &d[i-1], i))
            ERROR;
    int end = d.empty() ? 0 : d[d.rbegin()->first].start + d[d.rbegin()->first].count;
    int tail = n - end;
    if (tail > 0)
    {
        if (tail == 1)
        {
            if (!d[d.rbegin()->first].expand(n))
                ERROR;
        }
        else
        {
            int end_val = d.empty() ? 1 : d.rbegin()->first + 1;
            int add = tail / 2;
            for (int i = 0; i < add; i++)
                d[end_val++].count = 2;
            if (tail % 2 == 1)
                d[d.rbegin()->first].count++;
        }
    }
    else if (tail < 0)
        ERROR;

    cout << d.rbegin()->first << endl;
    for (int i = 1; i <= d.rbegin()->first; i++)
    for (int j = 0; j < d[i].count; j++)
        cout << i << " ";

    return 0;
}

#ifdef LOCAL_EXECUTION
PROGRAM_END
}
#endif


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <list>
#include <math.h>
#include <time.h>

using namespace std;

#define ERROR {cout << -1 << endl; return 0;}

int minC = 2;
int maxC = 5;

struct book
{
    int value = -1;
    int begin = -1;
    int end = -1;
    int start = -1;
    int count = 0;
    book *prev = 0;
    book *next = 0;

    bool take_place(book *p, int v)
    {
        prev = p;
        if (prev)
            prev->next = this;
        if (value == -1)
            value = v;
        if (value == 1)
            begin = start = 0;
        if (end - begin >= maxC)
            return false;
        if (value != 1)
        {
            int prev_end = prev->start + prev->count;
            if (end != -1 && prev_end > end)
                return false;
            start = prev_end;
        }
        count = max(minC, end - start + 1);
        if (count > maxC)
        {
            start = end - maxC + 1;
            count = end - start + 1;
            if (!prev->expand(start))
                return false;
        }
        return true;
    }

    bool expand(int p)
    {
        if (p - start > maxC)
        {
            if (!prev || !prev->expand(p - maxC))
                return false;
            start = p - maxC;
        }
        if (next && next->begin != -1 && next->begin < p - start)
            return false;
        count = p - start;
        return true;
    }
};

int n, t;
map<int, book> d;

#ifdef LOCAL_EXECUTION
#include "local.h"
#endif

int main()
{
    cin >> n;
    d.clear();
    for (int i = 0; i < n; i++)
    {
        cin >> t;
        if (t == 0)
            continue;
        d[t].value = t;
        d[t].count++;
        if (d[t].begin == -1)
            d[t].begin = i;
        d[t].end = i;
    }
    if (!d.empty())
    for (int i = 1; i <= d.rbegin()->first; i++)
        if (!d[i].take_place(i == 1 ? 0 : &d[i-1], i))
            ERROR;
    int end = d.empty() ? 0 : d[d.rbegin()->first].start + d[d.rbegin()->first].count;
    int tail = n - end;
    if (tail > 0)
    {
        if (tail == 1)
        {
            if (!d[d.rbegin()->first].expand(n))
                ERROR;
        }
        else
        {
            int end_val = d.empty() ? 1 : d.rbegin()->first + 1;
            int add = tail / 2;
            for (int i = 0; i < add; i++)
                d[end_val++].count = 2;
            if (tail % 2 == 1)
                d[d.rbegin()->first].count++;
        }
    }
    else if (tail < 0)
        ERROR;

    cout << d.rbegin()->first << endl;
    for (int i = 1; i <= d.rbegin()->first; i++)
    for (int j = 0; j < d[i].count; j++)
        cout << i << " ";

    return 0;
}

#ifdef LOCAL_EXECUTION
PROGRAM_END
}
#endif


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <list>
#include <math.h>
#include <time.h>

using namespace std;

#define ERROR {cout << -1 << endl; return 0;}

int minC = 2;
int maxC = 5;

struct book
{
    int value = -1;
    int begin = -1;
    int end = -1;
    int start = -1;
    int count = 0;
    book *prev = 0;
    book *next = 0;

    bool take_place(book *p, int v)
    {
        prev = p;
        if (prev)
            prev->next = this;
        if (value == -1)
            value = v;
        if (value == 1)
            begin = start = 0;
        if (end - begin >= maxC)
            return false;
        if (value != 1)
        {
            int prev_end = prev->start + prev->count;
            if ((end != -1 && prev_end > end) ||
                (begin != -1 && prev_end > begin))
                return false;
            start = prev_end;
        }
        count = max(minC, end - start + 1);
        if (count > maxC)
        {
            start = end - maxC + 1;
            count = end - start + 1;
            if (!prev->expand(start))
                return false;
        }
        return true;
    }

    bool expand(int p)
    {
        if (p - start > maxC)
        {
            if (!prev || !prev->expand(p - maxC))
                return false;
            start = p - maxC;
        }
        if (next && next->begin != -1 && next->begin < p - start)
            return false;
        count = p - start;
        return true;
    }
};

int n, t;
map<int, book> d;

#ifdef LOCAL_EXECUTION
#include "local.h"
#endif

int main()
{
    cin >> n;
    d.clear();
    for (int i = 0; i < n; i++)
    {
        cin >> t;
        if (t == 0)
            continue;
        d[t].value = t;
        d[t].count++;
        if (d[t].begin == -1)
            d[t].begin = i;
        d[t].end = i;
    }

    if (!d.empty())
    for (int i = 1; i <= d.rbegin()->first; i++)
        if (!d[i].take_place(i == 1 ? 0 : &d[i-1], i))
            ERROR;
    int end = d.empty() ? 0 : d[d.rbegin()->first].start + d[d.rbegin()->first].count;
    int tail = n - end;
    if (tail > 0)
    {
        if (tail == 1)
        {
            if (!d[d.rbegin()->first].expand(n))
                ERROR;
        }
        else
        {
            int end_val = d.empty() ? 1 : d.rbegin()->first + 1;
            int add = tail / 2;
            for (int i = 0; i < add; i++)
                d[end_val++].count = 2;
            if (tail % 2 == 1)
                d[d.rbegin()->first].count++;
        }
    }
    else if (tail < 0)
        ERROR;

    cout << d.rbegin()->first << endl;
    for (int i = 1; i <= d.rbegin()->first; i++)
    for (int j = 0; j < d[i].count; j++)
        cout << i << " ";

    return 0;
}

#ifdef LOCAL_EXECUTION
PROGRAM_END
}
#endif


#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cassert>

#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <set>

using namespace std;

typedef long long int64;

const int oo = 0x3f3f3f3f;
const int MIN_L = 2;
const int MAX_L = 5;

int N, MaxIndex;
vector<int> Left, Right, Solution;
bool Possible;

void Solve() {
    Possible = true;
    vector<int> previous = vector<int>(MaxIndex + 1, -1);
    for (int i = 1, p = 0; i <= MaxIndex && Possible; ++i) {
        if (Left[i] != -1 && (Right[i] - Left[i] + 1 > MAX_L || (p != 0 && Left[i] <= Right[p])))
            Possible = false;
        if (Left[i] != -1) {
            previous[i] = p;
            p = i;
        }
    }
    if (!Possible)
        return;
    vector< vector<int> > dp = vector< vector<int> >(MaxIndex + 1, vector<int>(MAX_L, false));
    dp[0][0] = true;
    for (int i = 1; i <= MaxIndex; ++i) {
        if (Left[i] == -1)
            continue;
        int j = previous[i];
        for (int l = 0; l < MAX_L; ++l) {
            int end = Right[i] + l, begin = min(Left[i], Right[i] + l + 1 - MIN_L);
            if (end - begin + 1 > MAX_L)
                continue;
            for (; end - begin + 1 <= MAX_L && !dp[i][l]; --begin) {
                for (int prevl = 0; prevl < MAX_L && !dp[i][l]; ++prevl) {
                    int prevEnd = Right[j] + prevl;
                    if (prevEnd >= begin)
                        continue;
                    int space = begin - prevEnd - 1, toFill = i - j - 1;
                    int minSpace = MIN_L * toFill, maxSpace = MAX_L * toFill;
                    if (space < minSpace || maxSpace < space)
                        continue;
                    if (dp[j][prevl])
                        dp[i][l] = true;
                }
            }
        }
    }
    int l = 0;
    for (; l < MAX_L && !dp[MaxIndex][l]; ++l);
    if (l == MAX_L) {
        Possible = false;
        return;
    }
    Solution = vector<int>(N, 0);
    for (int i = MaxIndex; i > 0; i = previous[i]) {
        int j = previous[i];
        int end = Right[i] + l, begin = min(Left[i], Right[i] + l + 1 - MIN_L);
        int fatherL = -1;
        for (; end - begin + 1 <= MAX_L && fatherL == -1; --begin) {
            for (int prevl = 0; prevl < MAX_L && fatherL == -1; ++prevl) {
                int prevEnd = Right[j] + prevl;
                if (prevEnd >= begin)
                    continue;
                int space = begin - prevEnd - 1, toFill = i - j - 1;
                int minSpace = MIN_L * toFill, maxSpace = MAX_L * toFill;
                if (space < minSpace || maxSpace < space)
                    continue;
                if (dp[j][prevl]) {
                    for (int k = prevEnd + 1, index = j + 1; k < begin; ++index) {
                        bool found = false;
                        for (int currentL = MIN_L; !found; ++currentL) {
                            int newSpace = space - currentL, newToFill = toFill - 1;
                            int newMinSpace = MIN_L * newToFill, newMaxSpace = MAX_L * newToFill;
                            if (newSpace < newMinSpace || newMaxSpace < newSpace)
                                continue;
                            found = true;
                            for (; currentL > 0; --currentL, ++k)
                                Solution[k] = index;
                            space = newSpace;
                            toFill = newToFill;
                        }
                    }
                    fatherL = prevl;
                }
            }
            for (int k = begin; k <= end; ++k)
                Solution[k] = i;
        }
        l = fatherL;
    }
    for (int i = Right[MaxIndex] + l + 1, index = MaxIndex + 1; i + 1 < N; i += 2)
        Solution[i] = Solution[i + 1] = index++;
    if (Solution[N - 1] == 0)
        Solution[N - 1] = Solution[N - 2];
}

void Read() {
    cin >> N;
    MaxIndex = 0;
    Left = Right = vector<int>(1, -1);
    for (int i = 0; i < N; ++i) {
        int index;
        cin >> index;
        if (index == 0)
            continue;
        MaxIndex = max(MaxIndex, index);
        if (index >= int(Left.size())) {
            Left.resize(index + 1, -1);
            Right.resize(index + 1, -1);
        }
        if (Left[index] == -1)
            Left[index] = i;
        Right[index] = i;
    }
}

void Print() {
    if (!Possible) {
        cout << "-1\n";
        return;
    }
    cout << Solution[N - 1] << "\n";
    for (int i = 0; i < N; ++i)
        cout << Solution[i] << " ";
    cout << "\n";
}

int main() {
    #ifndef ONLINE_JUDGE
        assert(freopen("e.in", "r", stdin));
        assert(freopen("e.out", "w", stdout));
    #endif
    Read();
    Solve();
    Print();
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cassert>

#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <set>

using namespace std;

typedef long long int64;

const int oo = 0x3f3f3f3f;
const int MIN_L = 2;
const int MAX_L = 5;

int N, MaxIndex;
vector<int> Left, Right, Solution;
bool Possible;

void Solve() {
    Possible = true;
    vector<int> previous = vector<int>(MaxIndex + 1, -1);
    for (int i = 1, p = 0; i <= MaxIndex && Possible; ++i) {
        if (Left[i] != -1 && (Right[i] - Left[i] + 1 > MAX_L || (p != 0 && Left[i] <= Right[p])))
            Possible = false;
        if (Left[i] != -1) {
            previous[i] = p;
            p = i;
        }
    }
    if (!Possible)
        return;
    vector< vector<bool> > dp = vector< vector<bool> >(MaxIndex + 1, vector<bool>(MAX_L, false));
    dp[0][0] = true;
    for (int i = 1; i <= MaxIndex; ++i) {
        if (Left[i] == -1)
            continue;
        int j = previous[i];
        for (int l = 0; l < MAX_L && Right[i] + l < N; ++l) {
            int end = Right[i] + l, begin = min(Left[i], Right[i] + l + 1 - MIN_L);
            if (end - begin + 1 > MAX_L)
                continue;
            for (; end - begin + 1 <= MAX_L && !dp[i][l]; --begin) {
                for (int prevl = 0; prevl < MAX_L && !dp[i][l]; ++prevl) {
                    int prevEnd = Right[j] + prevl;
                    if (prevEnd >= begin)
                        continue;
                    int space = begin - prevEnd - 1, toFill = i - j - 1;
                    int minSpace = MIN_L * toFill, maxSpace = MAX_L * toFill;
                    if (space < minSpace || maxSpace < space)
                        continue;
                    if (dp[j][prevl])
                        dp[i][l] = true;
                }
            }
        }
    }
    int lastl = 0;
    for (; lastl < MAX_L && !dp[MaxIndex][lastl]; ++lastl);
    if (lastl == MAX_L) {
        Possible = false;
        return;
    }
    Solution = vector<int>(N, 0);
    for (int i = MaxIndex, l = lastl; i > 0; i = previous[i]) {
        int j = previous[i];
        int end = Right[i] + l, begin = min(Left[i], Right[i] + l + 1 - MIN_L);
        int fatherL = -1;
        for (; end - begin + 1 <= MAX_L && fatherL == -1; --begin) {
            for (int prevl = 0; prevl < MAX_L && fatherL == -1; ++prevl) {
                int prevEnd = Right[j] + prevl;
                if (prevEnd >= begin)
                    continue;
                int space = begin - prevEnd - 1, toFill = i - j - 1;
                int minSpace = MIN_L * toFill, maxSpace = MAX_L * toFill;
                if (space < minSpace || maxSpace < space)
                    continue;
                if (dp[j][prevl]) {
                    for (int k = prevEnd + 1, index = j + 1; k < begin; ++index) {
                        bool found = false;
                        for (int currentL = MIN_L; !found; ++currentL) {
                            int newSpace = space - currentL, newToFill = toFill - 1;
                            int newMinSpace = MIN_L * newToFill, newMaxSpace = MAX_L * newToFill;
                            if (newSpace < newMinSpace || newMaxSpace < newSpace)
                                continue;
                            found = true;
                            for (; currentL > 0; --currentL, ++k)
                                Solution[k] = index;
                            space = newSpace;
                            toFill = newToFill;
                        }
                    }
                    fatherL = prevl;
                }
            }
            for (int k = begin; k <= end; ++k)
                Solution[k] = i;
        }
        l = fatherL;
    }
    for (int i = Right[MaxIndex] + lastl + 1, index = MaxIndex + 1; i + 1 < N; i += 2)
        Solution[i] = Solution[i + 1] = index++;
    if (Solution[N - 1] == 0)
        Solution[N - 1] = Solution[N - 2];
}

void Read() {
    cin >> N;
    MaxIndex = 0;
    Left = Right = vector<int>(1, -1);
    for (int i = 0; i < N; ++i) {
        int index;
        cin >> index;
        if (index == 0)
            continue;
        MaxIndex = max(MaxIndex, index);
        if (index >= int(Left.size())) {
            Left.resize(index + 1, -1);
            Right.resize(index + 1, -1);
        }
        if (Left[index] == -1)
            Left[index] = i;
        Right[index] = i;
    }
}

void Print() {
    if (!Possible) {
        cout << "-1\n";
        return;
    }
    cout << Solution[N - 1] << "\n";
    for (int i = 0; i < N; ++i)
        cout << Solution[i] << " ";
    cout << "\n";
}

int main() {
    #ifndef ONLINE_JUDGE
        assert(freopen("e.in", "r", stdin));
        assert(freopen("e.out", "w", stdout));
    #endif
    Read();
    Solve();
    Print();
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cassert>

#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <set>

using namespace std;

typedef long long int64;

const int oo = 0x3f3f3f3f;
const int MIN_L = 2;
const int MAX_L = 5;

int N, MaxIndex;
vector<int> Left, Right, Solution;
bool Possible;

void Solve() {
    Possible = true;
    vector<int> previous = vector<int>(MaxIndex + 1, -1);
    for (int i = 1, p = 0; i <= MaxIndex && Possible; ++i) {
        if (Left[i] != -1 && (Right[i] - Left[i] + 1 > MAX_L || (p != 0 && Left[i] <= Right[p])))
            Possible = false;
        if (Left[i] != -1) {
            previous[i] = p;
            p = i;
        }
    }
    if (!Possible)
        return;
    vector< vector<int> > dp = vector< vector<int> >(MaxIndex + 1, vector<int>(MAX_L, false));
    dp[0][0] = true;
    for (int i = 1; i <= MaxIndex; ++i) {
        if (Left[i] == -1)
            continue;
        int j = previous[i];
        for (int l = 0; l < MAX_L; ++l) {
            int end = Right[i] + l, begin = min(Left[i], Right[i] + l + 1 - MIN_L);
            if (end - begin + 1 > MAX_L)
                continue;
            for (; end - begin + 1 <= MAX_L && !dp[i][l]; --begin) {
                for (int prevl = 0; prevl < MAX_L && !dp[i][l]; ++prevl) {
                    int prevEnd = Right[j] + prevl;
                    if (prevEnd >= begin)
                        continue;
                    int space = begin - prevEnd - 1, toFill = i - j - 1;
                    int minSpace = MIN_L * toFill, maxSpace = MAX_L * toFill;
                    if (space < minSpace || maxSpace < space)
                        continue;
                    if (dp[j][prevl])
                        dp[i][l] = true;
                }
            }
        }
    }
    int lastl = 0;
    for (; lastl < MAX_L && !dp[MaxIndex][lastl]; ++lastl);
    if (lastl == MAX_L) {
        Possible = false;
        return;
    }
    Solution = vector<int>(N, 0);
    for (int i = MaxIndex, l = lastl; i > 0; i = previous[i]) {
        int j = previous[i];
        int end = Right[i] + l, begin = min(Left[i], Right[i] + l + 1 - MIN_L);
        int fatherL = -1;
        for (; end - begin + 1 <= MAX_L && fatherL == -1; --begin) {
            for (int prevl = 0; prevl < MAX_L && fatherL == -1; ++prevl) {
                int prevEnd = Right[j] + prevl;
                if (prevEnd >= begin)
                    continue;
                int space = begin - prevEnd - 1, toFill = i - j - 1;
                int minSpace = MIN_L * toFill, maxSpace = MAX_L * toFill;
                if (space < minSpace || maxSpace < space)
                    continue;
                if (dp[j][prevl]) {
                    for (int k = prevEnd + 1, index = j + 1; k < begin; ++index) {
                        bool found = false;
                        for (int currentL = MIN_L; !found; ++currentL) {
                            int newSpace = space - currentL, newToFill = toFill - 1;
                            int newMinSpace = MIN_L * newToFill, newMaxSpace = MAX_L * newToFill;
                            if (newSpace < newMinSpace || newMaxSpace < newSpace)
                                continue;
                            found = true;
                            for (; currentL > 0; --currentL, ++k)
                                Solution[k] = index;
                            space = newSpace;
                            toFill = newToFill;
                        }
                    }
                    fatherL = prevl;
                }
            }
            for (int k = begin; k <= end; ++k)
                Solution[k] = i;
        }
        l = fatherL;
    }
    for (int i = Right[MaxIndex] + lastl + 1, index = MaxIndex + 1; i + 1 < N; i += 2)
        Solution[i] = Solution[i + 1] = index++;
    if (Solution[N - 1] == 0)
        Solution[N - 1] = Solution[N - 2];
}

void Read() {
    cin >> N;
    MaxIndex = 0;
    Left = Right = vector<int>(1, -1);
    for (int i = 0; i < N; ++i) {
        int index;
        cin >> index;
        if (index == 0)
            continue;
        MaxIndex = max(MaxIndex, index);
        if (index >= int(Left.size())) {
            Left.resize(index + 1, -1);
            Right.resize(index + 1, -1);
        }
        if (Left[index] == -1)
            Left[index] = i;
        Right[index] = i;
    }
}

void Print() {
    if (!Possible) {
        cout << "-1\n";
        return;
    }
    cout << Solution[N - 1] << "\n";
    for (int i = 0; i < N; ++i)
        cout << Solution[i] << " ";
    cout << "\n";
}

int main() {
    #ifndef ONLINE_JUDGE
        assert(freopen("e.in", "r", stdin));
        assert(freopen("e.out", "w", stdout));
    #endif
    Read();
    Solve();
    Print();
    return 0;
}


// TwT514 {{{
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <bitset>
#include <queue>
#include <stack>
#include <functional>
#include <utility>
#define SZ(x) ((int)(x).size())
#define FOR(i,c) for (__typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define REP(i,n) for (int i=0; i<(int)(n); i++)
#define REP1(i,a,b) for (int i=(int)(a); i<=(int)(b); i++)
#define ALL(x) (x).begin(),(x).end()
#define MS0(x,n) memset((x),0,(n)*sizeof(*x))
#define MS1(x,n) memset((x),-1,(n)*sizeof(*x))
#define MP make_pair
#define PB push_back
#define RI(a) scanf("%d",&(a))
#define RII(a,b) scanf("%d%d",&(a),&(b))
#define RIII(a,b,c) scanf("%d%d%d",&(a),&(b),&(c))
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef vector<int> VI;
// }}}

#define N 200010
int n,a[N],nxt[N];
set<PII> vis[N];
bool good( int p, int q ) {
    if ( q>5 ) return 0;
    int np=nxt[p];
    if ( np>n ) return 1;
    if ( a[p-1]>a[np] ) return 0;
    int dv=a[np]-a[p-1];
    int di=np-(p-1)-1;
    if ( di/2 < dv-1 ) return 0;
    if ( di/5 > dv ) return 0;
    return 1;
}
bool go( int p, int q ) {
    if ( !good(p,q) ) return 0;
    if ( p>n ) {
        if ( q>=2 && q<=5 ) {
            printf("%d\n",a[n]);
            REP1(i,1,n) printf("%d%c",a[i],i==n?'\n':' ');
            return 1;
        }
        return 0;
    }
    if ( vis[p].count(PII(a[p-1],q)) ) return 0;
    vis[p].insert(PII(a[p-1],q));
    if ( a[p] ) {
        if ( a[p-1]==a[p] ) return go(p+1,q+1);
        else if ( q>=2 ) return go(p+1,1);
    } else {
        if ( q>=2 ) {
            a[p]=a[p-1]+1;
            if ( go(p+1,1) ) return 1;
            a[p]=0;
        }
        if ( q<5 ) {
            a[p]=a[p-1];
            if ( go(p+1,q+1) ) return 1;
            a[p]=0;
        }
    }
    return 0;
}
int main() {
    RI(n);
    REP1(i,1,n) RI(a[i]);
    if ( a[1]>1 ) return puts("-1"),0;
    a[1]=1;
    nxt[n+1]=n+1;
    for ( int i=n; i>=1; i-- )
        if ( a[i] ) nxt[i]=i;
        else nxt[i]=nxt[i+1];
    if ( !go(2,1) ) puts("-1");
    return 0;
}


// TwT514 {{{
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <bitset>
#include <queue>
#include <stack>
#include <functional>
#include <utility>
#define SZ(x) ((int)(x).size())
#define FOR(i,c) for (__typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define REP(i,n) for (int i=0; i<(int)(n); i++)
#define REP1(i,a,b) for (int i=(int)(a); i<=(int)(b); i++)
#define ALL(x) (x).begin(),(x).end()
#define MS0(x,n) memset((x),0,(n)*sizeof(*x))
#define MS1(x,n) memset((x),-1,(n)*sizeof(*x))
#define MP make_pair
#define PB push_back
#define RI(a) scanf("%d",&(a))
#define RII(a,b) scanf("%d%d",&(a),&(b))
#define RIII(a,b,c) scanf("%d%d%d",&(a),&(b),&(c))
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef vector<int> VI;
// }}}

#define N 200010
int n,a[N],nxt[N];
set<PII> vis[N];
bool good( int p, int q ) {
    if ( q>5 ) return 0;
    int np=nxt[p];
    if ( np>n ) return 1;
    if ( a[p-1]>a[np] ) return 0;
    int dv=a[np]-a[p-1];
    int di=np-(p-1)-1;
    if ( di/2 < dv-1 ) return 0;
    if ( di/5 > dv ) return 0;
    return 1;
}
bool go( int p, int q ) {
    if ( !good(p,q) ) return 0;
    if ( p>n ) {
        if ( q>=2 && q<=5 ) {
            printf("%d\n",a[n]);
            REP1(i,1,n) printf("%d%c",a[i],i==n?'\n':' ');
            return 1;
        }
        return 0;
    }
    if ( vis[p].count(PII(a[p-1],q)) ) return 0;
    vis[p].insert(PII(a[p-1],q));
    if ( a[p] ) {
        if ( a[p-1]==a[p] ) return go(p+1,q+1);
        else return go(p+1,1);
    } else {
        if ( q>=2 ) {
            a[p]=a[p-1]+1;
            if ( go(p+1,1) ) return 1;
            a[p]=0;
        }
        if ( q<5 ) {
            a[p]=a[p-1];
            if ( go(p+1,q+1) ) return 1;
            a[p]=0;
        }
    }
    return 0;
}
int main() {
    RI(n);
    REP1(i,1,n) RI(a[i]);
    if ( a[1]>1 ) return puts("-1"),0;
    a[1]=1;
    nxt[n+1]=n+1;
    for ( int i=n; i>=1; i-- )
        if ( a[i] ) nxt[i]=i;
        else nxt[i]=nxt[i+1];
    if ( !go(1,1) ) puts("-1");
    return 0;
}


// TwT514 {{{
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <bitset>
#include <queue>
#include <stack>
#include <functional>
#include <utility>
#define SZ(x) ((int)(x).size())
#define FOR(i,c) for (__typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define REP(i,n) for (int i=0; i<(int)(n); i++)
#define REP1(i,a,b) for (int i=(int)(a); i<=(int)(b); i++)
#define ALL(x) (x).begin(),(x).end()
#define MS0(x,n) memset((x),0,(n)*sizeof(*x))
#define MS1(x,n) memset((x),-1,(n)*sizeof(*x))
#define MP make_pair
#define PB push_back
#define RI(a) scanf("%d",&(a))
#define RII(a,b) scanf("%d%d",&(a),&(b))
#define RIII(a,b,c) scanf("%d%d%d",&(a),&(b),&(c))
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef vector<int> VI;
// }}}

#define N 200010
int n,a[N],nxt[N];
set<PII> vis[N];
bool good( int p, int q ) {
    if ( q>5 ) return 0;
    int np=nxt[p];
    if ( np>n ) return 1;
    if ( a[p-1]>a[np] ) return 0;
    int dv=a[np]-a[p-1];
    int di=np-(p-1)-1;
    if ( di/2 < dv-1 ) return 0;
    if ( di/5 > dv ) return 0;
    return 1;
}
bool go( int p, int q ) {
    if ( !good(p,q) ) return 0;
    if ( p>n ) {
        if ( q>=2 && q<=5 ) {
            printf("%d\n",a[n]);
            REP1(i,1,n) printf("%d%c",a[i],i==n?'\n':' ');
            return 1;
        }
        return 0;
    }
    if ( vis[p].count(PII(a[p],q)) ) return 0;
    vis[p].insert(PII(a[p],q));
    if ( a[p] ) {
        if ( a[p-1]==a[p] ) return go(p+1,q+1);
        else return go(p+1,1);
    } else {
        if ( q>=2 ) {
            a[p]=a[p-1]+1;
            if ( go(p+1,1) ) return 1;
            a[p]=0;
        }
        if ( q<5 ) {
            a[p]=a[p-1];
            if ( go(p+1,q+1) ) return 1;
            a[p]=0;
        }
    }
    return 0;
}
int main() {
    RI(n);
    REP1(i,1,n) RI(a[i]);
    if ( a[1]>1 ) return puts("-1"),0;
    a[1]=1;
    nxt[n+1]=n+1;
    for ( int i=n; i>=1; i-- )
        if ( a[i] ) nxt[i]=i;
        else nxt[i]=nxt[i+1];
    if ( !go(1,1) ) puts("-1");
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstddef>
#include <complex>
#include <ctime>
#include <climits>

#include <algorithm>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <string>
#include <numeric>
#include <functional>
#include <iterator>
#include <typeinfo>
#include <utility>
#include <memory>

#include <cassert>

#if __cplusplus >= 201103L
#include <tuple>
#include <ratio>
#include <array>
#include <forward_list>
#include <unordered_map>
#include <unordered_set>
#endif
using namespace std;

typedef long long int64;
const int inf = 2000000000;
static inline int Rint()
{
	struct X{ int dig[256]; X(){
	for(int i = '0'; i <= '9'; ++i) dig[i] = 1; dig['-'] = 1;
	}};
	static 	X fuck;int s = 1, v = 0, c;
	for (;!fuck.dig[c = getchar()];);
	if (c == '-') s = 0; else if (fuck.dig[c]) v = c ^ 48;
	for (;fuck.dig[c = getchar()]; v = v * 10 + (c ^ 48));
	return s ? v : -v;
}
typedef vector<int> vi;
typedef map<int, int> mii;
typedef set<int> si;

#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
#define sz(x) ((int)(x).size())
#define rep(i, s, e) for (int i = (s); i < (e); ++i)

#if __cplusplus >= 201103L
#define foreach(iter, c) for(auto& iter : c)
#else
#define foreach(itr, c) for(__typeof((c).begin()) itr = (c).begin(); itr != (c).end(); ++itr)
#endif

template<typename T> static inline void cmax(T& a, const T& b){if(b>a)a=b;}
template<typename T> static inline void cmin(T& a, const T& b){if(b<a)a=b;}
#define SL static inline

#define dbg(x) cerr << (#x) << " = " << (x) << endl

const int maxn = 2*100005;

int data[maxn];

int pos[maxn][2];
int check(int n)
{
	memset(pos, -1, sizeof pos);
	for (int i = 1, last = 0; i <= n; ++i)
	if (data[i] != 0)
	{
		if (data[i] < last) return 0;
		last = data[i];
		int l = (data[i] - 1) * 2 + 1;
		int r = data[i] * 5;
		if (i < l || i > r) return 0;
		if (pos[data[i]][0] == -1 || i < pos[data[i]][0])
		pos[data[i]][0] = i;
		if (pos[data[i]][1] == -1 || i > pos[data[i]][1])
		pos[data[i]][1] = i;
	}
	for (int i = 1; i <= n; ++i)
	if (pos[i][0] != -1 && pos[i][1] != -1)
	{
		if (pos[i][1] - pos[i][0] + 1 > 5) return 0;
	}
	return 1;
}

int dp[maxn][5];
int path[maxn][5];
int last_value[maxn];

void do_fill(int* data, int n, int start, int end)
{
	if (n == 0) return;
	for (int i = start, remain = end - start; i <= end; ++i, --remain)
	{
		*data++ = i;
		*data++ = i;
		n -= 2;
		while (n < remain * 2 || n > remain * 5)
		{
			*data++ = i;
			--n;
		}
	}
}
int main()
{
	const int n = Rint();
	for (int i = 1; i <= n; ++i)
	data[i] = Rint();
	if (!check(n))
	{
		puts("-1");
		return 0;
	}

	pos[0][0] = pos[0][1] = 0;
	dp[0][0] = 1;

	int64 last = 0;
	for (int i = 1; i <= n; ++i)
	if (pos[i][0] != -1)
	{
		last_value[i] = last;
		for (int j = pos[i][1];
				j <= n && j <= pos[i][1] + 4 && j - pos[i][0] + 1 <= 5
					; ++j)
		{
			int ok = 1;
			for (int k = j; k >= pos[i][0]; --k)
			if (data[k] != 0 && data[k] != i)
			{
				ok = 0;
				break;
			}
			if (ok == 0) continue;
			int used_length = j - pos[i][0] + 1;
			int at_least = used_length == 1 ? 1 : 0;
			int at_most = 5 - used_length;
			for (int k = 0; k <= 4; ++k)
			if (dp[last][k])
			{
				int numbers = i - 1 - last;
				int places = pos[i][0] - 1 - (pos[last][1] + k);
				int min_places = 2 * numbers + at_least;
				int max_places = 5 * numbers + at_most;
				if (places < min_places || places > max_places) continue;
				dp[i][j-pos[i][1]] = 1;
				path[i][j-pos[i][1]] = k;
				goto the_end;
			}
			the_end:;
		}
		last = i;
	}
	int64 can = -1;
	int off = -1;
	for (int l = 0; l <= 4; ++l)
	if (dp[last][l])
	{
		int av = n - (pos[last][1] + l);
		if (av == 0 || av >= 2)
		{
			int t = last + av / 2;
			if (t > can) can = t, off = l;
		}
	}
	if (can == -1)
	{
		puts("-1");
		return 0;
	}
	printf("%I64d\n", can);
	{
		int av = n - (pos[last][1] + off);
		if (av >= 2)
		{
			int val = last + 1;
			for (int i = pos[last][1] + off + 1; i + 1 <= n; i += 2)
			data[i] = data[i+1] = val++;
			data[n] = data[n-1];
		}
	}
	for (int curr = last; curr != 0;)
	{
		// fill me
		for (int i = pos[curr][1] + off; i >= pos[curr][0]; --i)
		data[i] = curr;

		int next_v = last_value[curr];
		int next_off = path[curr][off];

		int next_pos = next_v + next_off;

		int* u = data + (pos[next_pos][1] + next_off + 1);
		int* v = data + pos[curr][0];
		int start = next_v + 1;
		int end = curr - 1;
		if (pos[curr][1] + off == pos[curr][0])
		{
			*--v = curr;
		}
		int how = end - start + 1;

		while (v - u > how * 5) *--v = curr;
		do_fill(u, v-u, start, end);

		curr = next_v;
		off = next_off;
	}
	for (int i = 1; i <= n; ++i)
	printf("%d ", data[i]);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstddef>
#include <complex>
#include <ctime>
#include <climits>

#include <algorithm>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <string>
#include <numeric>
#include <functional>
#include <iterator>
#include <typeinfo>
#include <utility>
#include <memory>

#include <cassert>

#if __cplusplus >= 201103L
#include <tuple>
#include <ratio>
#include <array>
#include <forward_list>
#include <unordered_map>
#include <unordered_set>
#endif
using namespace std;

typedef long long int64;
const int inf = 2000000000;
static inline int Rint()
{
	struct X{ int dig[256]; X(){
	for(int i = '0'; i <= '9'; ++i) dig[i] = 1; dig['-'] = 1;
	}};
	static 	X fuck;int s = 1, v = 0, c;
	for (;!fuck.dig[c = getchar()];);
	if (c == '-') s = 0; else if (fuck.dig[c]) v = c ^ 48;
	for (;fuck.dig[c = getchar()]; v = v * 10 + (c ^ 48));
	return s ? v : -v;
}
typedef vector<int> vi;
typedef map<int, int> mii;
typedef set<int> si;

#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
#define sz(x) ((int)(x).size())
#define rep(i, s, e) for (int i = (s); i < (e); ++i)

#if __cplusplus >= 201103L
#define foreach(iter, c) for(auto& iter : c)
#else
#define foreach(itr, c) for(__typeof((c).begin()) itr = (c).begin(); itr != (c).end(); ++itr)
#endif

template<typename T> static inline void cmax(T& a, const T& b){if(b>a)a=b;}
template<typename T> static inline void cmin(T& a, const T& b){if(b<a)a=b;}
#define SL static inline

#define dbg(x) cerr << (#x) << " = " << (x) << endl

const int maxn = 2*100005;

int data[maxn];

int pos[maxn][2];
int check(int n)
{
	memset(pos, -1, sizeof pos);
	for (int i = 1, last = 0; i <= n; ++i)
	if (data[i] != 0)
	{
		if (data[i] < last) return 0;
		last = data[i];
		int l = (data[i] - 1) * 2 + 1;
		int r = data[i] * 5;
		if (i < l || i > r) return 0;
		if (pos[data[i]][0] == -1 || i < pos[data[i]][0])
		pos[data[i]][0] = i;
		if (pos[data[i]][1] == -1 || i > pos[data[i]][1])
		pos[data[i]][1] = i;
	}
	for (int i = 1; i <= n; ++i)
	if (pos[i][0] != -1 && pos[i][1] != -1)
	{
		if (pos[i][1] - pos[i][0] + 1 > 5) return 0;
	}
	return 1;
}

vi dp[maxn][6];
vector<int64> path[maxn][6];

void do_fill(int* data, int n, int start, int end)
{
	if (n == 0) return;
	//cerr << n << " " << start << " " << end << endl;
	for (int i = start, remain = end - start; i <= end; ++i, --remain)
	{
		*data++ = i;
		*data++ = i;
		n -= 2;
		while (n < remain * 2 || n > remain * 5)
		{
			*data++ = i;
			--n;
		}
	}
}
int main()
{
	const int n = Rint();
	for (int i = 1; i <= n; ++i)
	data[i] = Rint();
	if (!check(n))
	{
		puts("-1");
		return 0;
	}
	dp[0][2].pb(0);
	path[0][2].pb(-1);
	int64 last = 0;
	for (int i = 1; i <= n; ++i)
	if (pos[i][0] != -1)
	{
		for (int l = 2; l <= 5; ++l)
		for (int j = pos[i][1]; j <= n && j - l + 1 <= pos[i][0]; ++j)
		{
			int ok = 1;
			for (int k = j; k >= j - l + 1; --k)
			if (data[k] != 0 && data[k] != i)
			{
				ok = 0;
				break;
			}
			if (ok == 0) continue;
			for (int ll = 2; ll <= 5; ++ll)
			{
				vector<int>& vec = dp[last][ll];
				const int size = sz(vec);
				for (int id = 0; id < size; ++id)
				{
					const int64 it = vec[id];
					if (j - l + 1 > it)
					{
						int place = j - l + 1 - it - 1;
						int numbers = i - last - 1;
						int min = 2 * numbers;
						int max = 5 * numbers;
						if (place >= min && place <= max)
						{
							dp[i][l].pb(j);
							path[i][l].pb(last*1048576+id*8+ll);
							goto the_end;
						}
					}
				}
			}
			the_end:;
		}
		last = i;
	}
	int64 can = -1;
	int pos = -1;
	int length = -1;
	int id = -1;
	for (int l = 2; l <= 5; ++l)
	if (dp[last][l].size())
	{
		vector<int>& vec = dp[last][l];
		const int size = sz(vec);
		for (int i = 0; i < size; ++i)
		{
			int it = vec[i];
			if (it <= n)
			{
				int av = n - it;
				if (av == 0 || av >= 2)
				{
					int t = av / 2 + last;
					if (t > can) can = t, pos = it, length = l, id = i;
				}
			}
		}
	}
	if (can == -1)
	{
		puts("-1");
		return 0;
	}
	printf("%I64d\n", can);
	{
		int av = n - pos;
		if (av >= 2)
		{
			int val = last + 1;
			for (int i = pos + 1; i + 1 <= n; i += 2)
			data[i] = data[i+1] = val++;
			data[n] = data[n-1];
		}
	}
	for (int curr = last; curr != 0;)
	{
		// fill me
		for (int p = pos, i = 0; i < length; ++i, --p)
		data[p] = curr;

		int64 flag = path[curr][length][id];

		int next_v = flag >> 20;
		int next_l = flag & 7;
		int next_id = (flag & 1048575) >> 3;
		int next_pos = dp[next_v][next_l][next_id];

		int place = pos - length + 1 - next_pos - 1;
		int start = next_v + 1;
		int end = curr - 1;
		//cerr << curr << " " << pos << " " << length << " " << next_pos << endl;
		do_fill(data+next_pos+1, place, start, end);

		curr = next_v;
		pos = next_pos;
		length = next_l;
		id = next_id;
	}
	for (int i = 1; i <= n; ++i)
	printf("%d ", data[i]);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstddef>
#include <complex>
#include <ctime>
#include <climits>

#include <algorithm>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <string>
#include <numeric>
#include <functional>
#include <iterator>
#include <typeinfo>
#include <utility>
#include <memory>

#include <cassert>

#if __cplusplus >= 201103L
#include <tuple>
#include <ratio>
#include <array>
#include <forward_list>
#include <unordered_map>
#include <unordered_set>
#endif
using namespace std;

typedef long long int64;
const int inf = 2000000000;
static inline int Rint()
{
	struct X{ int dig[256]; X(){
	for(int i = '0'; i <= '9'; ++i) dig[i] = 1; dig['-'] = 1;
	}};
	static 	X fuck;int s = 1, v = 0, c;
	for (;!fuck.dig[c = getchar()];);
	if (c == '-') s = 0; else if (fuck.dig[c]) v = c ^ 48;
	for (;fuck.dig[c = getchar()]; v = v * 10 + (c ^ 48));
	return s ? v : -v;
}
typedef vector<int> vi;
typedef map<int, int> mii;
typedef set<int> si;

#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
#define sz(x) ((int)(x).size())
#define rep(i, s, e) for (int i = (s); i < (e); ++i)

#if __cplusplus >= 201103L
#define foreach(iter, c) for(auto& iter : c)
#else
#define foreach(itr, c) for(__typeof((c).begin()) itr = (c).begin(); itr != (c).end(); ++itr)
#endif

template<typename T> static inline void cmax(T& a, const T& b){if(b>a)a=b;}
template<typename T> static inline void cmin(T& a, const T& b){if(b<a)a=b;}
#define SL static inline

#define dbg(x) cerr << (#x) << " = " << (x) << endl

const int maxn = 2*100005;

int data[maxn];

int pos[maxn][2];
int check(int n)
{
	memset(pos, -1, sizeof pos);
	for (int i = 1, last = 0; i <= n; ++i)
	if (data[i] != 0)
	{
		if (data[i] < last) return 0;
		last = data[i];
		int l = (data[i] - 1) * 2 + 1;
		int r = data[i] * 5;
		if (i < l || i > r) return 0;
		if (pos[data[i]][0] == -1 || i < pos[data[i]][0])
		pos[data[i]][0] = i;
		if (pos[data[i]][1] == -1 || i > pos[data[i]][1])
		pos[data[i]][1] = i;
	}
	for (int i = 1; i <= n; ++i)
	if (pos[i][0] != -1 && pos[i][1] != -1)
	{
		if (pos[i][1] - pos[i][0] + 1 > 5) return 0;
	}
	return 1;
}

int dp[maxn][5];
int path[maxn][5];
int last_value[maxn];

void do_fill(int* data, int n, int start, int end)
{
	if (n == 0) return;
	for (int i = start, remain = end - start; i <= end; ++i, --remain)
	{
		*data++ = i;
		*data++ = i;
		n -= 2;
		while (n < remain * 2 || n > remain * 5)
		{
			*data++ = i;
			--n;
		}
	}
}
int main()
{
	const int n = Rint();
	for (int i = 1; i <= n; ++i)
	data[i] = Rint();
	if (!check(n))
	{
		puts("-1");
		return 0;
	}

	pos[0][0] = pos[0][1] = 0;
	dp[0][0] = 1;

	int64 last = 0;
	for (int i = 1; i <= n; ++i)
	if (pos[i][0] != -1)
	{
		last_value[i] = last;
		for (int j = pos[i][1];
				j <= n && j <= pos[i][1] + 4 && j - pos[i][0] + 1 <= 5
					; ++j)
		{
			int ok = 1;
			for (int k = j; k >= pos[i][0]; --k)
			if (data[k] != 0 && data[k] != i)
			{
				ok = 0;
				break;
			}
			if (ok == 0) continue;
			int used_length = j - pos[i][0] + 1;
			int at_least = used_length == 1 ? 1 : 0;
			int at_most = 5 - used_length;
			for (int k = 0; k <= 4; ++k)
			if (dp[last][k])
			{
				int numbers = i - 1 - last;
				int places = pos[i][0] - 1 - (pos[last][1] + k);
				int min_places = 2 * numbers + at_least;
				int max_places = 5 * numbers + at_most;
				if (places < min_places || places > max_places) continue;
				dp[i][j-pos[i][1]] = 1;
				path[i][j-pos[i][1]] = k;
				goto the_end;
			}
			the_end:;
		}
		last = i;
	}
	int64 can = -1;
	int off = -1;
	for (int l = 0; l <= 4; ++l)
	if (dp[last][l])
	{
		int av = n - (pos[last][1] + l);
		if (av == 0 || av >= 2)
		{
			int t = last + av / 2;
			if (t > can) can = t, off = l;
		}
	}
	if (can == -1)
	{
		puts("-1");
		return 0;
	}
	printf("%I64d\n", can);
	{
		int av = n - (pos[last][1] + off);
		if (av >= 2)
		{
			int val = last + 1;
			for (int i = pos[last][1] + off + 1; i + 1 <= n; i += 2)
			data[i] = data[i+1] = val++;
			data[n] = data[n-1];
		}
	}
	for (int curr = last; curr != 0;)
	{
		// fill me
		for (int i = pos[curr][1] + off; i >= pos[curr][0]; --i)
		data[i] = curr;

		int next_v = last_value[curr];
		int next_off = path[curr][off];

		int next_pos = next_v + next_off;

		int* u = data + (pos[next_v][1] + next_off + 1);
		int* v = data + pos[curr][0];
		int start = next_v + 1;
		int end = curr - 1;
		if (pos[curr][1] + off == pos[curr][0])
		{
			*--v = curr;
		}
		int how = end - start + 1;
		//cerr << curr << " " << how << " " << v - u << endl;
		while (v - u > how * 5) *--v = curr;
		do_fill(u, v-u, start, end);

		curr = next_v;
		off = next_off;
	}
	for (int i = 1; i <= n; ++i)
	printf("%d ", data[i]);
	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <sstream>

using namespace std;

#define mpr make_pair
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const double eps = 1e-12;
const int step[8][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b, T c = -1234567, T d = -1234567) {
	T ans =  a > b ? a : b;
	if(c != -1234567) ans = max1(ans, c);
	if(d != -1234567) ans = max1(ans, d);
	return ans;
}
template <class T> inline T min1(T a, T b, T c = -1234567, T d = -1234567) {
	T ans = a < b ? a : b;
	if(c != -1234567) ans = min(ans, c);
	if(d != -1234567) ans = min(ans, d);
	return ans;
}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lowb(T num) {return num & (-num); }
inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / abs1(a) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t>
inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}
inline int bitnum(ull nValue){
    nValue = ((0xaaaaaaaaaaaaaaaaull & nValue)>>1) + (0x5555555555555555ull & nValue);
    nValue = ((0xccccccccccccccccull & nValue)>>2) + (0x3333333333333333ull & nValue);
    nValue = ((0xf0f0f0f0f0f0f0f0ull & nValue)>>4) + (0x0f0f0f0f0f0f0f0full & nValue);
    nValue = ((0xff00ff00ff00ff00ull & nValue)>>8) + (0x00ff00ff00ff00ffull & nValue);
    nValue = ((0xffff0000ffff0000ull & nValue)>>16) + (0x0000ffff0000ffffull & nValue);
    nValue = ((0xffffffff00000000ull & nValue)>>32) + (0x00000000ffffffffull & nValue);
	return nValue;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

//.........................mi.......feng.......xian.......wai.......jin.......zhi.......challenge...............................................

const int maxn = 200010;
int dp[maxn][7];
int orig[maxn], arr[maxn][2], larr;
int stat[maxn];
int n;

inline pii adv(pii now, int add, int base = 5) {
	pii ans = now;
	if(ans.second >= base) {
		ans.first++;
		ans.second = 0;
		add--;
	}
	ans.second += add;
	ans.first += ans.second / base;
	ans.second %= base;
	return ans;
}

int main() {
	ios_base::sync_with_stdio(0);
//	freopen("input.txt", "r", stdin);
	scanf("%d", &n);
	if(n == 1) {
		printf("-1\n");
		return 0;
	}
	bool fla = 1;
	for(int i = 0; i < n; i++) {
		scanf("%d", orig + i);
		stat[orig[i]]++;
		if(orig[i] != 0 && stat[orig[i]] > 5) fla = 0;
	}
	if(!fla) {
		printf("-1\n");
		return 0;
	}
	if(n > 100) {
		for(int i = 0; i < n; i++) if(orig[i] == 0) {
			printf("%d\n", i - 1);
			printf("%d ", orig[i - 1]);
			int j = i;
			for(; orig[j] == 0 && j != n; j++) printf("%d ", orig[j]);
			printf("%d\n", orig[j]);
			i = j;
		}
	}

	arr[larr][0] = 0;
	arr[larr][1] = 0;
	larr++;
	for(int i = 0; i < n; i++) if(orig[i] != 0) {
		arr[larr][0] = orig[i];
		arr[larr++][1] = i + 1;
	}
	memset(dp, -1, sizeof(dp));
	dp[0][4] = 0;
	for(int i = 0; i < larr - 1; i++) {
		for(int j = 0; j < 5; j++) if(dp[arr[i][1]][j] != -1) {
//			cerr << 1 << endl;
			int l = arr[i + 1][1] - arr[i][1];
			pii big = adv(mpr(arr[i][0], j), l, 2);
//			cerr << "big: " << big.first << ' ' << big.second << endl;
			pii small = adv(mpr(arr[i][0], j), l, 5);
//			cerr << "small: " << small.first << ' ' << small.second <</ endl;
			for(int k = 0; k < 5; k++)
				if(mpr(arr[i + 1][0] + k / 2, k % 2) >= small && mpr(arr[i + 1][0] + k / 2, k % 2) <= big)
					dp[arr[i + 1][1]][k] = j;
		}
	}
//	for(int i = 0; i < larr; i++) {
//		cerr << arr[i][0] << ' ' << arr[i][1] << endl;
//		for(int j = 0; j < 5; j++) {
//			cerr << dp[arr[i][1]][j] << ' ';
//		}
//		cerr << endl;
//	}

	int f = -1;
	for(int j = 4; j >= 0; j--) if(dp[arr[larr - 1][1]][j] != -1) {
		if(j == 0 && arr[larr - 1][1] == n)
			break;
		f = j;
		break;
	}
	if(f == -1) {
		printf("-1\n");
		return 0;
	}
	int be = arr[larr - 1][1];
	if(f == 0) {
		orig[be] = arr[larr - 1][0];
		be++;
	}
//	cerr << f << endl;
	int flag = 0;
	for(int i = be, add = arr[larr - 1][0] + 1; i < n; i++, flag ^= 1) {
		orig[i] = add;
		if(flag) add++;
	}
	if(flag)
		orig[n - 1] = orig[n - 2];
//	for(int i = 0; i < n; i++)
//		cerr << orig[i] << ' ';
//	cerr << endl;
	for(int i = larr - 1; i; i--) {
//		cerr << "f: " << f << endl;
		int nxt = dp[arr[i][1]][f];
		pii be = mpr(arr[i - 1][0], nxt);
		for(int j = arr[i - 1][1]; j < arr[i][1] - 1; j++) {
			be.second++;
//			pii nxt = adv(be, arr[i ][1] - 1 - j, 2);
//			cerr << arr[i][1] - 1 - j << endl;
//			cerr << "be: " << be.first << ' ' << be.second << endl;
//			cerr << "nxt: " << nxt.first << ' ' << nxt.second << endl;
//			cerr << f + max(2 * (arr[i][0] - be.first - 1), 0) << endl;
			if(be.first != arr[i][0] && (be.second == 5 || adv(be, arr[i][1] - 1 - j, 2) < mpr(arr[i][0], f) ||
			arr[i][1] - 1 - j <= f + 2 * (arr[i][0] - be.first - 1)))
				be.first++, be.second = 0;
			orig[j] = be.first;
		}
		f = nxt;
//		cerr << endl;
	}
//	for(int i = 0; i < n; i++)
//		cerr << orig[i] << ' ';
//	cerr << endl;
	printf("%d\n", orig[n - 1]);
	for(int i = 0; i < n; i++) printf("%d ", orig[i]);
	printf("\n");

	return 0;
}


/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <sstream>

using namespace std;

#define mpr make_pair
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const double eps = 1e-12;
const int step[8][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}
template <class T> inline T max1(T a, T b, T c = -1234567, T d = -1234567) {
	T ans =  a > b ? a : b;
	if(c != -1234567) ans = max1(ans, c);
	if(d != -1234567) ans = max1(ans, d);
	return ans;
}
template <class T> inline T min1(T a, T b, T c = -1234567, T d = -1234567) {
	T ans = a < b ? a : b;
	if(c != -1234567) ans = min(ans, c);
	if(d != -1234567) ans = min(ans, d);
	return ans;
}
template <class T> inline T gcd1(T a, T b) {
	if(a < b) swap(a, b);
	if(a % b == 0) return b;
	return gcd1(b, a % b);
}
template <class T> inline T lowb(T num) {return num & (-num); }
inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / abs1(a) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t>
inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}
inline int bitnum(ull nValue){
    nValue = ((0xaaaaaaaaaaaaaaaaull & nValue)>>1) + (0x5555555555555555ull & nValue);
    nValue = ((0xccccccccccccccccull & nValue)>>2) + (0x3333333333333333ull & nValue);
    nValue = ((0xf0f0f0f0f0f0f0f0ull & nValue)>>4) + (0x0f0f0f0f0f0f0f0full & nValue);
    nValue = ((0xff00ff00ff00ff00ull & nValue)>>8) + (0x00ff00ff00ff00ffull & nValue);
    nValue = ((0xffff0000ffff0000ull & nValue)>>16) + (0x0000ffff0000ffffull & nValue);
    nValue = ((0xffffffff00000000ull & nValue)>>32) + (0x00000000ffffffffull & nValue);
	return nValue;
}
long long pow(long long n, long long m, long long mod = 0){
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

//.........................mi.......feng.......xian.......wai.......jin.......zhi.......challenge...............................................

const int maxn = 200010;
int dp[maxn][7];
int orig[maxn], arr[maxn][2], larr;
int stat[maxn];
int n;

inline pii adv(pii now, int add, int base = 5) {
	pii ans = now;
	if(ans.second >= base) {
		ans.first++;
		ans.second = 0;
		add--;
	}
	ans.second += add;
	ans.first += ans.second / base;
	ans.second %= base;
	return ans;
}
inline bool judge(pii a, pii b, int l) {
	int small = (b.first - a.first - 1) * 2 + b.second + 1 + int(a.second == 0);
	int big = (b.first - a.first - 1) * 5 + b.second + 5 - a.second;
	return l >= small && l <= big;
}

int main() {
	ios_base::sync_with_stdio(0);
//	freopen("input.txt", "r", stdin);
	scanf("%d", &n);
	if(n == 1) {
		printf("-1\n");
		return 0;
	}
	bool fla = 1;
	for(int i = 0; i < n; i++) {
		scanf("%d", orig + i);
		stat[orig[i]]++;
		if(orig[i] != 0 && stat[orig[i]] > 5) fla = 0;
	}
	if(!fla) {
		printf("-1\n");
		return 0;
	}
//	if(n > 100) {
//		for(int i = 0; i < n; i++) if(orig[i] == 0) {
//			printf("%d\n", i - 1);
//			printf("%d ", orig[i - 1]);
//			int j = i;
//			for(; orig[j] == 0 && j != n; j++);
//			printf("%d %d\n", j, orig[j]);
//			i = j;
//		}
//	}

	arr[larr][0] = 0;
	arr[larr][1] = 0;
	larr++;
	for(int i = 0; i < n; i++) if(orig[i] != 0) {
		arr[larr][0] = orig[i];
		arr[larr++][1] = i + 1;
	}
	memset(dp, -1, sizeof(dp));
	dp[0][4] = 0;
	for(int i = 0; i < larr - 1; i++) {
//		if(arr[i][0] == 701)
//			cout << i << endl;
		for(int j = 0; j < 5; j++) if(dp[arr[i][1]][j] != -1) {
//			cerr << 1 << endl;
			int l = arr[i + 1][1] - arr[i][1];
//			pii big = adv(mpr(arr[i][0], j), l, 2);
//			pii small = adv(mpr(arr[i][0], j), l, 5);
//			if(arr[i][0] == 701) {
//				cout << "big: " << big.first << ' ' << big.second << endl;
//				cout << "small: " << small.first << ' ' << small.second << endl;
//			}
			if(arr[i + 1][0] == arr[i][0]) {
				if(j + arr[i + 1][1] - arr[i][1] < 5)
					dp[arr[i + 1][1]][j + arr[i + 1][1] - arr[i][1]] = j;
			} else for(int k = 0; k < 5; k++) {
				if(judge(mpr(arr[i][0], j), mpr(arr[i + 1][0], k), l))
					dp[arr[i + 1][1]][k] = j;
			}
		}
	}
//	for(int i = 0; i < larr; i++) if(arr[i][0] == 701){
//		cout << arr[i][0] << ' ' << arr[i][1] << endl;
//		for(int j = 0; j < 5; j++) {
//			cout << dp[arr[i][1]][j] << ' ';
//		}
//		cout << endl;
//	}

	int f = -1;
	if(arr[larr - 1][1] != n) {
		for(int j = 3; j >= 0; j--) if(dp[arr[larr - 1][1]][j] != -1) {
			if(j == 0 && arr[larr - 1][1] == n)
				break;
			f = j;
			break;
		}
		if(f == -1 && dp[arr[larr - 1][1]][4])
			f = 4;
	} else {
		for(int j = 1; j <= 4; j++) if(dp[arr[larr - 1][1]][j] != -1) {
			if(j == 0 && arr[larr - 1][1] == n)
				break;
			f = j;
			break;
		}
	}
	if(f == -1 || (f == 4 && arr[larr - 1][1] == n - 1)) {
		printf("-1\n");
		return 0;
	}
	int be = arr[larr - 1][1];
	if(f == 0) {
		orig[be] = arr[larr - 1][0];
		be++;
	}
//	cerr << f << endl;
	int flag = 0;
	for(int i = be, add = arr[larr - 1][0] + 1; i < n; i++, flag ^= 1) {
		orig[i] = add;
		if(flag) add++;
	}
	if(flag)
		orig[n - 1] = orig[n - 2];
//	for(int i = 0; i < n; i++)
//		cerr << orig[i] << ' ';
//	cerr << endl;
	for(int i = larr - 1; i; i--) {
//		cerr << "f: " << f << endl;
//		if(arr[i][0] == 1925) cout << f << ' ' << i << endl;
		int nxt = dp[arr[i][1]][f];
		pii be = mpr(arr[i - 1][0], nxt);
		for(int j = arr[i - 1][1]; j < arr[i][1] - 1; j++) {
			be.second++;
//			pii nxt = adv(be, arr[i ][1] - 1 - j, 2);
//			cerr << arr[i][1] - 1 - j << endl;
//			cerr << "be: " << be.first << ' ' << be.second << endl;
//			cerr << "nxt: " << nxt.first << ' ' << nxt.second << endl;
//			cerr << f + max(2 * (arr[i][0] - be.first - 1), 0) << endl;
			if(be.first != arr[i][0] && (be.second == 5 || adv(be, arr[i][1] - 1 - j, 2) < mpr(arr[i][0], f) ||
			arr[i][1] - 1 - j <= f + 2 * (arr[i][0] - be.first - 1)))
				be.first++, be.second = 0;
			orig[j] = be.first;
		}
		f = nxt;
//		cerr << endl;
	}
//	for(int i = 0; i < n; i++)
//		cerr << orig[i] << ' ';
//	cerr << endl;
	printf("%d\n", orig[n - 1]);
	for(int i = 0; i < n; i++) printf("%d ", orig[i]);
	printf("\n");

	return 0;
}