#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>

using namespace std;

class p {
public:
	int l, r, c;
	p(int l, int r, int c)
		:l(l), r(r), c(c)
	{}
};

bool cmp(const p &i, const p &j) {
	return i.l < j.l;
}

int a[200002], n;
vector<p> v;
int l[100001], r[100001];
int d[6][100001];

int f(int h, int k) {
	if (k < 0) return 1;
	if (d[h][k] >= 0) return d[h][k];
	if (v[k + 1].l - h <= v[k].r) return d[h][k] = 0;
	for (int i = v[k].l - 4; i <= v[k].l; i++) {
		for (int j = v[k].r; j <= v[k].r + 4; j++) {
			int cl = i, cr = j, nl = v[k + 1].l - h;
			if (cl<1 || cr>n || cr >= nl) continue;
			if (cr - cl + 1 > 5 || cr - cl + 1 < 2) continue;
			int c1 = (nl - cr + 3) / 5, c2 = (nl - cr - 1) / 2;
			if (v[k].c + c1 + 1 > v[k + 1].c || v[k].c + c2 + 1 < v[k + 1].c) continue;
			if (f(v[k].l - i, k - 1)) return d[h][k] = 1;
		}
	}
	return d[h][k] = 0;
}

void trace(int h, int k) {
	if (k < 0) return;
	for (int i = v[k].l - 4; i <= v[k].l; i++) {
		for (int j = v[k].r; j <= v[k].r + 4; j++) {
			int cl = i, cr = j, nl = v[k + 1].l - h;
			if (cl<1 || cr>n || cr >= nl) continue;
			if (cr - cl + 1 > 5 || cr - cl + 1 < 2) continue;
			int c1 = (nl - cr + 3) / 5, c2 = (nl - cr - 1) / 2;
			if (v[k].c + c1 + 1 > v[k + 1].c || v[k].c + c2 + 1 < v[k + 1].c) continue;
			if (f(v[k].l - i, k - 1)) {
				for (int p = i; p <= j; p++)
					a[p] = v[k].c;
				int need = (v[k + 1].c - v[k].c - 1), len = nl - cr - 1;
				if (need) {
					int p = len / need, q = len%need, sum = 0;
					int cur = v[k].c + 1;
					for (int i = cr + 1; i < nl; i++) {
						a[i] = cur;
						sum++;
						if (sum == p) {
							if (q) q--;
							else {
								sum = 0; cur++;
							}
						}
						else if (sum > p) {
							sum = 0;
							cur++;
						}
					}
				}
				trace(v[k].l - i, k - 1);
				return;
			}
		}
	}
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		if (i == 1) {
			if (a[i] > 1) {
				puts("-1");
				return 0;
			}
			a[i] = 1;
		}
		if (a[i]) {
			if (!l[a[i]]) l[a[i]] = i;
			r[a[i]] = i;
		}
	}
	for (int i = 1; i <= 100000; i++) if (l[i]) {
		v.push_back(p(l[i], r[i], i));
	}
	if (v.size() == 1) {
		if (v[0].r - v[0].l + 1 > 5) {
			puts("-1");
			return 0;
		}
		if (v[0].r == 1) {
			a[2] = 1;
			v[0].r++;
		}
		for (int i = v[0].l; i <= v[0].r; i++)
			a[i] = 1;
		int rem = (n - v[0].r) / 2;
		int cur = 2;
		for (int i = v[0].r + 1; i < n; i += 2) {
			a[i] = a[i + 1] = cur;
			cur++;
		}
		if (a[n] == 0) a[n] = a[n - 1];
		printf("%d\n", a[n]);
		for (int i = 1; i <= n; i++)
			printf("%d ", a[i]);
		puts("");
		return 0;
	}
	sort(v.begin(), v.end(), cmp);
	for (int i = 0; i < v.size(); i++) {
		if (v[i].r - v[i].l + 1 > 5) {
			puts("-1");
			return 0;
		}
		if (i && v[i].l <= v[i - 1].r) {
			puts("-1");
			return 0;
		}
		if (i && v[i].c < v[i - 1].c) {
			puts("-1");
			return 0;
		}
		if (i > 0 && i < v.size() - 1 && v[i].l == v[i].r && v[i - 1].r == v[i].l - 1 && v[i + 1].l == v[i].r + 1) {
			puts("-1");
			return 0;
		}
	}
	for (int i = 0; i < v.size(); i++) {
		for (int j = v[i].l; j <= v[i].r; j++)
			a[j] = v[i].c;
	}
	memset(d, -1, sizeof(d));
	for (int l = v.back().l - 4; l <= v.back().l; l++) {
		for (int r = v.back().r; r <= v.back().r + 4; r++) {
			if (r - l + 1 > 5 || r - l + 1 < 2) continue;
			if (f(v.back().l - l, v.size() - 2)) {
				trace(v.back().l - l, v.size() - 2);
				for (int j = l; j <= r; j++)
					a[j] = v.back().c;
				int cur = v.back().c + 1;
				for (int j = r + 1; j < n; j += 2) {
					a[j] = a[j + 1] = cur;
					cur++;
				}
				if (a[n] == 0) a[n] = a[n - 1];
				printf("%d\n", a[n]);
				for (int j = 1; j <= n; j++)
					printf("%d ", a[j]);
				puts("");
				return 0;
			}
		}
	}
	puts("-1");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost {ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); }
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long int ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PLL, PLL > PP;
typedef pair <PII, int> PPI;
typedef pair <int, PII> PIP;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const int mod = 998244353;
const int inf = 1e9+9;
const ll MOD = 1e9+696969;
const long long INF = 4LL * 1000000LL * 1000000LL * 1000000LL;

template<class T> int size(T &&x) {
	return int(x.size());
}
template<class A, class B> ostream& operator<<(ostream &out, const pair<A, B> &p) {
	return out << '(' << p.first << ", " << p.second << ')';
}
template<class T> auto operator<<(ostream &out, T &&x) -> decltype(x.begin(), out) {
	out << '{';
	for(auto it = x.begin(); it != x.end(); ++it)
		out << *it << (it == prev(x.end()) ? "" : ", ");
	return out << '}';
}
void dump() {}
template<class T, class... Args> void dump(T &&x, Args... args) {
	cerr << x << ";  ";
	dump(args...);
}
#ifdef DEBUG
  struct Nl{~Nl(){cerr << '\n';}};
# define debug(x...) cerr << (strcmp(#x, "") ? #x ":  " : ""), dump(x), Nl(), cerr << ""
#else
# define debug(...) 0 && cerr
#endif
mt19937_64 rng(0);
int random(int l, int r) {
	return uniform_int_distribution<int>(l, r)(rng);
}

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
inline void addmod(int &x, int val) {
	x += val;
	while (x >= mod) x -= mod;
}
const int maxn = 200100;

bool poss(int i, PII stan1, int j, PII stan2) {
	assert(i <= j);
	if (i == j) {
		return stan1 == stan2;
	}

	int dst = j - i - 1; //liczb pomiedzy
	if (stan1.e1 == stan2.e1) {
		return (stan1.e2 + dst + 1 == stan2.e2);
	}
	else {
		int must_be = (stan1.e2 == 1 ? 1 : 0);
		int more_copies = 5 - must_be;
		must_be += stan2.e2 - 1;
		int MIN = must_be + (stan2.e1 - stan1.e1 - 1) * 2;
		int MAX = more_copies + must_be + (stan2.e1 - stan1.e1 - 1) * 5;
		//for init number
		return (MIN <= dst && dst <= MAX);
	}
}

int nast(int i, PII stan1, int j, PII stan2) {
	assert(i <= j);
	if (i == j) return stan1.e1;

	if (stan1.e1 == stan2.e1) return stan1.e1;

	int value = stan1.e1;
	if (stan1.e2 != 5) {
		if (poss(i + 1, make_pair(value, stan1.e2 + 1), j, stan2)) return value;
	}

	return value + 1;
}

int n;
vector <int> pos;
bool dp[maxn][6];
int tab[maxn];

int main() {
	//cout << nast(1, {1, 1}, 5, {}) << endl;
	ios_base::sync_with_stdio(false);
	cin >> n;
	//init
	pos.push_back(0);
	dp[0][5] = 1;

	int lt = 0;
	for (int i=1; i<=n; ++i) {
		cin >> tab[i];
		if (tab[i] > 0) {
			pos.push_back(i);
			lt = i;
		}
	}

	int sz = pos.size();
	for (int i = 0; i + 1 < sz; ++i) {
		int lewe = pos[i], prawe = pos[i + 1];
		for (int a = 1; a <= 5; ++a) {
			if (dp[lewe][a]) {
				for (int b = 1; b <= 5; ++b) {
					if (poss(lewe, {tab[lewe], a}, prawe, {tab[prawe], b})) {
						dp[prawe][b] = 1;
					}
				}
			}
		}
	}

	bool odp = false, ans = false;
	int ka = 0;
	if (tab[n] == 0) {
		for (int value = n; value > 0; --value) {
			for (int a=1; a<=5; ++a) {
				for (int b=2; b<=5; ++b) {
					if (!ans && dp[lt][a] && poss(lt, {tab[lt], a}, n, {value, b})) {
						tab[n] = value;
						dp[n][b] = true;
						ka = b;
						pos.push_back(n);
						ans = true;
					}
				}
			}
		}
	}

	for (int a=2; a<=5; ++a)
		if (dp[n][a]) odp = true;

	if (!odp) OUT("-1");
	sz = pos.size();
	for (int i = sz - 2; i >= 0; --i) {
		int lewe = pos[i], prawe = pos[i + 1];
		for (int a = 1; a <= 5; ++a) {
			if (dp[lewe][a] && poss(lewe, {tab[lewe], a}, prawe, {tab[prawe], ka})) {
				//debug(lewe, a, prawe, ka);
				int kal = a;
				for (int ruch = lewe; ruch + 1 < prawe; ++ruch) {

					int wstawie = nast(ruch, {tab[ruch], kal}, prawe, {tab[prawe], ka});
					if (wstawie == tab[ruch]) ++kal;
					else kal = 1;
					tab[ruch + 1] = wstawie;
				}

				ka = a;
				break;
			}
		}
	}

	cout << tab[n] << "\n";
	for (int i=1; i<=n; ++i) cout << tab[i] << ' ';
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost {ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); }
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long int ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PLL, PLL > PP;
typedef pair <PII, int> PPI;
typedef pair <int, PII> PIP;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const int mod = 998244353;
const int inf = 1e9+9;
const ll MOD = 1e9+696969;
const long long INF = 4LL * 1000000LL * 1000000LL * 1000000LL;

template<class T> int size(T &&x) {
	return int(x.size());
}
template<class A, class B> ostream& operator<<(ostream &out, const pair<A, B> &p) {
	return out << '(' << p.first << ", " << p.second << ')';
}
template<class T> auto operator<<(ostream &out, T &&x) -> decltype(x.begin(), out) {
	out << '{';
	for(auto it = x.begin(); it != x.end(); ++it)
		out << *it << (it == prev(x.end()) ? "" : ", ");
	return out << '}';
}
void dump() {}
template<class T, class... Args> void dump(T &&x, Args... args) {
	cerr << x << ";  ";
	dump(args...);
}
#ifdef DEBUG
  struct Nl{~Nl(){cerr << '\n';}};
# define debug(x...) cerr << (strcmp(#x, "") ? #x ":  " : ""), dump(x), Nl(), cerr << ""
#else
# define debug(...) 0 && cerr
#endif
mt19937_64 rng(0);
int random(int l, int r) {
	return uniform_int_distribution<int>(l, r)(rng);
}

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
inline void addmod(int &x, int val) {
	x += val;
	while (x >= mod) x -= mod;
}
const int maxn = 200100;

bool poss(int i, PII stan1, int j, PII stan2) {
	assert(i <= j);
	if (i == j) {
		return stan1 == stan2;
	}

	int dst = j - i - 1; //liczb pomiedzy
	if (stan1.e1 == stan2.e1) {
		return (stan1.e2 + dst + 1 == stan2.e2);
	}
	else {
		int must_be = (stan1.e2 == 1 ? 1 : 0);
		int more_copies = 5 - stan1.e2 - must_be; //ile jeszcze mozna wcisnac tego elementu
		must_be += stan2.e2 - 1;
		int MIN = must_be + (stan2.e1 - stan1.e1 - 1) * 2;
		int MAX = more_copies + must_be + (stan2.e1 - stan1.e1 - 1) * 5;
		//for init number
		return (MIN <= dst && dst <= MAX);
	}
}

int nast(int i, PII stan1, int j, PII stan2) {
	assert(i <= j);
	if (i == j) return stan1.e1;

	if (stan1.e1 == stan2.e1) return stan1.e1;

	int value = stan1.e1;
	if (stan1.e2 != 5) {
		if (poss(i + 1, make_pair(value, stan1.e2 + 1), j, stan2)) return value;
	}

	return value + 1;
}

int n;
vector <int> pos;
bool dp[maxn][6];
int tab[maxn];

int main() {
	ios_base::sync_with_stdio(false);
	cin >> n;
	//init
	pos.push_back(0);
	dp[0][5] = 1;

	int lt = 0;
	for (int i=1; i<=n; ++i) {
		cin >> tab[i];
		if (tab[i] > 0) {
			pos.push_back(i);
			lt = i;
		}
	}

	int sz = pos.size();
	for (int i = 0; i + 1 < sz; ++i) {
		int lewe = pos[i], prawe = pos[i + 1];
		for (int a = 1; a <= 5; ++a) {
			if (dp[lewe][a]) {
				for (int b = 1; b <= 5; ++b) {
					if (poss(lewe, {tab[lewe], a}, prawe, {tab[prawe], b})) {
						debug(lewe, a, prawe, b);
						dp[prawe][b] = 1;
					}
				}
			}
		}
	}

	bool odp = false, ans = false;
	int ka = 0;
	if (tab[n] == 0) {
		for (int value = n; value > 0; --value) {
			for (int a=1; a<=5; ++a) {
				for (int b=2; b<=5; ++b) {
					if (!ans && dp[lt][a] && poss(lt, {tab[lt], a}, n, {value, b})) {
						tab[n] = value;
						dp[n][b] = true;
						pos.push_back(n);
						ans = true;
					}
				}
			}
		}
	}

	for (int a=2; a<=5; ++a)
		if (dp[n][a]) odp = true, ka = a;

	if (!odp) OUT("-1");
	sz = pos.size();
	for (int i = sz - 2; i >= 0; --i) {
		int lewe = pos[i], prawe = pos[i + 1];
		for (int a = 1; a <= 5; ++a) {
			if (!dp[lewe][a]) continue;
			if (poss(lewe, {tab[lewe], a}, prawe, {tab[prawe], ka})) {
				int kal = a;
				for (int ruch = lewe; ruch + 1 < prawe; ++ruch) {
					int wstawie = nast(ruch, {tab[ruch], kal}, prawe, {tab[prawe], ka});
					if (wstawie == tab[ruch]) ++kal;
					else kal = 1;
					tab[ruch + 1] = wstawie;
				}

				ka = a;
				break;
			}
		}
	}

	cout << tab[n] << "\n";
	for (int i=1; i<=n; ++i) cout << tab[i] << ' ';
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost {ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); }
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long int ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PLL, PLL > PP;
typedef pair <PII, int> PPI;
typedef pair <int, PII> PIP;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const int mod = 998244353;
const int inf = 1e9+9;
const ll MOD = 1e9+696969;
const long long INF = 4LL * 1000000LL * 1000000LL * 1000000LL;

template<class T> int size(T &&x) {
	return int(x.size());
}
template<class A, class B> ostream& operator<<(ostream &out, const pair<A, B> &p) {
	return out << '(' << p.first << ", " << p.second << ')';
}
template<class T> auto operator<<(ostream &out, T &&x) -> decltype(x.begin(), out) {
	out << '{';
	for(auto it = x.begin(); it != x.end(); ++it)
		out << *it << (it == prev(x.end()) ? "" : ", ");
	return out << '}';
}
void dump() {}
template<class T, class... Args> void dump(T &&x, Args... args) {
	cerr << x << ";  ";
	dump(args...);
}
#ifdef DEBUG
  struct Nl{~Nl(){cerr << '\n';}};
# define debug(x...) cerr << (strcmp(#x, "") ? #x ":  " : ""), dump(x), Nl(), cerr << ""
#else
# define debug(...) 0 && cerr
#endif
mt19937_64 rng(0);
int random(int l, int r) {
	return uniform_int_distribution<int>(l, r)(rng);
}

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
inline void addmod(int &x, int val) {
	x += val;
	while (x >= mod) x -= mod;
}
const int maxn = 200100;

bool poss(int i, PII stan1, int j, PII stan2) {
	assert(i <= j);
	if (i == j) {
		return stan1 == stan2;
	}

	int dst = j - i - 1; //liczb pomiedzy
	if (stan1.e1 == stan2.e1) {
		return (stan1.e2 + dst == stan2.e2);
	}
	else {
		int must_be = (stan1.e2 == 1 ? 1 : 0);
		must_be += stan2.e2 - 1;
		int MIN = must_be + (stan2.e1 - stan1.e1 - 1) * 2;
		int MAX = must_be + (stan2.e1 - stan1.e1 - 1) * 5;
		return (MIN <= dst && dst <= MAX);
	}
}

int nast(int i, PII stan1, int j, PII stan2) {
	assert(i <= j);
	if (i == j) return stan1.e1;

	if (stan1.e1 == stan2.e1) return stan1.e1;

	int value = stan1.e1;
	if (stan1.e2 != 5) {
		if (poss(i + 1, make_pair(value, stan1.e2 + 1), j, stan2)) return value;
	}

	return value + 1;
}

int n;
vector <int> pos;
bool dp[maxn][6];
int tab[maxn];

bool finish(int i, int kro) {
	assert(1 <= kro && kro <= 5);
	if (i == n && kro == 1) return false;
	if (i + 1 == n && kro == 5) return false;
	return true;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin >> n;
	//init
	pos.push_back(0);
	dp[0][5] = 1;

	int lt = 0;
	for (int i=1; i<=n; ++i) {
		cin >> tab[i];
		if (tab[i] > 0) {
			pos.push_back(i);
			lt = i;
		}
	}

	int sz = pos.size();
	for (int i = 0; i + 1 < sz; ++i) {
		int lewe = pos[i], prawe = pos[i + 1];
		for (int a = 1; a <= 5; ++a) {
			if (dp[lewe][a]) {
				for (int b = 1; b <= 5; ++b) {
					if (poss(lewe, {tab[lewe], a}, prawe, {tab[prawe], b})) {
						dp[prawe][b] = 1;
					}
				}
			}
		}
	}

	bool odp = false, ans = false;
	int ka = 0;
	if (tab[n] == 0) {
		for (int value = n; value > 0; --value) {
			for (int a=1; a<=5; ++a) {
				for (int b=2; b<=5; ++b) {
					if (!ans && dp[lt][a] && poss(lt, {tab[lt], a}, n, {value, b})) {
						tab[n] = value;
						dp[n][b] = true;
						ka = b;
						pos.push_back(n);
						ans = true;
					}
				}
			}
		}
	}

	for (int a=2; a<=5; ++a)
		if (dp[n][a]) odp = true;

	if (!odp) OUT("-1");
	sz = pos.size();
	for (int i = sz - 2; i >= 0; --i) {
		int lewe = pos[i], prawe = pos[i + 1];
		for (int a = 1; a <= 5; ++a) {
			if (dp[lewe][a] && poss(lewe, {tab[lewe], a}, prawe, {tab[prawe], ka})) {
				int kal = a;
				for (int ruch = lewe; ruch + 1 < prawe; ++ruch) {

					int wstawie = nast(ruch, {tab[ruch], kal}, prawe, {tab[prawe], ka});
					if (wstawie == tab[ruch]) ++kal;
					else kal = 1;
					//debug(lewe, prawe, ruch, wstawie);
					tab[ruch + 1] = wstawie;
				}

				ka = a;
				break;
			}
		}
	}

	cout << tab[n] << "\n";
	for (int i=1; i<=n; ++i) cout << tab[i] << ' ';
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost {ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); }
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long int ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PLL, PLL > PP;
typedef pair <PII, int> PPI;
typedef pair <int, PII> PIP;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const int mod = 998244353;
const int inf = 1e9+9;
const ll MOD = 1e9+696969;
const long long INF = 4LL * 1000000LL * 1000000LL * 1000000LL;

template<class T> int size(T &&x) {
	return int(x.size());
}
template<class A, class B> ostream& operator<<(ostream &out, const pair<A, B> &p) {
	return out << '(' << p.first << ", " << p.second << ')';
}
template<class T> auto operator<<(ostream &out, T &&x) -> decltype(x.begin(), out) {
	out << '{';
	for(auto it = x.begin(); it != x.end(); ++it)
		out << *it << (it == prev(x.end()) ? "" : ", ");
	return out << '}';
}
void dump() {}
template<class T, class... Args> void dump(T &&x, Args... args) {
	cerr << x << ";  ";
	dump(args...);
}
#ifdef DEBUG
  struct Nl{~Nl(){cerr << '\n';}};
# define debug(x...) cerr << (strcmp(#x, "") ? #x ":  " : ""), dump(x), Nl(), cerr << ""
#else
# define debug(...) 0 && cerr
#endif
mt19937_64 rng(0);
int random(int l, int r) {
	return uniform_int_distribution<int>(l, r)(rng);
}

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
inline void addmod(int &x, int val) {
	x += val;
	while (x >= mod) x -= mod;
}
const int maxn = 200100;

bool poss(int i, PII stan1, int j, PII stan2) {
	assert(i <= j);
	if (i == j) {
		return stan1 == stan2;
	}

	int dst = j - i - 1; //liczb pomiedzy
	if (stan1.e1 == stan2.e1) {
		return (stan1.e2 + dst + 1 == stan2.e2);
	}
	else {
		int must_be = (stan1.e2 == 1 ? 1 : 0);
		int more_copies = 5 - stan1.e2 - must_be; //ile jeszcze mozna wcisnac tego elementu
		must_be += stan2.e2 - 1;
		int MIN = must_be + (stan2.e1 - stan1.e1 - 1) * 2;
		int MAX = more_copies + must_be + (stan2.e1 - stan1.e1 - 1) * 5;
		//for init number
		return (MIN <= dst && dst <= MAX);
	}
}

int nast(int i, PII stan1, int j, PII stan2) {
	assert(i <= j);
	if (i == j) return stan1.e1;

	if (stan1.e1 == stan2.e1) return stan1.e1;

	int value = stan1.e1;
	if (stan1.e2 != 5) {
		if (poss(i + 1, make_pair(value, stan1.e2 + 1), j, stan2)) return value;
	}

	return value + 1;
}

int n;
vector <int> pos;
bool dp[maxn][6];
int tab[maxn];

int main() {
	//cout << nast(1, {1, 1}, 5, {}) << endl;
	ios_base::sync_with_stdio(false);
	cin >> n;
	//init
	pos.push_back(0);
	dp[0][5] = 1;

	int lt = 0;
	for (int i=1; i<=n; ++i) {
		cin >> tab[i];
		if (tab[i] > 0) {
			pos.push_back(i);
			lt = i;
		}
	}

	int sz = pos.size();
	for (int i = 0; i + 1 < sz; ++i) {
		int lewe = pos[i], prawe = pos[i + 1];
		for (int a = 1; a <= 5; ++a) {
			if (dp[lewe][a]) {
				for (int b = 1; b <= 5; ++b) {
					if (poss(lewe, {tab[lewe], a}, prawe, {tab[prawe], b})) {
						debug(lewe, a, prawe, b);
						dp[prawe][b] = 1;
					}
				}
			}
		}
	}

	bool odp = false, ans = false;
	int ka = 0;
	if (tab[n] == 0) {
		for (int value = n; value > 0; --value) {
			for (int a=1; a<=5; ++a) {
				for (int b=2; b<=5; ++b) {
					if (!ans && dp[lt][a] && poss(lt, {tab[lt], a}, n, {value, b})) {
						tab[n] = value;
						dp[n][b] = true;
						ka = b;
						pos.push_back(n);
						ans = true;
					}
				}
			}
		}
	}

	for (int a=2; a<=5; ++a)
		if (dp[n][a]) odp = true;

	if (!odp) OUT("-1");
	sz = pos.size();
	for (int i = sz - 2; i >= 0; --i) {
		int lewe = pos[i], prawe = pos[i + 1];
		for (int a = 1; a <= 5; ++a) {
			if (dp[lewe][a] && poss(lewe, {tab[lewe], a}, prawe, {tab[prawe], ka})) {
				//debug(lewe, a, prawe, ka);
				int kal = a;
				for (int ruch = lewe; ruch + 1 < prawe; ++ruch) {

					int wstawie = nast(ruch, {tab[ruch], kal}, prawe, {tab[prawe], ka});
					if (wstawie == tab[ruch]) ++kal;
					else kal = 1;
					tab[ruch + 1] = wstawie;
				}

				ka = a;
				break;
			}
		}
	}

	cout << tab[n] << "\n";
	for (int i=1; i<=n; ++i) cout << tab[i] << ' ';
}


#include <bits/stdc++.h>
using namespace std;
#define e1 first
#define e2 second
#define pb push_back
#define mp make_pair
#define boost {ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); }
#define eb emplace_back
#define OUT(x) {cout << x; exit(0); }
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define scanf(...) scanf(__VA_ARGS__)?:0
typedef long long int ll;
typedef unsigned long long ull;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <PLL, int> PLLI;
typedef pair <PLL, PLL > PP;
typedef pair <PII, int> PPI;
typedef pair <int, PII> PIP;
typedef pair <ll, int> PLI;
typedef unsigned int ui;
const int mod = 998244353;
const int inf = 1e9+9;
const ll MOD = 1e9+696969;
const long long INF = 4LL * 1000000LL * 1000000LL * 1000000LL;

template<class T> int size(T &&x) {
	return int(x.size());
}
template<class A, class B> ostream& operator<<(ostream &out, const pair<A, B> &p) {
	return out << '(' << p.first << ", " << p.second << ')';
}
template<class T> auto operator<<(ostream &out, T &&x) -> decltype(x.begin(), out) {
	out << '{';
	for(auto it = x.begin(); it != x.end(); ++it)
		out << *it << (it == prev(x.end()) ? "" : ", ");
	return out << '}';
}
void dump() {}
template<class T, class... Args> void dump(T &&x, Args... args) {
	cerr << x << ";  ";
	dump(args...);
}
#ifdef DEBUG
  struct Nl{~Nl(){cerr << '\n';}};
# define debug(x...) cerr << (strcmp(#x, "") ? #x ":  " : ""), dump(x), Nl(), cerr << ""
#else
# define debug(...) 0 && cerr
#endif
mt19937_64 rng(0);
int random(int l, int r) {
	return uniform_int_distribution<int>(l, r)(rng);
}

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
inline void addmod(int &x, int val) {
	x += val;
	while (x >= mod) x -= mod;
}
const int maxn = 200100;

bool poss(int i, PII stan1, int j, PII stan2) {
	assert(i <= j);
	if (i == j) {
		return stan1 == stan2;
	}

	int dst = j - i - 1; //liczb pomiedzy
	if (stan1.e1 == stan2.e1) {
		return (stan1.e2 + dst + 1 == stan2.e2);
	}
	else {
		int must_be = (stan1.e2 == 1 ? 1 : 0);
		must_be += stan2.e2 - 1;
		int MIN = must_be + (stan2.e1 - stan1.e1 - 1) * 2;
		int MAX = must_be + (stan2.e1 - stan1.e1 - 1) * 5;
		return (MIN <= dst && dst <= MAX);
	}
}

int nast(int i, PII stan1, int j, PII stan2) {
	assert(i <= j);
	if (i == j) return stan1.e1;

	if (stan1.e1 == stan2.e1) return stan1.e1;

	int value = stan1.e1;
	if (stan1.e2 != 5) {
		if (poss(i + 1, make_pair(value, stan1.e2 + 1), j, stan2)) return value;
	}

	return value + 1;
}

int n;
vector <int> pos;
bool dp[maxn][6];
int tab[maxn];

bool finish(int i, int kro) {
	assert(1 <= kro && kro <= 5);
	if (i == n && kro == 1) return false;
	if (i + 1 == n && kro == 5) return false;
	return true;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin >> n;
	//init
	pos.push_back(0);
	dp[0][5] = 1;

	int lt = 0;
	for (int i=1; i<=n; ++i) {
		cin >> tab[i];
		if (tab[i] > 0) {
			pos.push_back(i);
			lt = i;
		}
	}

	int sz = pos.size();
	for (int i = 0; i + 1 < sz; ++i) {
		int lewe = pos[i], prawe = pos[i + 1];
		for (int a = 1; a <= 5; ++a) {
			if (dp[lewe][a]) {
				for (int b = 1; b <= 5; ++b) {
					if (poss(lewe, {tab[lewe], a}, prawe, {tab[prawe], b})) {
						dp[prawe][b] = 1;
					}
				}
			}
		}
	}

	bool odp = false, ans = false;
	int ka = 0;
	if (tab[n] == 0) {
		for (int value = n; value > 0; --value) {
			for (int a=1; a<=5; ++a) {
				for (int b=2; b<=5; ++b) {
					if (!ans && dp[lt][a] && poss(lt, {tab[lt], a}, n, {value, b})) {
						tab[n] = value;
						dp[n][b] = true;
						ka = b;
						pos.push_back(n);
						ans = true;
					}
				}
			}
		}
	}

	for (int a=2; a<=5; ++a)
		if (dp[n][a]) odp = true;

	if (!odp) OUT("-1");
	sz = pos.size();
	for (int i = sz - 2; i >= 0; --i) {
		int lewe = pos[i], prawe = pos[i + 1];
		for (int a = 1; a <= 5; ++a) {
			if (dp[lewe][a] && poss(lewe, {tab[lewe], a}, prawe, {tab[prawe], ka})) {
				int kal = a;
				for (int ruch = lewe; ruch + 1 < prawe; ++ruch) {

					int wstawie = nast(ruch, {tab[ruch], kal}, prawe, {tab[prawe], ka});
					if (wstawie == tab[ruch]) ++kal;
					else kal = 1;
					//debug(lewe, prawe, ruch, wstawie);
					tab[ruch + 1] = wstawie;
				}

				ka = a;
				break;
			}
		}
	}

	cout << tab[n] << "\n";
	for (int i=1; i<=n; ++i) cout << tab[i] << ' ';
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MX = 200005;

int a[MX];
int n;

bool possible(int j, int i, int s1, int s2)
{
	if (a[i] == a[j]) return false;
	int cnt = a[i] - a[j] - 1;
	if (s1 == 1) {
		if (j + 1 > n || a[j + 1] != 0) return false;
		s1++;
		j++;
	}

	if (i - s2 + 1 <= j) return false;

	int mn = (max(0, (i - s2) - j - (5 - s1)) + 4) / 5;
	int mx = ((i-s2) - j) / 2;

	return mn <= cnt && cnt <= mx;
}

bool can[MX][6];

int main()
{
	ignore = scanf("%d", &n);
	for (int i = 1; i <= n; i++) ignore = scanf("%d", a + i);

	{ // PREPROCESS
		int pr = 0;
		for (int i = 1; i <= n; i++) {
			if (!a[i]) continue;
			if (a[i] == a[pr]) {
				while (pr < i) {
					a[pr] = a[i];
					pr++;
				}
			}

			pr = i;
		}

		pr = 0;
		for (int i = 1; i <= n; i++) {
			if (!a[i]) continue;
			if (a[i] < pr) {
				printf("-1\n");
				return 0;
			}
			pr = a[i];
		}
	}

	int pr = 0;
	can[0][5] = true;

	for (int i = 1; i <= n; i++) {
		if (!a[i]) continue;

		int cnt = 1;
		while (i + 1 <= n && a[i + 1] == a[i]) {
			i++;
			cnt++;
		}

		while (cnt <= 5) {
			for (int c = 1; c <= 5; c++) {
				if (!can[pr][c]) continue;

				can[i][cnt] |= possible(pr, i, c, cnt);
			}

			cnt++;
		}

		pr = i;
	}

	can[n][1] = false;
	can[n - 1][5] = false;

	int x = 2;
	while (x <= 5 && !can[pr][x]) x++;
	if (x > 5) {
		if (can[pr][1]) x = 1;
	}
	if (x > 5) {
		printf("-1\n");
		return 0;
	}

	if (x == 1) {
		x = 2;
		pr++;
		a[pr] = a[pr - 1];
	}

	for (int i = pr + 1; i <= n; i += 2) {
		if (i + 1 <= n) {
			a[i] = a[i - 1] + 1;
			a[i + 1] = a[i];
		}
		else {
			a[i] = a[i - 1];
		}
	}

	while (pr) {
		int j = pr - 1;
		int t;
		while (j >= 0) {
			bool ok = false;
			for (t = 1; t <= 5; t++) {
				if (can[j][t] && possible(j, pr, t, x)) {
					ok = true;
					break;
				}
			}
			if (ok) break;
			j--;
		}

		if (t == 1) {
			t = 2;
			j++;
			a[j] = a[j - 1];
		}

		while (--pr > j) {
			int cc = 0;
			for (int i = pr; a[i + 1] == a[pr + 1]; i++) cc++;

			a[pr] = a[pr + 1] - 1;
			for (int v = 1; v + cc <= 5; v++) {
				if (a[pr+1] == a[j] || possible(j, pr + cc, t, cc + v)) {
					a[pr] = a[pr + 1];
					break;
				}
			}
		}

		x = t;
	}

	for (int i = 1, cc = 0; i <= n; i++) {
		if (a[i] < a[i - 1]) {
			printf("-1\n");
			return 0;
		}
		if (a[i] == a[i - 1]) {
			cc++;
		}
		else {
			cc = 0;
		}
		if (cc == 5) {
			printf("-1\n");
			return 0;
		}
	}

	printf("%d\n", a[n]);
	for (int i = 1; i <= n; i++) {
		printf("%d ", a[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MX = 200005;

int a[MX];
int n;

bool possible(int j, int i, int s1, int s2, int cnt)
{
	if (s1 == 1) {
		if (j + 1 > n || a[j + 1] != 0) return false;
		s1++;
		j++;
	}

	if (i - s2 + 1 <= j) return false;

	int mn = (max(0, (i - s2) - j - (5 - s1)) + 4) / 5;
	int mx = ((i-s2) - j) / 2;

	return mn <= cnt && cnt <= mx;
}

bool can[MX][6];

int main()
{
	ignore = scanf("%d", &n);
	for (int i = 1; i <= n; i++) ignore = scanf("%d", a + i);

	{
		int pr = 0;
		for (int i = 1; i <= n; i++) {
			if (!a[i]) continue;
			if (a[i] == a[pr]) {
				while (pr < i) {
					a[pr] = a[i];
					pr++;
				}
			}

			pr = i;
		}

		pr = 0;
		for (int i = 1; i <= n; i++) {
			if (!a[i]) continue;
			if (a[i] < pr) {
				printf("-1\n");
				return 0;
			}
			pr = a[i];
		}
	}

	int pr = 0;
	can[0][5] = true;

	for (int i = 1; i <= n; i++) {
		if (!a[i]) continue;

		int cnt = 1;
		while (i + 1 <= n && a[i + 1] == a[i]) {
			i++;
			cnt++;
		}

		while (cnt <= 5) {
			for (int c = 1; c <= 5; c++) {
				if (!can[pr][c]) continue;

				can[i][cnt] = possible(pr, i, c, cnt, a[i] - a[pr] - 1);
			}

			cnt++;
		}

		pr = i;
	}

	can[n][1] = false;
	can[n - 1][5] = false;

	int x = 2;
	while (x <= 5 && !can[pr][x]) x++;
	if (x > 5) {
		if (can[pr][1]) x = 1;
	}
	if (x > 5) {
		printf("-1\n");
		return 0;
	}

	if (x == 1) {
		x = 2;
		pr++;
		a[pr] = a[pr - 1];
	}

	for (int i = pr + 1; i <= n; i += 2) {
		if (i + 1 <= n) {
			a[i] = a[i - 1] + 1;
			a[i + 1] = a[i];
		}
		else {
			a[i] = a[i - 1];
		}
	}

	while (true) {
		int j = pr - 1;
		int t;
		while (j >= 0) {
			bool ok = false;
			for (t = 1; t <= 5; t++) {
				if (can[j][t] && possible(j, pr, t, x, a[pr] - a[j] - 1)) {
					ok = true;
					break;
				}
			}
			if (ok) break;
			j--;
		}

		if (j < 0) break;

		if (t == 1) {
			t = 2;
			j++;
			a[j] = a[j - 1];
		}

		while (--pr > j) {
			if (a[pr]) continue;
			int cc = 0;
			for (int i = pr; a[i + 1] == a[pr + 1]; i++) cc++;

			bool ok = false;
			for (int v = 1; v + cc <= 5; v++) {
				if (v + cc <= 5 && possible(j, pr + cc, t, cc + v, a[pr+1]-a[j]-1)) {
					a[pr] = a[pr + 1];
					ok = true;
					break;
				}
			}
			if (!ok) {
				a[pr] = a[pr + 1] - 1;
			}
		}

		pr = j;
		x = t;
	}

	printf("%d\n", a[n]);
	for (int i = 1; i <= n; i++) {
		printf("%d ", a[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MX = 200005;

int a[MX];
int n;

bool possible(int j, int i, int s1, int s2, int cnt)
{
	if (s1 == 1) {
		if (j + 1 > n || a[j + 1] != 0) return false;
		s1++;
		j++;
	}

	if (i - s2 + 1 <= j) return false;

	int mn = (max(0, (i - s2) - j - (5 - s1)) + 4) / 5;
	int mx = ((i-s2) - j) / 2;

	return mn <= cnt && cnt <= mx;
}

bool can[MX][6];

int main()
{
	ignore = scanf("%d", &n);
	for (int i = 1; i <= n; i++) ignore = scanf("%d", a + i);

	{
		int pr = 0;
		for (int i = 1; i <= n; i++) {
			if (!a[i]) continue;
			if (a[i] == a[pr]) {
				while (pr < i) {
					a[pr] = a[i];
					pr++;
				}
			}

			pr = i;
		}

		pr = 0;
		for (int i = 1; i <= n; i++) {
			if (!a[i]) continue;
			if (a[i] < pr) {
				printf("-1\n");
				return 0;
			}
			pr = a[i];
		}
	}

	int pr = 0;
	can[0][5] = true;

	for (int i = 1; i <= n; i++) {
		if (!a[i]) continue;

		int cnt = 1;
		while (i + 1 <= n && a[i + 1] == a[i]) {
			i++;
			cnt++;
		}

		while (cnt <= 5) {
			for (int c = 1; c <= 5; c++) {
				if (!can[pr][c]) continue;

				can[i][cnt] |= possible(pr, i, c, cnt, a[i] - a[pr] - 1);
			}

			cnt++;
		}

		pr = i;
	}

	can[n][1] = false;
	can[n - 1][5] = false;

	int x = 2;
	while (x <= 5 && !can[pr][x]) x++;
	if (x > 5) {
		if (can[pr][1]) x = 1;
	}
	if (x > 5) {
		printf("-1\n");
		return 0;
	}

	if (x == 1) {
		x = 2;
		pr++;
		a[pr] = a[pr - 1];
	}

	for (int i = pr + 1; i <= n; i += 2) {
		if (i + 1 <= n) {
			a[i] = a[i - 1] + 1;
			a[i + 1] = a[i];
		}
		else {
			a[i] = a[i - 1];
		}
	}

	while (true) {
		int j = pr - 1;
		int t;
		while (j >= 0) {
			bool ok = false;
			for (t = 1; t <= 5; t++) {
				if (can[j][t] && possible(j, pr, t, x, a[pr] - a[j] - 1)) {
					ok = true;
					break;
				}
			}
			if (ok) break;
			j--;
		}

		if (j < 0) break;

		if (t == 1) {
			t = 2;
			j++;
			a[j] = a[j - 1];
		}

		while (--pr > j) {
			int cc = 0;
			for (int i = pr; a[i + 1] == a[pr + 1]; i++) cc++;

			bool ok = false;
			for (int v = 1; v + cc <= 5; v++) {
				if (a[pr+1] == a[j] || (v + cc <= 5 && possible(j, pr + cc, t, cc + v, a[pr+1]-a[j]-1))) {
					a[pr] = a[pr + 1];
					ok = true;
					break;
				}
			}
			if (!ok) {
				a[pr] = a[pr + 1] - 1;
			}
		}

		pr = j;
		x = t;
	}

	for (int i = 1, cc = 0; i <= n; i++) {
		if (a[i] < a[i - 1]) {
			printf("-1\n");
			return 0;
		}
		if (a[i] == a[i - 1]) {
			cc++;
		}
		else {
			cc = 0;
		}
		if (cc == 5) {
			printf("-1\n");
			return 0;
		}
	}

	printf("%d\n", a[n]);
	for (int i = 1; i <= n; i++) {
		printf("%d ", a[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MX = 200005;

int a[MX];
int n;

bool possible(int j, int i, int s1, int s2, int cnt)
{
	if (s1 == 1) {
		if (j + 1 > n || a[j + 1] != 0) return false;
		s1++;
		j++;
	}

	if (i - s2 + 1 <= j) return false;

	int mn = (max(0, (i - s2) - j - (5 - s1)) + 4) / 5;
	int mx = ((i-s2) - j) / 2;

	return mn <= cnt && cnt <= mx;
}

bool can[MX][6];

int main()
{
	ignore = scanf("%d", &n);
	for (int i = 1; i <= n; i++) ignore = scanf("%d", a + i);

	{
		int pr = 0;
		for (int i = 1; i <= n; i++) {
			if (!a[i]) continue;
			if (a[i] == a[pr]) {
				while (pr < i) {
					a[pr] = a[i];
					pr++;
				}
			}

			pr = i;
		}

		pr = 0;
		for (int i = 1; i <= n; i++) {
			if (!a[i]) continue;
			if (a[i] < pr) {
				printf("-1\n");
				return 0;
			}
			pr = a[i];
		}
	}

	int pr = 0;
	can[0][5] = true;

	for (int i = 1; i <= n; i++) {
		if (!a[i]) continue;

		int cnt = 1;
		while (i + 1 <= n && a[i + 1] == a[i]) {
			i++;
			cnt++;
		}

		while (cnt <= 5) {
			for (int c = 1; c <= 5; c++) {
				if (!can[pr][c]) continue;

				can[i][cnt] = possible(pr, i, c, cnt, a[i] - a[pr] - 1);
			}

			cnt++;
		}

		pr = i;
	}

	can[n][1] = false;
	can[n - 1][5] = false;

	int x = 2;
	while (x <= 5 && !can[pr][x]) x++;
	if (x > 5) {
		if (can[pr][1]) x = 1;
	}
	if (x > 5) {
		printf("-1\n");
		return 0;
	}

	if (x == 1) {
		x = 2;
		pr++;
		a[pr] = a[pr - 1];
	}

	for (int i = pr + 1; i <= n; i += 2) {
		if (i + 1 <= n) {
			a[i] = a[i - 1] + 1;
			a[i + 1] = a[i];
		}
		else {
			a[i] = a[i - 1];
		}
	}

	while (true) {
		int j = pr - 1;
		int t;
		while (j >= 0) {
			bool ok = false;
			for (t = 1; t <= 5; t++) {
				if (can[j][t] && possible(j, pr, t, x, a[pr] - a[j] - 1)) {
					ok = true;
					break;
				}
			}
			if (ok) break;
			j--;
		}

		if (j < 0) break;

		if (t == 1) {
			t = 2;
			j++;
			a[j] = a[j - 1];
		}

		while (--pr > j) {
			int cc = 0;
			for (int i = pr; a[i + 1] == a[pr + 1]; i++) cc++;

			bool ok = false;
			for (int v = 1; v + cc <= 5; v++) {
				if (a[pr+1] == a[j] || (v + cc <= 5 && possible(j, pr + cc, t, cc + v, a[pr+1]-a[j]-1))) {
					a[pr] = a[pr + 1];
					ok = true;
					break;
				}
			}
			if (!ok) {
				a[pr] = a[pr + 1] - 1;
			}
		}

		pr = j;
		x = t;
	}

	for (int i = 1, cc = 0; i <= n; i++) {
		if (a[i] < a[i - 1]) {
			printf("-1\n");
			return 0;
		}
		if (a[i] == a[i - 1]) {
			cc++;
		}
		else {
			cc = 0;
		}
		if (cc == 5) {
			printf("-1\n");
			return 0;
		}
	}

	printf("%d\n", a[n]);
	for (int i = 1; i <= n; i++) {
		printf("%d ", a[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MX = 200005;

int a[MX];
int n;

bool possible(int j, int i, int s1, int s2, int cnt)
{
	if (s1 == 1) {
		if (j + 1 > n || a[j + 1] != 0) return false;
		s1++;
		j++;
	}

	if (i - s2 + 1 <= j) return false;

	int mn = (max(0, (i - s2) - j - (5 - s1)) + 4) / 5;
	int mx = ((i-s2) - j) / 2;

	return mn <= cnt && cnt <= mx;
}

bool can[MX][6];

int main()
{
	ignore = scanf("%d", &n);
	for (int i = 1; i <= n; i++) ignore = scanf("%d", a + i);

	{
		int pr = 0;
		for (int i = 1; i <= n; i++) {
			if (!a[i]) continue;
			if (a[i] == a[pr]) {
				while (pr < i) {
					a[pr] = a[i];
					pr++;
				}
			}
		}

		pr = 0;
		for (int i = 1; i <= n; i++) {
			if (!a[i]) continue;
			if (a[i] < pr) {
				printf("-1\n");
				return 0;
			}
			pr = a[i];
		}
	}

	int pr = 0;
	can[0][5] = true;

	for (int i = 1; i <= n; i++) {
		if (!a[i]) continue;

		int cnt = 1;
		while (i + 1 <= n && a[i + 1] == a[i]) {
			i++;
			cnt++;
		}

		while (cnt <= 5) {
			for (int c = 1; c <= 5; c++) {
				if (!can[pr][c]) continue;

				can[i][cnt] = possible(pr, i, c, cnt, a[i] - a[pr] - 1);
			}

			cnt++;
		}

		pr = i;
	}

	can[n][1] = false;
	can[n - 1][5] = false;

	int x = 2;
	while (x <= 5 && !can[pr][x]) x++;
	if (x > 5) {
		if (can[pr][1]) x = 1;
	}
	if (x > 5) {
		printf("-1\n");
		return 0;
	}

	if (x == 1) {
		x = 2;
		pr++;
		a[pr] = a[pr - 1];
	}

	for (int i = pr + 1; i <= n; i += 2) {
		if (i + 1 <= n) {
			a[i] = a[i - 1] + 1;
			a[i + 1] = a[i];
		}
		else {
			a[i] = a[i - 1];
		}
	}

	while (true) {
		int j = pr - 1;
		int t;
		while (j >= 0) {
			bool ok = false;
			for (t = 1; t <= 5; t++) {
				if (can[j][t] && possible(j, pr, t, x, a[pr] - a[j] - 1)) {
					ok = true;
					break;
				}
			}
			if (ok) break;
			j--;
		}

		if (j < 0) break;

		if (t == 1) {
			t = 2;
			j++;
			a[j] = a[j - 1];
		}

		while (--pr > j) {
			if (a[pr]) continue;
			int cc = 0;
			for (int i = pr; a[i + 1] == a[pr + 1]; i++) cc++;

			bool ok = false;
			for (int v = 1; v + cc <= 5; v++) {
				if (v + cc <= 5 && possible(j, pr + cc, t, cc + v, a[pr+1]-a[j]-1)) {
					a[pr] = a[pr + 1];
					ok = true;
					break;
				}
			}
			if (!ok) {
				a[pr] = a[pr + 1] - 1;
			}
		}

		pr = j;
		x = t;
	}

	printf("%d\n", a[n]);
	for (int i = 1; i <= n; i++) {
		printf("%d ", a[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
#define db double
#define pb push_back
#define all(x) begin(x), end(x)
#define SZ(x) (int)(x).size()
#define cps(x) sort(all(x)), (x).erase(unique(all(x)), end(x))
#define cps2(x, y) sort(all(x), y), (x).erase(unique(all(x)), end(x))
#define mem(x, y) memset(& x, y, sizeof(x))
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int n0 = 2e5 + 123, k0 = 1e5 + 123;
int n, a[n0], l[n0], r[n0], p[n0], ans[n0];
array <int, 2> dp[n0][5];
vector <array <int, 2>> seg;

void greedy(int l, int r, int x, int y) {
	if (l > r) return;
	while (x <= y) {
		for (int i = 5; i >= 2; i--) {
			if (i > r - l + 1) continue;
			if ((y - x) * 5 >= (r - l + 1) - i && (y - x) * 2 <= (r - l + 1) - i) {
				for (int j = l; j < l + i; j++)
					ans[j] = x;
				l += i;
				x++;
				break;
			}
		}
	}
}

void rec(int x, int y) {
	int R = seg[x][1] + y;
	int L = dp[x][y][0];
	for (int i = L; i <= R; i++)
		ans[i] = a[seg[x][0]];
	if (x > 0) {
		int R0 = seg[x - 1][1] + dp[x][y][1];
		greedy(R0 + 1, L - 1, a[seg[x - 1][1]] + 1, a[seg[x][0]] - 1);
		rec(x - 1, dp[x][y][1]);
	}	else {
		greedy(1, L - 1, 1, a[seg[x][0]] - 1);
	}
}

int main() {
	ios_base::sync_with_stdio(0), cin.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		if (!l[a[i]]) l[a[i]] = i;
		r[a[i]] = i;
	}
	for (int i = 1; i < k0; i++) {
		if (r[i] - l[i] + 1 > 5) return cout << -1, 0;
		if (l[i])
			seg.pb({l[i], r[i]});
	}
	sort(all(seg));
	mem(dp, -1);
	if (SZ(seg)) {
		int L = seg[0][0], R = seg[0][1];
		for (int j = R; j < min(n + 1, L + 5); j++) {
			if (0 == SZ(seg) - 1 && n - j == 1) continue;
			for (int k = L; k > max(0, j - 5); k--) {
				if (j - k + 1 < 2) continue;
				int d = a[L] - 1, len = k - 1;
				if ((k == 1 && a[L] == 1) || (2 * d <= len && len <= 5 * d))
					dp[0][j - R] = {k, 0};
			}
		}
	}
	for (int i = 1; i < SZ(seg); i++) {
		int L = seg[i][0], R = seg[i][1], R0 = seg[i - 1][1];
		if (R0 >= L) return cout << -1, 0;
		for (int j = R; j < min(n + 1, L + 5); j++) {
			if (i == SZ(seg) - 1 && n - j == 1) continue;
			for (int k = L; k > max(0, j - 5); k--) {
				if (j - k + 1 < 2) continue;
				for (int l = 0; l < 5; l++) {
					int d = a[L] - a[R0] - 1, len = k - (R0 + l) - 1;
					if (dp[i - 1][l][0] != -1 && 2 * d <= len && len <= 5 * d)
						dp[i][j - R] = {k, l};
				}
			}
		}
	}
	int ok = 0;
	if (SZ(seg)) {
		for (int i = 0; i < 5; i++) {
			if (dp[SZ(seg) - 1][i][0] != -1) {
				rec(SZ(seg) - 1, i), ok = 1;
				break;
			}
		}
	}	else ok = 1;
	if (ok) {
		int pos = n + 1;
		for (int i = n; i >= 1; i--) {
			if (ans[i]) break;
			pos = i;
		}
		int x = ans[pos - 1];
		for (int i = pos; i + 1 <= n; i += 2) {
			ans[i] = ++x;
			ans[i + 1] = x;
		}
		if (!ans[n]) ans[n] = ans[n - 1];
		cout << ans[n] << '\n';
		for (int i = 1; i <= n; i++)
			cout << ans[i] << ' ';
	}	else cout << -1;
}


#include <cstdio>
#include <cassert>

const int SMAX = (int)1e+5 + 10;
const int NMAX = 2 * SMAX;

int gArr[NMAX];

struct Block
{
	int l, r;

	int GetLeftVal() const { return gArr[l]; }
	int GetRightVal() const { return gArr[r]; }
	int GetLeftMultiplicity() const;
	int GetRightMultiplicity() const;
	bool IsHomogen() const { return GetLeftVal() == GetRightVal(); }
	void DoFixes(int prefix, int postfix);
} gBlocks[SMAX];

int Block::GetLeftMultiplicity() const
{
	int c = GetLeftVal();
	int i;
	for (i = l + 1; i <= r && gArr[i] == c; ++i)
	{
	}
	return i - l;
}

int Block::GetRightMultiplicity() const
{
	int c = GetRightVal();
	int i;
	for (i = r - 1; i >= l && gArr[i] == c; --i)
	{
	}
	return r - i;
}

void Block::DoFixes(int prefix, int postfix)
{
	int c = gArr[l];
	for (int i = 1; i <= prefix; i++)
	{
		gArr[l - i] = c;
	}

	c = gArr[r];
	for (int i = 1; i <= postfix; i++)
	{
		gArr[r + i] = c;
	}
}

const int MIN_DAY = 2;
const int MAX_DAY = 5;

class State
{
	int mPrevIndex;
	int mDPrefix;
public:
	State() : mPrevIndex(-1), mDPrefix(-1) {}
	State(int aPrevIx, int aDPref) : mPrevIndex(aPrevIx), mDPrefix(aDPref) {}
	bool IsValid() const { return mPrevIndex >= 0; }
	int GetPrevIndex() const { return mPrevIndex; }
	int GetPrefix() const { return mDPrefix; }
};
State myDP[SMAX][MAX_DAY];

void GenNonHomogenBlockEnd(int bIx, const State& best)
{
	int lm = gBlocks[bIx].GetRightMultiplicity();
	for (int d = 0; d < MAX_DAY; ++d)
	{
		if (MIN_DAY <= lm + d && lm + d <= MAX_DAY)
		{
			myDP[bIx][d] = best;
		}
	}
}

void FillAverage(int start, int end, int startVal, int endVal)
{
	int g = end - start;
	long long dVal = endVal - startVal;
	for (int i = 0; i < g; i++)
	{
		gArr[start + i] = startVal + (dVal*i) / g;
	}
}

bool SolveS(int N, int B)
{
	GenNonHomogenBlockEnd(0, State(MAX_DAY, 0));
	for (int i = 1; i < B; ++i)
	{
		Block& last = gBlocks[i - 1];
		Block& cur = gBlocks[i];
		assert(last.GetRightVal() < cur.GetLeftVal());

		const int lm = last.GetRightMultiplicity();
		const int cm = cur.GetLeftMultiplicity();
		const bool bCurHomo = cur.IsHomogen();
		const int valDiff = cur.GetLeftVal() - last.GetRightVal() - 1;
		State firstGood;
		for (int d = 0; d < MAX_DAY; ++d)
		{
			State& st = myDP[i - 1][d];
			if (!st.IsValid())
				continue;

			for (int d2 = MAX_DAY; --d2 >= 0; )
			{
				if ((MIN_DAY <= d2 + cm || bCurHomo) && d2 + cm <= MAX_DAY)
				{
					int g = (cur.l - d2) - (last.r + d) - 1;
					if (MIN_DAY * valDiff <= g && g <= MAX_DAY * valDiff)
					{
						firstGood = State(d, d2);
						if (bCurHomo)
						{
							int freeNum = MAX_DAY - (d2 + cm);
							for (int d3 = ((d2 + cm) == 1) ? 1 : 0; d3 <= freeNum; ++d3)
							{
								if (!myDP[i][d3].IsValid())
								{
									myDP[i][d3] = State(d, d2);
								}
							}
						}
						else
						{
							goto CYCEND;
						}
					}
				}
			}
		}
	CYCEND:
		if (!firstGood.IsValid())
		{
			return false;
		}
		else if (!bCurHomo)
		{
			GenNonHomogenBlockEnd(i, firstGood);
		}
	}

	for (int d = 0; d < MAX_DAY; ++d)
	{
		State& st = myDP[B - 1][d];
		if (!st.IsValid())
			continue;
		int lastPos = gBlocks[B - 1].r + d;
		int rem = (N - 1) - lastPos;
		if (rem >= 0)
		{
			if (rem != 1 || gBlocks[B - 1].GetRightMultiplicity() + d + (gBlocks[B - 1].IsHomogen() ? st.GetPrefix() : 0) < MAX_DAY)
			{
				int dBest = d;
				for (int i = B; --i >= 0; )
				{
					State& bestDP = myDP[i][dBest];
					gBlocks[i].DoFixes(bestDP.GetPrefix(), dBest);
					dBest = bestDP.GetPrevIndex();
				}
				if (rem == 1)
				{
					gArr[N - 1] = gArr[N - 2];
				}

				int lastVal = 0;
				int lastCnt = MIN_DAY;
				bool ret = true;
				for (int j = 0; j < N; )
				{
					if (gArr[j] == 0)
					{
						int k;
						for (k = j + 1; k < N && gArr[k] == 0; ++k)
						{
						}
						int vs = gArr[j - 1] + 1;
						int ve;
						if (k == N)
						{
							ve = vs + (N - j) / 2;
						}
						else
						{
							ve = gArr[k];
						}
						FillAverage(j, k, vs, ve);
						j = k;
					}
					else
					{
						if (lastVal != gArr[j])
						{
							if (lastVal > gArr[j])
								ret = false;
							lastVal = gArr[j];
							if (lastCnt < MIN_DAY)
								ret = false;
							lastCnt = 1;
						}
						else
						{
							if (++lastCnt > MAX_DAY)
							{
								ret = false;
							}
						}
						++j;
					}
				}
				return ret;
			}
		}
	}

	return false;
}

int Genblocks(int N, bool& badConfig)
{
	badConfig = (gArr[0] > 1) || (gArr[1] > 1);
	gArr[0] = gArr[1] = 1;

	gBlocks[0].l = 0;
	gBlocks[0].r = N - 1;
	int nBlocks = 1;
	for (int i = 2; i < N && !badConfig; ++i)
	{
		int aiPrev = gArr[i - 1];
		int ai = gArr[i];
		if ((aiPrev == 0) != (ai == 0))
		{
			if (ai)
			{
				int lastVal = gBlocks[nBlocks - 1].GetRightVal();
				if (lastVal > ai)
				{
					badConfig = true;
				}
				else if (lastVal == ai)
				{
					// join
					for (int j = gBlocks[nBlocks - 1].r + 1; j < i; ++j)
					{
						gArr[j] = ai;
					}
					gBlocks[nBlocks - 1].r = N - 1;
				}
				else
				{
					gBlocks[nBlocks].l = i;
					gBlocks[nBlocks].r = N - 1;
					++nBlocks;
				}
			}
			else
			{
				gBlocks[nBlocks - 1].r = i - 1;
			}
		}
	}
	return nBlocks;
}

int main()
{
//	void DoCheck();
//	return DoCheck();

	int N;
	scanf("%d", &N);
	for (int i = 0; i < N; ++i)
	{
		int ai;
		scanf("%d", &ai);
		gArr[i] = ai;
	}

	bool badConfig;
	int nBlocks = Genblocks(N, badConfig);

	int nBook = -1;
	if (!badConfig)
	{
		if (SolveS(N, nBlocks))
		{
			nBook = gArr[N - 1];
		}
	}
	printf("%d\n", nBook);
	if (nBook >= 0)
	{
		for (int j = 0; j < N; j++)
		{
			printf("%d ", gArr[j]);
		}
	}

	return 0;
}

#if 0

#include <cstdlib>
//using namespace std;

void GenCheck(int bookMax, float eraseRate)
{
	int nBook = rand() % (bookMax - 1) + 2;

	int N = 0;
	for (int i = 1; i <= nBook; ++i)
	{
		int runLen = rand() % (5-1) + 2;
		for (int j = 0; j < runLen; ++j)
		{
			gArr[N++] = i;
		}
	}

	int eraseNum = N * eraseRate;
	for (int k = 0; k < eraseNum; ++k)
	{
		gArr[rand() % N] = 0;
	}

	for (int i = 0; i < N; ++i)
	{
		printf("%d ", gArr[i]);
	}
	printf("\n");

	bool badConfig;
	int nBlocks = Genblocks(N, badConfig);
	assert(!badConfig);

	for (int i = 0; i < nBlocks; ++i)
	{
		for (int j = 0; j < MAX_DAY; ++j)
		{
			myDP[i][j] = State();
		}
	}

	int nBookRes = -1;
	if (!badConfig)
	{
		if (SolveS(N, nBlocks))
		{
			nBookRes = gArr[N - 1];
		}
	}
	assert(nBookRes >= nBook);
}

int DoCheck()
{
	int bookMax = 4;
	float eraseRate = 0.4;
	for (int i = 0*189; ; ++i)
	{
		srand(i);
		GenCheck(bookMax, eraseRate);
	}
	return 0;
}
#endif


#include <cstdio>
#include <cassert>

const int SMAX = (int)1e+5 + 10;
const int NMAX = 2 * SMAX;

int gArr[NMAX];

struct Block
{
	int l, r;

	int GetLeftVal() const { return gArr[l]; }
	int GetRightVal() const { return gArr[r]; }
	int GetLeftMultiplicity() const;
	int GetRightMultiplicity() const;
	bool IsHomogen() const { return GetLeftVal() == GetRightVal(); }
	void DoFixes(int prefix, int postfix);
} gBlocks[SMAX];

int Block::GetLeftMultiplicity() const
{
	int c = GetLeftVal();
	int i;
	for (i = l+1; i <= r && gArr[i] == c; ++i)
	{
	}
	return i - l;
}

int Block::GetRightMultiplicity() const
{
	int c = GetRightVal();
	int i;
	for (i = r - 1; i >= l && gArr[i] == c; --i)
	{
	}
	return r - i;
}

void Block::DoFixes(int prefix, int postfix)
{
	int c = gArr[l];
	for (int i = 1; i < prefix; i++)
	{
		gArr[l - i] = c;
	}

	c = gArr[r];
	for (int i = 1; i < postfix; i++)
	{
		gArr[r + i] = c;
	}
}

const int MIN_DAY = 2;
const int MAX_DAY = 5;

class State
{
	int mPrevIndex;
	int mDPrefix;
public:
	State() : mPrevIndex(-1), mDPrefix(-1) {}
	State(int aPrevIx, int aDPref) : mPrevIndex(aPrevIx), mDPrefix(aDPref) {}
	bool IsValid() const { return mPrevIndex >= 0; }
	int GetPrevIndex() const { return mPrevIndex; }
	int GetPrefix() const { return mDPrefix; }
};
State dp[SMAX][MAX_DAY];

void GenNonHomogenBlockEnd(int bIx, const State& best)
{
	int lm = gBlocks[bIx].GetLeftMultiplicity();
	for (int d = 0; d < MAX_DAY; ++d)
	{
		if (MIN_DAY <= lm + d && lm + d <= MAX_DAY)
		{
			dp[bIx][d] = best;
		}
	}
}

void FillAverage(int start, int end, int startVal, int endVal)
{
	int g = end - start;
	long long dVal = endVal - startVal;
	for (int i = 0; i < g; i++)
	{
		gArr[start + i] = startVal + (dVal*i)/g;
	}
}

bool SolveS(int N, int B)
{
	GenNonHomogenBlockEnd(0, State(MAX_DAY, 0));
	for (int i = 1; i < B; ++i)
	{
		Block& last = gBlocks[i - 1];
		Block& cur = gBlocks[i];
		assert(last.GetRightVal() < cur.GetLeftVal());

		const int lm = last.GetRightMultiplicity();
		const int cm = cur.GetLeftMultiplicity();
		const bool bCurHomo = cur.IsHomogen();
		const int valDiff = cur.GetLeftVal() - last.GetRightVal() - 1;
		State firstGood;
		for (int d = 0; d < MAX_DAY; ++d)
		{
			State& st = dp[i - 1][d];
			if (!st.IsValid())
				continue;

			for (int d2 = MAX_DAY; --d2 >= 0; )
			{
				if ((MIN_DAY <= d2 + cm || bCurHomo) && d2 + cm <= MAX_DAY)
				{
					int g = (cur.l - d2) - (last.r + d) - 1;
					if (MIN_DAY * valDiff <= g && g <= MAX_DAY * valDiff)
					{
						firstGood = State(d, d2);
						if (bCurHomo)
						{
							int freeNum = MAX_DAY - (d2 + cm);
							for (int d3 = ((d2 + cm) == 1) ? 1 : 0; d3 <= freeNum; ++d3)
							{
								if (!dp[i][d3].IsValid())
								{
									dp[i][d3] = State(d, d2);
								}
							}
						}
						else
						{
							goto CYCEND;
						}
					}
				}
			}
		}
CYCEND:
		if (!firstGood.IsValid())
		{
			return false;
		}
		else if (!bCurHomo)
		{
			GenNonHomogenBlockEnd(i, firstGood);
		}
	}

	for (int d = 0; d < MAX_DAY; ++d)
	{
		State& st = dp[B - 1][d];
		if (!st.IsValid())
			continue;
		int lastPos = gBlocks[B - 1].r + d;
		int rem = (N - 1) - lastPos;
		if (rem >= 0)
		{
			if (rem != 1 || gBlocks[B - 1].GetRightMultiplicity() + d < MAX_DAY)
			{
				int dBest = d;
				for (int i = B; --i >= 0; )
				{
					gBlocks[i].DoFixes(dp[i][dBest].GetPrefix(), dBest);
					dBest = dp[i][dBest].GetPrevIndex();
				}
				if (rem == 1)
				{
					gArr[N - 1] = gArr[N - 2];
				}

				int lastVal = 0;
				int lastCnt = MIN_DAY;
				bool ret = true;
				for (int j = 0; j < N; )
				{
					if (gArr[j] == 0)
					{
						int k;
						for (k = j + 1; k < N && gArr[k] == 0; ++k)
						{
						}
						int vs = gArr[j - 1] + 1;
						int ve;
						if (k == N)
						{
							ve = vs + (N - j) / 2;
						}
						else
						{
							ve = gArr[k];
						}
						FillAverage(j, k, vs, ve);
						j = k;
					}
					else
					{
						if (lastVal != gArr[j])
						{
							if (lastVal > gArr[j])
								ret = false;
							lastVal = gArr[j];
							if (lastCnt < MIN_DAY)
								ret = false;
							lastCnt = 1;
						}
						else
						{
							if (++lastCnt > MAX_DAY)
							{
								ret = false;
							}
						}
						++j;
					}
				}
				return ret;
			}
		}
	}

	return false;
}

int main()
{
	int N;
	scanf("%d", &N);
	for (int i = 0; i < N; ++i)
	{
		int ai;
		scanf("%d", &ai);
		gArr[i] = ai;
	}

	bool badConfig = (gArr[0]>1) || (gArr[1]>1);
	gArr[0] = gArr[1] = 1;

	gBlocks[0].l = 0;
	gBlocks[0].r = N - 1;
	int nBlocks = 1;
	for (int i = 2; i < N && !badConfig; ++i)
	{
		int aiPrev = gArr[i-1];
		int ai = gArr[i];
		if ((aiPrev == 0) != (ai == 0))
		{
			if (ai)
			{
				int lastVal = gBlocks[nBlocks - 1].GetRightVal();
				if (lastVal > ai)
				{
					badConfig = true;
				}
				else if (lastVal == ai)
				{
					// join
					for (int j = gBlocks[nBlocks - 1].r + 1; j < i; ++j)
					{
						gArr[j] = ai;
					}
				}
				else
				{
					gBlocks[nBlocks].l = i;
					gBlocks[nBlocks].r = N - 1;
					++nBlocks;
				}
			}
			else
			{
				gBlocks[nBlocks - 1].r = i - 1;
			}
		}
	}

	int nBook = -1;
	if (!badConfig)
	{
		if (SolveS(N, nBlocks))
		{
			nBook = gArr[N-1];
		}
	}
	printf("%d\n", nBook);
	if (nBook >= 0)
	{
		for (int j = 0; j < N; j++)
		{
			printf("%d ", gArr[j]);
		}
	}

	return 0;
}


/*
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int nMax = 200001;
#define rank Rank
#define abs Abs

int  num[nMax];
int sa[nMax], rank[nMax], height[nMax];
int wa[nMax], wb[nMax], wv[nMax], wd[300];

// wd[i] = j   表示原串中不大于i字符共有j个
// rank[i] = j 表示以i为开头的后缀 排第j
// sa[i]   = j 表示第i大的字符串是以j开头的后缀

int cmp(int *r, int a, int b, int l){
return r[a] == r[b] && r[a+l] == r[b+l];
}
//主要是求出sa数组，rank数组可以由sa得到的
void da(int *r, int n, int m){          //  倍增算法 r为待匹配数组  n为总长度 m为字符范围
// n为字符串长度，m为字符的取值范围，r为字符串。后面的j为每次排序时子串的长度。
int i, j, p, *x = wa, *y = wb, *t;

//下面4行计算每个字母的排名
for(i = 0; i < m; i ++) wd[i] = 0;
for(i = 0; i < n; i ++) wd[x[i]=r[i]] ++;  //统计字符的个数
for(i = 1; i < m; i ++) wd[i] += wd[i-1];  //统计不大于字符的字符个数
for(i = n-1; i >= 0; i --) sa[-- wd[x[i]]] = i;  //计算每个字符排名  i之所以从n-1开始循环，是为了保证在当字符串中有相等的字符串时，默认靠前的字符串更小一些。
//sa[i] 表示ascil i的字符在字符串n中的排名为sa[i]

//基数排序
for(j = 1, p = 1; p < n; j *= 2, m = p){
//变量j 是当前字符串的长度，数组y 保存的是对第二关键字排序的结果。
//对第二关键字排序
for(p = 0, i = n-j; i < n; i ++) y[p ++] = i;
for(i = 0; i < n; i ++) if(sa[i] >= j) y[p ++] = sa[i] - j;

//对第一关键字排序
for(i = 0; i < n; i ++) wv[i] = x[y[i]];
for(i = 0; i < m; i ++) wd[i] = 0;
for(i = 0; i < n; i ++) wd[wv[i]] ++;
for(i = 1; i < m; i ++) wd[i] += wd[i-1];
for(i = n-1; i >= 0; i --) sa[-- wd[wv[i]]] = y[i];

/*
计算rank 值。这里要注
意的是，可能有多个字符串的rank 值是相同的，所以必须比较两个字符串是否
完全相同，y 数组的值已经没有必要保存，为了节省空间，这里用y 数组保存rank
值。这里又有一个小优化，将x 和y 定义为指针类型，复制整个数组的操作可以
用交换指针的值代替，不必将数组中值一个一个的复制。
*/
/*
for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; i ++){
x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p - 1: p ++;
}
}
}
/*
待排序的字符串放在r 数组中，从r[0]到r[n-1]，长度为n，且最大值小
于m。为了函数操作的方便，约定除r[n-1]外所有的r[i]都大于0, r[n-1]=0。
函数结束后，结果放在sa 数组中，从sa[0]到sa[n-1]。
*/
/*
void calHeight(int *r, int n){           //  求height数组。
int i, j, k = 0;
for(i = 1; i <= n; i ++) rank[sa[i]] = i;
for(i = 0; i < n; height[rank[i ++]] = k){
for(k ? k -- : 0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k ++);
}
}

int loc[nMax],m;
char str[nMax],res[nMax];
bool vis[1004];
inline int abs(int a){if(a>0)return a;return -a;}

bool check(int mid,int len){
int i,j;
// cout<<"mid"<<mid<<endl;
for(i=2;i<=len;i++){
if(height[i]<mid)continue;
for(j=i-1;j>=2;j--){
//       cout<<i<<' '<<j<<endl;
if(abs(sa[i]-sa[j])>=mid){
return 1;
}
if(height[j]<mid)break;
}
}
return 0;
}

int main(){
int n,k,i,j,a,b,sp,ans;
while(scanf("%d",&n)&&n){
n--;
ans=0;
for(i=0;i<=n;i++){
scanf("%d",&num[i]);
}
if(n<10){
printf("0\n");
continue;
}
for(i=0;i<n;i++){
num[i]=num[i+1]-num[i]+90;
}
num[n]=0;
da(num,n+1,200);
calHeight(num,n);

int left=3,right=n,mid;//开始二分
while(right>=left){
mid=(right+left)/2;
if(check(mid,n)){         //判断长度为mid的串是否是所有字符串的公共子串
left=mid+1;
ans=mid;
}
else{
right=mid-1;
}
}
if(ans<4){
printf("0\n");
}
else{
printf("%d\n",ans+1);
}
}
return 0;
}
/*
30
25 27 30 34 39 45 52 60 69 79 69 60 52 45 39 34 30 26 22 18
82 78 74 70 66 67 64 60 65 80

*/
#include<iostream>
using namespace std;
int a[200010],cnt[100002],n;
pair<int,int> Max[200010],Min[200010];

int main()
{
	//ios::sync_with_stdio(0);
	cin>>n;
	for(int i=1;i<=n;++i)
		cin>>a[i];
	if(a[1]>1)  cout<<"-1"<<endl;
	else{
		bool flag=1;
		Max[1]=Min[1]=make_pair(1,1);
		for(int i=2;i<=n&&flag;++i)
		{
			if(Max[i-1].second>=2)  Max[i]=make_pair(Max[i-1].first+1,1);
			else Max[i]=make_pair(Max[i-1].first,Max[i-1].second+1);
      		                            	          // 上一本书数目大于2。能过，不断地加 112233  小于二，则添加
			if(Min[i-1].second==5)  Min[i]=make_pair(Min[i-1].first+1,1);
			else Min[i]=make_pair(Min[i-1].first,Min[i-1].second+1);
			                                          //  i[1]=5  满书，放下一个   111112222233333
			if(a[i]){
				if(a[i]<Min[i].first || a[i]>Max[i].first) flag=0;                //cout<<"\1"<<endl;}
				else{
					Max[i]=min(Max[i],make_pair(a[i],5));
					Min[i]=max(Min[i],make_pair(a[i],1));
				}  // 状态转移
			}
		}
		if(flag)
		{
			pair<int,int> ans = Max[n];
			if(ans.second==1)  ans=make_pair(ans.first-1,5);  // 最后一天要大于等于2
			if(ans<Min[n])  cout<<-1<<endl;
			else{
				cout<<ans.first<<endl;
				a[n]=ans.first;
				cnt[a[n]]=1;
				for(int i=n-1;i;--i)
				{
					a[i]=min(Max[i].first,a[i+1]);
					if(cnt[a[i]]==5)  a[i]--;
					cnt[a[i]]++;
				}
				for(int i=1;i<=n;++i)
					cout<<a[i]<<' ';
				cout<<endl;
			}
		}
		else cout<<-1<<endl;
	}
	return 0;
}


#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <bitset>
#include <queue>
#include <set>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;

#define LL long long
#define ULL unsigned long long
#define eps 1e-9
#define N (300000 + 10)
#define M (100000 + 10)
#define pii pair<int,int>
#define MP make_pair
#define inf 0x3f3f3f3f
#define md (ll+rr>>1)
#define lson ll, md, ls
#define rson md + 1, rr, rs
#define ls i<<1
#define rs i<<1|1
#define mod 1000000007
#define Pi acos(-1.0)

struct node {
	int x, y;
	node() {}
	node(int x, int y) : x(x), y(y) {}
	bool operator < (const node &ot) const {
		return x < ot.x || (x == ot.x && y < ot.y);
	}
}l[N], r[N];
int cnt[N];
int a[N];
int main() {
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
	int pre = 0;
	if(a[1] > 1) {
		puts("-1");
		return 0;
	}
	for(int i = 1; i <= n; ++i) if(a[i]) {
		if(a[i] < pre) {
			puts("-1");
			return 0;
		}
		pre = a[i];
	}

	l[0] = r[0] = node(1, 0);
	for(int i = 1; i <= n; ++i) {
		l[i] = l[i-1]; l[i].y++;
		r[i] = r[i-1]; r[i].y++;
		if(l[i].y > 5) l[i].x++, l[i].y = 1;
		if(r[i].y > 2) r[i].x++, r[i].y = 1;
		if(a[i] && (a[i] < l[i].x || a[i] > r[i].x)) {
			puts("-1");
			return 0;
		}
		if(a[i]) l[i] = max(l[i], node(a[i], 1));
		if(a[i]) r[i] = min(r[i], node(a[i], 5));
	}
	node ans = r[n];
	if(ans.y == 1) ans.x --, ans.y = 5;
	if(ans < l[n]) {
		puts("-1");
		return 0;
	}
	printf("%d\n", ans.x);
	a[n] = ans.x;
	cnt[a[n]] = 1;
	for(int i = n-1; i > 0; --i) {
		a[i] = min(a[i+1], r[i].x);
		if(cnt[a[i]] == 5) a[i]--;
		cnt[a[i]]++;
	}
	for(int i = 1; i <= n; ++i)
		printf("%d%c", a[i], i == n ? '\n' : ' ');
}


#pragma comment(linker, "/STACK:600000000")
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>

#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <queue>
#include <stack>
#include <list>

#include <ctime>
#include <cassert>

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector <int> vi;
#define sz(s) int((s).size())

typedef long double ldb;
typedef long long int64;
typedef pair <int, int> pii;
typedef pair <double, double> pdd;

#define y0 wwwwwww
#define y1 qqqqqqq
#define next NEXT
#define prev PREV
#define forn(i, n) for (int i = 0; i < (int) n; i++)
#define ford(i, n) for (int i = (int) n - 1; i >= 0; i--)
#define seta(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define last(a) a[a.size() - 1]
#define mp make_pair
#define fs first
#define sc second

template <class T> T sqr(T x) { return x * x; }

double const pi = 3.1415926535897932384626433832795;
int const inf = (int) 1e9;
int64 const inf64 = (int64) 4e18;
const string name = "e";

const int NMAX = 200010;

int n, a[NMAX], d[NMAX][6], ans[NMAX], prev[NMAX][6];
vector<pii> q;

vector<pii> get_opt(int idx1, int col1, int sh1, int idx2, int col2, int sh2, bool& answer) {
	vector<pii> res;
	answer = 0;
	if (col1 > col2 || (col1 == col2 && sh1 >= sh2)) return res;
	if (col1 == col2) {
		if (sh2 - sh1 == idx2 - idx1) {
			forn(i, sh2 - sh1 - 1)
				res.pb(mp(idx1 + i + 1, col1));
			answer = 1;
		}
		return res;
	}

	vector<pii> RES;
	forn(i, sh2 - 1)
		RES.pb(mp(idx2 - i - 1, col2));
	idx2 -= sh2, col2--;
	for (int i = max(0, 2 - sh1); i < 6 - sh1; ++i) {
		res = RES;
		forn(j, i)
			res.pb(mp(idx1 + j + 1, col1));
		int newidx1 = idx1 + i + 1;
		int newcol1 = col1 + 1;

		if (col2 == col1 - 1) {
			if (idx2 == newidx1 - 1) {
				answer = 1;
				return res;
			}
			continue;
		}
		int delta_idx = idx2 - newidx1 + 1;
		int delta_col = col2 - newcol1 + 1;
		if (2 * delta_col <= delta_idx && delta_idx <= 5 * delta_col) {
			int sz, num;
			if (delta_col == 0) sz = 0, num = 0;
			else sz = delta_idx / delta_col, num = delta_col - delta_idx % delta_col;
			forn(j, num) {
				forn(f, sz)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			forn(j, delta_col - num) {
				forn(f, sz + 1)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			answer = 1;
			return res;
		}
	}
	res.clear();
	return res;
}

int may(int idx1, int col1, int sh1, int idx2, int col2, int sh2) {
	bool answer = 0;
	vector<pii> ept = get_opt(idx1, col1, sh1, idx2, col2, sh2, answer);
	return answer;
}

void rec(int x, int y) {
	ans[q[x].fs] = q[x].sc;
//	if (q[x].sc == 1925 && x > 0 && q[x - 1].sc == 1925 && y <= prev[x][y]) exit(1);
	if (x == 0) return;
	rec(x - 1, prev[x][y]);
	bool unused = 0;
	vector<pii> ept = get_opt(q[x - 1].fs, q[x - 1].sc, prev[x][y], q[x].fs, q[x].sc, y, unused);

	forn(i, ept.size())
		ans[ept[i].fs] = ept[i].sc;
}

int main() {
//	freopen((name + ".in").data(), "r", stdin);
//	freopen((name + ".out").data(), "w", stdout);

	cin >> n;
	q.pb(mp(0, 1));
	forn(i, n) {
		scanf("%d", &a[i]);
		if (i == 0 && a[i] != 0) {
			if (a[i] != 1) {
				cout << -1 << endl;
				return 0;
			}
		}
		else if (a[i] != 0) q.pb(mp(i, a[i]));
	}
	seta(d, 0);
	d[0][1] = 1;
	forn(i, q.size() - 1)
		forn(j, 6)
			if (j && d[i][j])
				forn(f, 6) {
					if (f && may(q[i].fs, q[i].sc, j, q[i + 1].fs, q[i + 1].sc, f))
						d[i + 1][f] = 1;
						prev[i + 1][f] = j;
				}

	ford(j, 6)
		if (d[q.size() - 1][j] && (j >= 2 || q[q.size() - 1].fs != n - 1) && (j <= 4 || q[q.size() - 1].fs != n - 2)) {
			rec(q.size() - 1, j);
			int now = q[q.size() - 1].fs + 1;
			if (j == 1)
				ans[now++] = q[q.size() - 1].sc;
			while (now < n) {
				if (now == n - 1) {
					ans[now] = ans[now - 1];
					now++;
				}
				else {
					ans[now] = ans[now - 1] + 1;
					ans[now + 1] = ans[now - 1] + 1;
					now += 2;
				}
			}
			cout << ans[n - 1] << endl;
			forn(i, n) {
				if (i) printf(" ");
				printf("%d", ans[i]);
			}
			cout << endl;
			exit(0);
		}
	cout << -1 << endl;

	return 0;
}


#pragma comment(linker, "/STACK:600000000")
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>

#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <queue>
#include <stack>
#include <list>

#include <ctime>
#include <cassert>

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector <int> vi;
#define sz(s) int((s).size())

typedef long double ldb;
typedef long long int64;
typedef pair <int, int> pii;
typedef pair <double, double> pdd;

#define y0 wwwwwww
#define y1 qqqqqqq
#define next NEXT
#define prev PREV
#define forn(i, n) for (int i = 0; i < (int) n; i++)
#define ford(i, n) for (int i = (int) n - 1; i >= 0; i--)
#define seta(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define last(a) a[a.size() - 1]
#define mp make_pair
#define fs first
#define sc second

template <class T> T sqr(T x) { return x * x; }

double const pi = 3.1415926535897932384626433832795;
int const inf = (int) 1e9;
int64 const inf64 = (int64) 4e18;
const string name = "e";

const int NMAX = 200010;

int n, a[NMAX], d[NMAX][6], ans[NMAX], prev[NMAX][6];
vector<pii> q;

vector<pii> get_opt(int idx1, int col1, int sh1, int idx2, int col2, int sh2, bool& answer) {
	vector<pii> res;
	answer = 0;
	if (col1 == col2) {
		if (sh2 - sh1 == idx2 - idx1) {
			forn(i, sh2 - sh1 - 1)
				res.pb(mp(idx1 + i + 1, col1));
			answer = 1;
		}
		return res;
	}

	vector<pii> RES;
	forn(i, sh2 - 1)
		RES.pb(mp(idx2 - i - 1, col2));
	idx2 -= sh2, col2--;
	for (int i = max(0, 2 - sh1); i < 6 - sh1; ++i) {
		res = RES;
		forn(j, i)
			res.pb(mp(idx1 + j + 1, col1));
		int newidx1 = idx1 + i + 1;
		int newcol1 = col1 + 1;

		if (col2 == col1 - 1) {
			if (idx2 == newidx1 - 1) {
				answer = 1;
				return res;
			}
			continue;
		}
		int delta_idx = idx2 - newidx1 + 1;
		int delta_col = col2 - newcol1 + 1;
		if (2 * delta_col <= delta_idx && delta_idx <= 5 * delta_col) {
			int sz, num;
			if (delta_col == 0) sz = 0, num = 0;
			else sz = delta_idx / delta_col, num = delta_col - delta_idx % delta_col;
			forn(j, num) {
				forn(f, sz)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			forn(j, delta_col - num) {
				forn(f, sz + 1)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			answer = 1;
			return res;
		}
	}
	res.clear();
	return res;
}

int may(int idx1, int col1, int sh1, int idx2, int col2, int sh2) {
	bool answer = 0;
	vector<pii> ept = get_opt(idx1, col1, sh1, idx2, col2, sh2, answer);
	return answer;
}

void rec(int x, int y) {
	ans[q[x].fs] = q[x].sc;
	if (q[x].sc == 1925 && x > 0 && q[x - 1].sc == 1925 && y <= prev[x][y]) exit(1);
	if (x == 0) return;
	rec(x - 1, prev[x][y]);
	bool unused = 0;
	vector<pii> ept = get_opt(q[x - 1].fs, q[x - 1].sc, prev[x][y], q[x].fs, q[x].sc, y, unused);

	forn(i, ept.size())
		ans[ept[i].fs] = ept[i].sc;
}

int main() {
//	freopen((name + ".in").data(), "r", stdin);
//	freopen((name + ".out").data(), "w", stdout);

	cin >> n;
	q.pb(mp(0, 1));
	forn(i, n) {
		scanf("%d", &a[i]);
		if (i == 0 && a[i] != 0) {
			if (a[i] != 1) {
				cout << -1 << endl;
				return 0;
			}
		}
		else if (a[i] != 0) q.pb(mp(i, a[i]));
	}
	seta(d, 0);
	d[0][1] = 1;
	forn(i, q.size() - 1)
		forn(j, 6)
			if (j && d[i][j])
				forn(f, 6) {
					if (f && may(q[i].fs, q[i].sc, j, q[i + 1].fs, q[i + 1].sc, f))
						d[i + 1][f] = 1;
						prev[i + 1][f] = j;
				}

	ford(j, 6)
		if (d[q.size() - 1][j] && (j >= 2 || q[q.size() - 1].fs != n - 1) && (j <= 4 || q[q.size() - 1].fs != n - 2)) {
			rec(q.size() - 1, j);
			int now = q[q.size() - 1].fs + 1;
			if (j == 1)
				ans[now++] = q[q.size() - 1].sc;
			while (now < n) {
				if (now == n - 1) {
					ans[now] = ans[now - 1];
					now++;
				}
				else {
					ans[now] = ans[now - 1] + 1;
					ans[now + 1] = ans[now - 1] + 1;
					now += 2;
				}
			}
			cout << ans[n - 1] << endl;
			forn(i, n) {
				if (i) printf(" ");
				printf("%d", ans[i]);
			}
			cout << endl;
			exit(0);
		}
	cout << -1 << endl;

	return 0;
}


#pragma comment(linker, "/STACK:600000000")
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>

#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <queue>
#include <stack>
#include <list>

#include <ctime>
#include <cassert>

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector <int> vi;
#define sz(s) int((s).size())

typedef long double ldb;
typedef long long int64;
typedef pair <int, int> pii;
typedef pair <double, double> pdd;

#define y0 wwwwwww
#define y1 qqqqqqq
#define next NEXT
#define prev PREV
#define forn(i, n) for (int i = 0; i < (int) n; i++)
#define ford(i, n) for (int i = (int) n - 1; i >= 0; i--)
#define seta(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define last(a) a[a.size() - 1]
#define mp make_pair
#define fs first
#define sc second

template <class T> T sqr(T x) { return x * x; }

double const pi = 3.1415926535897932384626433832795;
int const inf = (int) 1e9;
int64 const inf64 = (int64) 4e18;
const string name = "e";

const int NMAX = 200010;

int n, a[NMAX], d[NMAX][6], ans[NMAX], prev[NMAX][6];
vector<pii> q;

vector<pii> get_opt(int idx1, int col1, int sh1, int idx2, int col2, int sh2, bool& answer) {
	vector<pii> res;
	answer = 0;
	if (col1 == col2) {
		if (sh2 - sh1 == idx2 - idx1) {
			forn(i, sh2 - sh1 - 1)
				res.pb(mp(idx1 + i + 1, col1));
			answer = 1;
		}
		return res;
	}

	vector<pii> RES;
	forn(i, sh2 - 1)
		RES.pb(mp(idx2 - i - 1, col2));
	idx2 -= sh2, col2--;
	for (int i = max(0, 2 - sh1); i < 6 - sh1; ++i) {
		res = RES;
		forn(j, i)
			res.pb(mp(idx1 + j + 1, col1));
		int newidx1 = idx1 + i + 1;
		int newcol1 = col1 + 1;

		if (col2 == col1 - 1) {
			if (idx2 == newidx1 - 1) {
				answer = 1;
				return res;
			}
			continue;
		}
		int delta_idx = idx2 - newidx1 + 1;
		int delta_col = col2 - newcol1 + 1;
		if (2 * delta_col <= delta_idx && delta_idx <= 5 * delta_col) {
			int sz, num;
			if (delta_col == 0) sz = 0, num = 0;
			else sz = delta_idx / delta_col, num = delta_col - delta_idx % delta_col;
			forn(j, num) {
				forn(f, sz)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			forn(j, delta_col - num) {
				forn(f, sz + 1)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			answer = 1;
			return res;
		}
	}
	res.clear();
	return res;
}

int may(int idx1, int col1, int sh1, int idx2, int col2, int sh2) {
	bool answer = 0;
	vector<pii> ept = get_opt(idx1, col1, sh1, idx2, col2, sh2, answer);
	return answer;
}

void rec(int x, int y) {
	ans[q[x].fs] = q[x].sc;
	if (q[x].sc == 1925 && x > 0 && q[x - 1].sc == 1925) exit(1);
	if (x == 0) return;
	rec(x - 1, prev[x][y]);
	bool unused = 0;
	vector<pii> ept = get_opt(q[x - 1].fs, q[x - 1].sc, prev[x][y], q[x].fs, q[x].sc, y, unused);

	forn(i, ept.size())
		ans[ept[i].fs] = ept[i].sc;
}

int main() {
//	freopen((name + ".in").data(), "r", stdin);
//	freopen((name + ".out").data(), "w", stdout);

	cin >> n;
	q.pb(mp(0, 1));
	forn(i, n) {
		scanf("%d", &a[i]);
		if (i == 0 && a[i] != 0) {
			if (a[i] != 1) {
				cout << -1 << endl;
				return 0;
			}
		}
		else if (a[i] != 0) q.pb(mp(i, a[i]));
	}
	seta(d, 0);
	d[0][1] = 1;
	forn(i, q.size() - 1)
		forn(j, 6)
			if (j && d[i][j])
				forn(f, 6) {
					if (f && may(q[i].fs, q[i].sc, j, q[i + 1].fs, q[i + 1].sc, f))
						d[i + 1][f] = 1;
						prev[i + 1][f] = j;
				}

	ford(j, 6)
		if (d[q.size() - 1][j] && (j >= 2 || q[q.size() - 1].fs != n - 1) && (j <= 4 || q[q.size() - 1].fs != n - 2)) {
			rec(q.size() - 1, j);
			int now = q[q.size() - 1].fs + 1;
			if (j == 1)
				ans[now++] = q[q.size() - 1].sc;
			while (now < n) {
				if (now == n - 1) {
					ans[now] = ans[now - 1];
					now++;
				}
				else {
					ans[now] = ans[now - 1] + 1;
					ans[now + 1] = ans[now - 1] + 1;
					now += 2;
				}
			}
			cout << ans[n - 1] << endl;
			forn(i, n) {
				if (i) printf(" ");
				printf("%d", ans[i]);
			}
			cout << endl;
			exit(0);
		}
	cout << -1 << endl;

	return 0;
}


#pragma comment(linker, "/STACK:600000000")
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>

#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <queue>
#include <stack>
#include <list>

#include <ctime>
#include <cassert>

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector <int> vi;
#define sz(s) int((s).size())

typedef long double ldb;
typedef long long int64;
typedef pair <int, int> pii;
typedef pair <double, double> pdd;

#define y0 wwwwwww
#define y1 qqqqqqq
#define next NEXT
#define prev PREV
#define forn(i, n) for (int i = 0; i < (int) n; i++)
#define ford(i, n) for (int i = (int) n - 1; i >= 0; i--)
#define seta(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define last(a) a[a.size() - 1]
#define mp make_pair
#define fs first
#define sc second

template <class T> T sqr(T x) { return x * x; }

double const pi = 3.1415926535897932384626433832795;
int const inf = (int) 1e9;
int64 const inf64 = (int64) 4e18;
const string name = "e";

const int NMAX = 200010;

int n, a[NMAX], d[NMAX][6], ans[NMAX], prev[NMAX][6];
vector<pii> q;

vector<pii> get_opt(int idx1, int col1, int sh1, int idx2, int col2, int sh2, bool& answer) {
	vector<pii> res;
	answer = 0;
	//if (col1 > col2 || (col1 == col2 && sh1 >= sh2)) return res;
	if (col1 == col2) {
		if (sh2 - sh1 == idx2 - idx1) {
			forn(i, sh2 - sh1 - 1)
				res.pb(mp(idx1 + i + 1, col1));
			answer = 1;
		}
		return res;
	}

	vector<pii> RES;
	forn(i, sh2 - 1)
		RES.pb(mp(idx2 - i - 1, col2));
	idx2 -= sh2, col2--;
	for (int i = max(0, 2 - sh1); i < 6 - sh1; ++i) {
		res = RES;
		forn(j, i)
			res.pb(mp(idx1 + j + 1, col1));
		int newidx1 = idx1 + i + 1;
		int newcol1 = col1 + 1;

		if (col2 == col1 - 1) {
			if (idx2 == newidx1 - 1) {
				answer = 1;
				return res;
			}
			continue;
		}
		int delta_idx = idx2 - newidx1 + 1;
		int delta_col = col2 - newcol1 + 1;
		if (2 * delta_col <= delta_idx && delta_idx <= 5 * delta_col) {
			int sz, num;
			if (delta_col == 0) sz = 0, num = 0;
			else sz = delta_idx / delta_col, num = delta_col - delta_idx % delta_col;
			forn(j, num) {
				forn(f, sz)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			forn(j, delta_col - num) {
				forn(f, sz + 1)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			answer = 1;
			return res;
		}
	}
	res.clear();
	return res;
}

int may(int idx1, int col1, int sh1, int idx2, int col2, int sh2) {
	bool answer = 0;
	vector<pii> ept = get_opt(idx1, col1, sh1, idx2, col2, sh2, answer);
	return answer;
}

void rec(int x, int y) {
	ans[q[x].fs] = q[x].sc;
	//if (q[x].sc == 1925 && x > 0 && q[x - 1].sc == 1925 && y == prev[x][y]) exit(1);
	if (x == 0) return;
	rec(x - 1, prev[x][y]);
	bool unused = 0;
	vector<pii> ept = get_opt(q[x - 1].fs, q[x - 1].sc, prev[x][y], q[x].fs, q[x].sc, y, unused);

	forn(i, ept.size())
		ans[ept[i].fs] = ept[i].sc;
}

int main() {
//	freopen((name + ".in").data(), "r", stdin);
//	freopen((name + ".out").data(), "w", stdout);

	cin >> n;
	q.pb(mp(0, 1));
	forn(i, n) {
		scanf("%d", &a[i]);
		if (i == 0 && a[i] != 0) {
			if (a[i] != 1) {
				cout << -1 << endl;
				return 0;
			}
		}
		else if (a[i] != 0) q.pb(mp(i, a[i]));
	}
	seta(d, 0);
	d[0][1] = 1;
	forn(i, q.size() - 1)
		forn(j, 6)
			if (j && d[i][j])
				forn(f, 6) {
					if (f && may(q[i].fs, q[i].sc, j, q[i + 1].fs, q[i + 1].sc, f)) {
						d[i + 1][f] = 1;
						prev[i + 1][f] = j;
					}
				}

	ford(j, 6)
		if (d[q.size() - 1][j] && (j >= 2 || q[q.size() - 1].fs != n - 1)/* && (j <= 4 || q[q.size() - 1].fs != n - 2)*/) {
			rec(q.size() - 1, j);
			int now = q[q.size() - 1].fs + 1;
			if (j == 1)
				ans[now++] = q[q.size() - 1].sc;
			while (now < n) {
				if (now == n - 1) {
					ans[now] = ans[now - 1];
					now++;
				}
				else {
					ans[now] = ans[now - 1] + 1;
					ans[now + 1] = ans[now - 1] + 1;
					now += 2;
				}
			}
			cout << ans[n - 1] << endl;
			forn(i, n) {
				if (i) printf(" ");
				printf("%d", ans[i]);
			}
			cout << endl;
			exit(0);
		}
	cout << -1 << endl;

	return 0;
}


#pragma comment(linker, "/STACK:600000000")
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>

#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <queue>
#include <stack>
#include <list>

#include <ctime>
#include <cassert>

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector <int> vi;
#define sz(s) int((s).size())

typedef long double ldb;
typedef long long int64;
typedef pair <int, int> pii;
typedef pair <double, double> pdd;

#define y0 wwwwwww
#define y1 qqqqqqq
#define next NEXT
#define prev PREV
#define forn(i, n) for (int i = 0; i < (int) n; i++)
#define ford(i, n) for (int i = (int) n - 1; i >= 0; i--)
#define seta(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define last(a) a[a.size() - 1]
#define mp make_pair
#define fs first
#define sc second

template <class T> T sqr(T x) { return x * x; }

double const pi = 3.1415926535897932384626433832795;
int const inf = (int) 1e9;
int64 const inf64 = (int64) 4e18;
const string name = "e";

const int NMAX = 200010;

int n, a[NMAX], d[NMAX][6], ans[NMAX], prev[NMAX][6];
vector<pii> q;

vector<pii> get_opt(int idx1, int col1, int sh1, int idx2, int col2, int sh2, bool& answer) {
	vector<pii> res;
	answer = 0;
	//if (col1 > col2 || (col1 == col2 && sh1 >= sh2)) return res;
	if (col1 == col2) {
		if (sh2 - sh1 == idx2 - idx1) {
			forn(i, sh2 - sh1 - 1)
				res.pb(mp(idx1 + i + 1, col1));
			answer = 1;
		}
		return res;
	}

	vector<pii> RES;
	forn(i, sh2 - 1)
		RES.pb(mp(idx2 - i - 1, col2));
	idx2 -= sh2, col2--;
	for (int i = max(0, 2 - sh1); i < 6 - sh1; ++i) {
		res = RES;
		forn(j, i)
			res.pb(mp(idx1 + j + 1, col1));
		int newidx1 = idx1 + i + 1;
		int newcol1 = col1 + 1;

		if (col2 == col1 - 1) {
			if (idx2 == newidx1 - 1) {
				answer = 1;
				return res;
			}
			continue;
		}
		int delta_idx = idx2 - newidx1 + 1;
		int delta_col = col2 - newcol1 + 1;
		if (2 * delta_col <= delta_idx && delta_idx <= 5 * delta_col) {
			int sz, num;
			if (delta_col == 0) sz = 0, num = 0;
			else sz = delta_idx / delta_col, num = delta_col - delta_idx % delta_col;
			forn(j, num) {
				forn(f, sz)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			forn(j, delta_col - num) {
				forn(f, sz + 1)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			answer = 1;
			return res;
		}
	}
	res.clear();
	return res;
}

int may(int idx1, int col1, int sh1, int idx2, int col2, int sh2) {
	bool answer = 0;
	vector<pii> ept = get_opt(idx1, col1, sh1, idx2, col2, sh2, answer);
	return answer;
}

void rec(int x, int y) {
	ans[q[x].fs] = q[x].sc;
	//if (q[x].sc == 1925 && x > 0 && q[x - 1].sc == 1925 && y == prev[x][y]) exit(1);
	if (x == 0) return;
	rec(x - 1, prev[x][y]);
	bool unused = 0;
	vector<pii> ept = get_opt(q[x - 1].fs, q[x - 1].sc, prev[x][y], q[x].fs, q[x].sc, y, unused);

	forn(i, ept.size())
		ans[ept[i].fs] = ept[i].sc;
}

int main() {
//	freopen((name + ".in").data(), "r", stdin);
//	freopen((name + ".out").data(), "w", stdout);

	cin >> n;
	q.pb(mp(0, 1));
	forn(i, n) {
		scanf("%d", &a[i]);
		if (i == 0 && a[i] != 0) {
			if (a[i] != 1) {
				cout << -1 << endl;
				return 0;
			}
		}
		else if (a[i] != 0) q.pb(mp(i, a[i]));
	}
	seta(d, 0);
	d[0][1] = 1;
	forn(i, q.size() - 1)
		forn(j, 6)
			if (j && d[i][j])
				forn(f, 6) {
					if (f && may(q[i].fs, q[i].sc, j, q[i + 1].fs, q[i + 1].sc, f)) {
						d[i + 1][f] = 1;
						prev[i + 1][f] = j;
					}
				}

	ford(j, 6)
		if (d[q.size() - 1][j] && (j >= 2 || q[q.size() - 1].fs != n - 1) && (j <= 4 || q[q.size() - 1].fs != n - 2)) {
			rec(q.size() - 1, j);
			int now = q[q.size() - 1].fs + 1;
			if (j == 1)
				ans[now++] = q[q.size() - 1].sc;
			while (now < n) {
				if (now == n - 1) {
					ans[now] = ans[now - 1];
					now++;
				}
				else {
					ans[now] = ans[now - 1] + 1;
					ans[now + 1] = ans[now - 1] + 1;
					now += 2;
				}
			}
			cout << ans[n - 1] << endl;
			forn(i, n) {
				if (i) printf(" ");
				printf("%d", ans[i]);
			}
			cout << endl;
			exit(0);
		}
	cout << -1 << endl;

	return 0;
}


#pragma comment(linker, "/STACK:600000000")
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>

#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <queue>
#include <stack>
#include <list>

#include <ctime>
#include <cassert>

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector <int> vi;
#define sz(s) int((s).size())

typedef long double ldb;
typedef long long int64;
typedef pair <int, int> pii;
typedef pair <double, double> pdd;

#define y0 wwwwwww
#define y1 qqqqqqq
#define next NEXT
#define prev PREV
#define forn(i, n) for (int i = 0; i < (int) n; i++)
#define ford(i, n) for (int i = (int) n - 1; i >= 0; i--)
#define seta(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define last(a) a[a.size() - 1]
#define mp make_pair
#define fs first
#define sc second

template <class T> T sqr(T x) { return x * x; }

double const pi = 3.1415926535897932384626433832795;
int const inf = (int) 1e9;
int64 const inf64 = (int64) 4e18;
const string name = "e";

const int NMAX = 200010;

int n, a[NMAX], d[NMAX][6], ans[NMAX], prev[NMAX][6];
vector<pii> q;

vector<pii> get_opt(int idx1, int col1, int sh1, int idx2, int col2, int sh2, bool& answer) {
	vector<pii> res;
	answer = 0;
	if (col1 > col2 || (col1 == col2 && sh1 >= sh2)) return res;
	if (col1 == col2) {
		if (sh2 - sh1 == idx2 - idx1) {
			forn(i, sh2 - sh1 - 1)
				res.pb(mp(idx1 + i + 1, col1));
			answer = 1;
		}
		return res;
	}

	vector<pii> RES;
	forn(i, sh2 - 1)
		RES.pb(mp(idx2 - i - 1, col2));
	idx2 -= sh2, col2--;
	for (int i = max(0, 2 - sh1); i < 6 - sh1; ++i) {
		res = RES;
		forn(j, i)
			res.pb(mp(idx1 + j + 1, col1));
		int newidx1 = idx1 + i + 1;
		int newcol1 = col1 + 1;

		if (col2 == col1 - 1) {
			if (idx2 == newidx1 - 1) {
				answer = 1;
				return res;
			}
			continue;
		}
		int delta_idx = idx2 - newidx1 + 1;
		int delta_col = col2 - newcol1 + 1;
		if (2 * delta_col <= delta_idx && delta_idx <= 5 * delta_col) {
			int sz, num;
			if (delta_col == 0) sz = 0, num = 0;
			else sz = delta_idx / delta_col, num = delta_col - delta_idx % delta_col;
			forn(j, num) {
				forn(f, sz)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			forn(j, delta_col - num) {
				forn(f, sz + 1)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			answer = 1;
			return res;
		}
	}
	res.clear();
	return res;
}

int may(int idx1, int col1, int sh1, int idx2, int col2, int sh2) {
	bool answer = 0;
	vector<pii> ept = get_opt(idx1, col1, sh1, idx2, col2, sh2, answer);
	return answer;
}

void rec(int x, int y) {
	ans[q[x].fs] = q[x].sc;
	if (q[x].sc == 1925 && x > 0 && q[x - 1].sc == 1925 && y == prev[x][y]) exit(1);
	if (x == 0) return;
	rec(x - 1, prev[x][y]);
	bool unused = 0;
	vector<pii> ept = get_opt(q[x - 1].fs, q[x - 1].sc, prev[x][y], q[x].fs, q[x].sc, y, unused);

	forn(i, ept.size())
		ans[ept[i].fs] = ept[i].sc;
}

int main() {
//	freopen((name + ".in").data(), "r", stdin);
//	freopen((name + ".out").data(), "w", stdout);

	cin >> n;
	q.pb(mp(0, 1));
	forn(i, n) {
		scanf("%d", &a[i]);
		if (i == 0 && a[i] != 0) {
			if (a[i] != 1) {
				cout << -1 << endl;
				return 0;
			}
		}
		else if (a[i] != 0) q.pb(mp(i, a[i]));
	}
	seta(d, 0);
	d[0][1] = 1;
	forn(i, q.size() - 1)
		forn(j, 6)
			if (j && d[i][j])
				forn(f, 6) {
					if (f && may(q[i].fs, q[i].sc, j, q[i + 1].fs, q[i + 1].sc, f))
						d[i + 1][f] = 1;
						prev[i + 1][f] = j;
				}

	ford(j, 6)
		if (d[q.size() - 1][j] && (j >= 2 || q[q.size() - 1].fs != n - 1) && (j <= 4 || q[q.size() - 1].fs != n - 2)) {
			rec(q.size() - 1, j);
			int now = q[q.size() - 1].fs + 1;
			if (j == 1)
				ans[now++] = q[q.size() - 1].sc;
			while (now < n) {
				if (now == n - 1) {
					ans[now] = ans[now - 1];
					now++;
				}
				else {
					ans[now] = ans[now - 1] + 1;
					ans[now + 1] = ans[now - 1] + 1;
					now += 2;
				}
			}
			cout << ans[n - 1] << endl;
			forn(i, n) {
				if (i) printf(" ");
				printf("%d", ans[i]);
			}
			cout << endl;
			exit(0);
		}
	cout << -1 << endl;

	return 0;
}


#pragma comment(linker, "/STACK:600000000")
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>

#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <queue>
#include <stack>
#include <list>

#include <ctime>
#include <cassert>

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector <int> vi;
#define sz(s) int((s).size())

typedef long double ldb;
typedef long long int64;
typedef pair <int, int> pii;
typedef pair <double, double> pdd;

#define y0 wwwwwww
#define y1 qqqqqqq
#define next NEXT
#define prev PREV
#define forn(i, n) for (int i = 0; i < (int) n; i++)
#define ford(i, n) for (int i = (int) n - 1; i >= 0; i--)
#define seta(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define last(a) a[a.size() - 1]
#define mp make_pair
#define fs first
#define sc second

template <class T> T sqr(T x) { return x * x; }

double const pi = 3.1415926535897932384626433832795;
int const inf = (int) 1e9;
int64 const inf64 = (int64) 4e18;
const string name = "e";

const int NMAX = 200010;

int n, a[NMAX], d[NMAX][6], ans[NMAX], prev[NMAX][6];
vector<pii> q;

vector<pii> get_opt(int idx1, int col1, int sh1, int idx2, int col2, int sh2, bool& answer) {
	vector<pii> res;
	answer = 0;
	if (col1 == col2) {
		if (sh2 - sh1 == idx2 - idx1) {
			forn(i, sh2 - sh1 - 1)
				res.pb(mp(idx1 + i + 1, col1));
			answer = 1;
		}
		return res;
	}

	vector<pii> RES;
	forn(i, sh2 - 1)
		RES.pb(mp(idx2 - i - 1, col2));
	idx2 -= sh2, col2--;
	for (int i = max(0, 2 - sh1); i < 6 - sh1; ++i) {
		res = RES;
		forn(j, i)
			res.pb(mp(idx1 + j + 1, col1));
		int newidx1 = idx1 + i + 1;
		int newcol1 = col1 + 1;

		if (col2 == col1 - 1) {
			if (idx2 == newidx1 - 1) {
				answer = 1;
				return res;
			}
			continue;
		}
		int delta_idx = idx2 - newidx1 + 1;
		int delta_col = col2 - newcol1 + 1;
		if (2 * delta_col <= delta_idx && delta_idx <= 5 * delta_col) {
			int sz, num;
			if (delta_col == 0) sz = 0, num = 0;
			else sz = delta_idx / delta_col, num = delta_col - delta_idx % delta_col;
			forn(j, num) {
				forn(f, sz)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			forn(j, delta_col - num) {
				forn(f, sz + 1)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			answer = 1;
			return res;
		}
	}
	res.clear();
	return res;
}

int may(int idx1, int col1, int sh1, int idx2, int col2, int sh2) {
	bool answer = 0;
	vector<pii> ept = get_opt(idx1, col1, sh1, idx2, col2, sh2, answer);
	return answer;
}

void rec(int x, int y) {
	ans[q[x].fs] = q[x].sc;
	if (q[x].sc == 1925 && x > 0 && q[x - 1].sc == 1925 && x > 1 && q[x - 2].sc == 1925) exit(1);
	if (x == 0) return;
	rec(x - 1, prev[x][y]);
	bool unused = 0;
	vector<pii> ept = get_opt(q[x - 1].fs, q[x - 1].sc, prev[x][y], q[x].fs, q[x].sc, y, unused);

	forn(i, ept.size())
		ans[ept[i].fs] = ept[i].sc;
}

int main() {
//	freopen((name + ".in").data(), "r", stdin);
//	freopen((name + ".out").data(), "w", stdout);

	cin >> n;
	q.pb(mp(0, 1));
	forn(i, n) {
		scanf("%d", &a[i]);
		if (i == 0 && a[i] != 0) {
			if (a[i] != 1) {
				cout << -1 << endl;
				return 0;
			}
		}
		else if (a[i] != 0) q.pb(mp(i, a[i]));
	}
	seta(d, 0);
	d[0][1] = 1;
	forn(i, q.size() - 1)
		forn(j, 6)
			if (j && d[i][j])
				forn(f, 6) {
					if (f && may(q[i].fs, q[i].sc, j, q[i + 1].fs, q[i + 1].sc, f))
						d[i + 1][f] = 1;
						prev[i + 1][f] = j;
				}

	ford(j, 6)
		if (d[q.size() - 1][j] && (j >= 2 || q[q.size() - 1].fs != n - 1) && (j <= 4 || q[q.size() - 1].fs != n - 2)) {
			rec(q.size() - 1, j);
			int now = q[q.size() - 1].fs + 1;
			if (j == 1)
				ans[now++] = q[q.size() - 1].sc;
			while (now < n) {
				if (now == n - 1) {
					ans[now] = ans[now - 1];
					now++;
				}
				else {
					ans[now] = ans[now - 1] + 1;
					ans[now + 1] = ans[now - 1] + 1;
					now += 2;
				}
			}
			cout << ans[n - 1] << endl;
			forn(i, n) {
				if (i) printf(" ");
				printf("%d", ans[i]);
			}
			cout << endl;
			exit(0);
		}
	cout << -1 << endl;

	return 0;
}


#pragma comment(linker, "/STACK:600000000")
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>

#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <queue>
#include <stack>
#include <list>

#include <ctime>
#include <cassert>

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector <int> vi;
#define sz(s) int((s).size())

typedef long double ldb;
typedef long long int64;
typedef pair <int, int> pii;
typedef pair <double, double> pdd;

#define y0 wwwwwww
#define y1 qqqqqqq
#define next NEXT
#define prev PREV
#define forn(i, n) for (int i = 0; i < (int) n; i++)
#define ford(i, n) for (int i = (int) n - 1; i >= 0; i--)
#define seta(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define last(a) a[a.size() - 1]
#define mp make_pair
#define fs first
#define sc second

template <class T> T sqr(T x) { return x * x; }

double const pi = 3.1415926535897932384626433832795;
int const inf = (int) 1e9;
int64 const inf64 = (int64) 4e18;
const string name = "e";

const int NMAX = 200010;

int n, a[NMAX], d[NMAX][6], ans[NMAX], prev[NMAX][6];
vector<pii> q;

vector<pii> get_opt(int idx1, int col1, int sh1, int idx2, int col2, int sh2, bool& answer) {
	vector<pii> res;
	answer = 0;
	if (col1 > col2 || (col1 == col2 && sh1 >= sh2)) return res;
	if (col1 == col2) {
		if (sh2 - sh1 == idx2 - idx1) {
			forn(i, sh2 - sh1 - 1)
				res.pb(mp(idx1 + i + 1, col1));
			answer = 1;
		}
		return res;
	}

	vector<pii> RES;
	forn(i, sh2 - 1)
		RES.pb(mp(idx2 - i - 1, col2));
	idx2 -= sh2, col2--;
	for (int i = max(0, 2 - sh1); i < 6 - sh1; ++i) {
		res = RES;
		forn(j, i)
			res.pb(mp(idx1 + j + 1, col1));
		int newidx1 = idx1 + i + 1;
		int newcol1 = col1 + 1;

		if (col2 == col1 - 1) {
			if (idx2 == newidx1 - 1) {
				answer = 1;
				return res;
			}
			continue;
		}
		int delta_idx = idx2 - newidx1 + 1;
		int delta_col = col2 - newcol1 + 1;
		if (2 * delta_col <= delta_idx && delta_idx <= 5 * delta_col) {
			int sz, num;
			if (delta_col == 0) sz = 0, num = 0;
			else sz = delta_idx / delta_col, num = delta_col - delta_idx % delta_col;
			forn(j, num) {
				forn(f, sz)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			forn(j, delta_col - num) {
				forn(f, sz + 1)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			answer = 1;
			return res;
		}
	}
	res.clear();
	return res;
}

int may(int idx1, int col1, int sh1, int idx2, int col2, int sh2) {
	bool answer = 0;
	vector<pii> ept = get_opt(idx1, col1, sh1, idx2, col2, sh2, answer);
	return answer;
}

void rec(int x, int y) {
	ans[q[x].fs] = q[x].sc;
	//if (q[x].sc == 1925 && x > 0 && q[x - 1].sc == 1925 && y == prev[x][y]) exit(1);
	if (x == 0) return;
	rec(x - 1, prev[x][y]);
	bool unused = 0;
	vector<pii> ept = get_opt(q[x - 1].fs, q[x - 1].sc, prev[x][y], q[x].fs, q[x].sc, y, unused);

	forn(i, ept.size())
		ans[ept[i].fs] = ept[i].sc;
}

int main() {
//	freopen((name + ".in").data(), "r", stdin);
//	freopen((name + ".out").data(), "w", stdout);

	cin >> n;
	q.pb(mp(0, 1));
	forn(i, n) {
		scanf("%d", &a[i]);
		if (i == 0 && a[i] != 0) {
			if (a[i] != 1) {
				cout << -1 << endl;
				return 0;
			}
		}
		else if (a[i] != 0) q.pb(mp(i, a[i]));
	}
	seta(d, 0);
	d[0][1] = 1;
	forn(i, q.size() - 1)
		forn(j, 6)
			if (j && d[i][j])
				forn(f, 6) {
					if (f && may(q[i].fs, q[i].sc, j, q[i + 1].fs, q[i + 1].sc, f)) {
						d[i + 1][f] = 1;
						prev[i + 1][f] = j;
					}
				}

	ford(j, 6)
		if (d[q.size() - 1][j] && (j >= 2 || q[q.size() - 1].fs != n - 1) && (j <= 4 || q[q.size() - 1].fs != n - 2)) {
			rec(q.size() - 1, j);
			int now = q[q.size() - 1].fs + 1;
			if (j == 1)
				ans[now++] = q[q.size() - 1].sc;
			while (now < n) {
				if (now == n - 1) {
					ans[now] = ans[now - 1];
					now++;
				}
				else {
					ans[now] = ans[now - 1] + 1;
					ans[now + 1] = ans[now - 1] + 1;
					now += 2;
				}
			}
			cout << ans[n - 1] << endl;
			forn(i, n) {
				if (i) printf(" ");
				printf("%d", ans[i]);
			}
			cout << endl;
			exit(0);
		}
	cout << -1 << endl;

	return 0;
}


#pragma comment(linker, "/STACK:600000000")
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>

#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <queue>
#include <stack>
#include <list>

#include <ctime>
#include <cassert>

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef vector <int> vi;
#define sz(s) int((s).size())

typedef long double ldb;
typedef long long int64;
typedef pair <int, int> pii;
typedef pair <double, double> pdd;

#define y0 wwwwwww
#define y1 qqqqqqq
#define next NEXT
#define prev PREV
#define forn(i, n) for (int i = 0; i < (int) n; i++)
#define ford(i, n) for (int i = (int) n - 1; i >= 0; i--)
#define seta(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define last(a) a[a.size() - 1]
#define mp make_pair
#define fs first
#define sc second

template <class T> T sqr(T x) { return x * x; }

double const pi = 3.1415926535897932384626433832795;
int const inf = (int) 1e9;
int64 const inf64 = (int64) 4e18;
const string name = "e";

const int NMAX = 200010;

int n, a[NMAX], d[NMAX][6], ans[NMAX], prev[NMAX][6];
vector<pii> q;

vector<pii> get_opt(int idx1, int col1, int sh1, int idx2, int col2, int sh2, bool& answer) {
	vector<pii> res;
	answer = 0;
	//if (col1 > col2 || (col1 == col2 && sh1 >= sh2)) return res;
	if (col1 == col2) {
		if (sh2 - sh1 == idx2 - idx1) {
			forn(i, sh2 - sh1 - 1)
				res.pb(mp(idx1 + i + 1, col1));
			answer = 1;
		}
		return res;
	}

	vector<pii> RES;
	forn(i, sh2 - 1)
		RES.pb(mp(idx2 - i - 1, col2));
	idx2 -= sh2, col2--;
	for (int i = max(0, 2 - sh1); i < 6 - sh1; ++i) {
		res = RES;
		forn(j, i)
			res.pb(mp(idx1 + j + 1, col1));
		int newidx1 = idx1 + i + 1;
		int newcol1 = col1 + 1;

		if (col2 == col1 - 1) {
			if (idx2 == newidx1 - 1) {
				answer = 1;
				return res;
			}
			continue;
		}
		int delta_idx = idx2 - newidx1 + 1;
		int delta_col = col2 - newcol1 + 1;
		if (2 * delta_col <= delta_idx && delta_idx <= 5 * delta_col) {
			int sz, num;
			if (delta_col == 0) sz = 0, num = 0;
			else sz = delta_idx / delta_col, num = delta_col - delta_idx % delta_col;
			forn(j, num) {
				forn(f, sz)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			forn(j, delta_col - num) {
				forn(f, sz + 1)
					res.pb(mp(newidx1++, newcol1));
				newcol1++;
			}
			answer = 1;
			return res;
		}
	}
	res.clear();
	return res;
}

int may(int idx1, int col1, int sh1, int idx2, int col2, int sh2) {
	bool answer = 0;
	vector<pii> ept = get_opt(idx1, col1, sh1, idx2, col2, sh2, answer);
	return answer;
}

void rec(int x, int y) {
	ans[q[x].fs] = q[x].sc;
	//if (q[x].sc == 1925 && x > 0 && q[x - 1].sc == 1925 && y == prev[x][y]) exit(1);
	if (x == 0) return;
	rec(x - 1, prev[x][y]);
	bool unused = 0;
	vector<pii> ept = get_opt(q[x - 1].fs, q[x - 1].sc, prev[x][y], q[x].fs, q[x].sc, y, unused);

	forn(i, ept.size())
		ans[ept[i].fs] = ept[i].sc;
}

int main() {
//	freopen((name + ".in").data(), "r", stdin);
//	freopen((name + ".out").data(), "w", stdout);

	cin >> n;
	q.pb(mp(0, 1));
	forn(i, n) {
		scanf("%d", &a[i]);
		if (i == 0 && a[i] != 0) {
			if (a[i] != 1) {
				cout << -1 << endl;
				return 0;
			}
		}
		else if (a[i] != 0) q.pb(mp(i, a[i]));
	}
	seta(d, 0);
	d[0][1] = 1;
	forn(i, q.size() - 1)
		forn(j, 6)
			if (j && d[i][j])
				forn(f, 6) {
					if (f && may(q[i].fs, q[i].sc, j, q[i + 1].fs, q[i + 1].sc, f)) {
						d[i + 1][f] = 1;
						prev[i + 1][f] = j;
					}
				}

	ford(j, 6)
		if (d[q.size() - 1][j] && /*(j >= 2 || q[q.size() - 1].fs != n - 1) &&*/ (j <= 4 || q[q.size() - 1].fs != n - 2)) {
			rec(q.size() - 1, j);
			int now = q[q.size() - 1].fs + 1;
			if (j == 1)
				ans[now++] = q[q.size() - 1].sc;
			while (now < n) {
				if (now == n - 1) {
					ans[now] = ans[now - 1];
					now++;
				}
				else {
					ans[now] = ans[now - 1] + 1;
					ans[now + 1] = ans[now - 1] + 1;
					now += 2;
				}
			}
			cout << ans[n - 1] << endl;
			forn(i, n) {
				if (i) printf(" ");
				printf("%d", ans[i]);
			}
			cout << endl;
			exit(0);
		}
	cout << -1 << endl;

	return 0;
}