#include <bits/stdc++.h>   using namespace std;   template <typename T>   void read(T &t) {     t = 0;     char ch = getchar();     int f = 1;     while (ch <  0  || ch >  9 ) {       if (ch ==  - ) f = -1;       ch = getchar();     }     do {       (t *= 10) += ch -  0 ;       ch = getchar();     } while ( 0  <= ch && ch <=  9 );     t *= f;   }   template <typename T>   void write(T t) {     if (t < 0) {       putchar( - );       write(-t);       return;     }     if (t > 9) write(t / 10);     putchar( 0  + t % 10);   }   template <typename T>   void writeln(T t) {     write(t);     puts(  );   }   const int maxn = 610;   const int maxm = 300010;   int n, a[maxm];   namespace xyr {   const int maxm = 1000000;   int n, tot, head[maxn], id[610][610];   int nxt[maxm], to[maxm], ans;   void Add(int x, int y) {     tot++;     nxt[tot] = head[x];     head[x] = tot;     to[tot] = y;   }   void add(int x, int y, int z) {     if (id[x][y]) return;     id[x][y] = id[y][x] = z;     Add(x, y);     Add(y, x);   }   int match[maxn], pre[maxn], vis[maxn], fa[maxn];   queue<int> q;   int find(int x) {     if (fa[x] == x) return x;     return fa[x] = find(fa[x]);   }   int mk[maxn], cnt;   int lca(int x, int y) {     cnt++;     while (1) {       if (x) {         x = find(x);         if (mk[x] == cnt) return x;         mk[x] = cnt;         x = pre[match[x]];       }       swap(x, y);     }   }   void blossom(int x, int y, int z) {     while (find(x) != z) {       pre[x] = y;       y = match[x];       if (vis[y] == 2) vis[y] = 1, q.push(y);       if (find(x) == x) fa[x] = z;       if (find(y) == y) fa[y] = z;       x = pre[y];     }   }   int dfs(int s) {     for (int i = 1; i <= n; i++) vis[i] = pre[i] = 0, fa[i] = i;     q = queue<int>();     q.push(s);     vis[s] = 1;     while (!q.empty()) {       int u = q.front();       q.pop();       for (int i = head[u], v; i; i = nxt[i]) {         v = to[i];         if (find(u) == find(v) || vis[v] == 2) continue;         if (!vis[v]) {           vis[v] = 2;           pre[v] = u;           if (!match[v]) {             for (int x = v, lst; x; x = lst)               lst = match[pre[x]], match[x] = pre[x], match[pre[x]] = x;             return 1;           }           vis[match[v]] = 1;           q.push(match[v]);         } else {           int z = lca(u, v);           blossom(u, v, z);           blossom(v, u, z);         }       }     }     return 0;   }   void solve() {     for (int i = n; i >= 1; i--)       if (!match[i]) ans += dfs(i);   }   };  // namespace xyr   bool ban[610];   int mx, used[maxm];   vector<pair<int, int>> V, V2;   namespace BF {   vector<int> g[610];   int tim[610];   queue<int> q;   void link(int x, int y) { g[x].push_back(y), g[y].push_back(x); }   void solve() {     for (int i = 1; i <= mx; i++) tim[i] = -1;     for (int i = 1; i <= mx; i++)       if (ban[i]) tim[i] = 0, q.push(i);     while (!q.empty()) {       int x = q.front();       q.pop();       for (int &y : g[x])         if (tim[y] == -1) tim[y] = tim[x] + 1, q.push(y);     }   }   };  // namespace BF   int dir[maxm], bel[maxn];   bool MK[maxm];   namespace Forest {   bool oncyc[610], vis[610];   int fa[610], from[610];   vector<pair<int, int>> g[610];   void add(int x, int y, int z) {     g[x].push_back(make_pair(y, z)), g[y].push_back(make_pair(x, z));   }   int X, Y, Z;   vector<int> V[610];   int D[610], tot, S, dis[610];   void dfs(int x, int p, int w) {     vis[x] = 1;     fa[x] = p;     from[x] = w;     V[S].push_back(x);     dis[x] = dis[p] + 1;     for (auto [y, z] : g[x]) {       if (z == from[x]) continue;       if (vis[y]) {         if (dis[x] > dis[y]) Y = x, X = y, Z = z;       } else         dfs(y, x, z);     }   }   int VIS[610];   void DFS(int x, int f) {     VIS[x] = 1;     for (auto [y, z] : g[x])       if (!oncyc[y] && z != f && !VIS[y]) {         DFS(y, z);         dir[z] = y;       }   }   int TREE[610];   void solve() {     for (int i = 1; i <= mx; i++)       if (!vis[i]) {         X = Y = 0;         S = i;         dfs(i, 0, -1);         if (X) {           tot = 0;           dir[Z] = X;           while (1) {             D[++tot] = Y;             if (Y == X) break;             dir[from[Y]] = Y;             Y = fa[Y];           }           for (int j = 1; j <= tot; j++) oncyc[D[j]] = 1;           for (int j = 1; j <= tot; j++) DFS(D[j], 0);         } else {           TREE[i] = 1;           for (int &x : V[i]) {             bel[x] = i;           }         }       }     tot = 0;   }   int XYR[610];   void insert(int x) { XYR[bel[x]] = x; }   void insert(int x, int y) { insert(x), insert(y); }   void solve_again() {     memset(vis, 0, sizeof(vis));     for (int i = 1; i <= mx; i++)       if (bel[i] == i && TREE[i]) {         if (XYR[i]) {           S = i;           V[i].clear();           dfs(XYR[i], 0, -1);         } else           XYR[i] = i;         for (int &x : V[i])           if (x != XYR[i]) dir[from[x]] = x;       }   }   };  // namespace Forest   int now, R[maxm];   int GETNXT() {     while (used[now]) now++;     used[now] = 1;     return now;   }   int main() {     read(n);     int F1 = 1, F2 = 1;     for (int i = 1; i <= n; i++)       read(a[i]), R[i] = a[i], mx = max(mx, a[i]), used[a[i]] = 1,                   F1 &= (a[i] == 0), F2 &= (a[i] != 0);     if (F1) {       for (int i = 0; i < n; i++) printf( %d  , i / 2 + 1);       puts(  );       return 0;     }     if (F2) {       for (int i = 1; i <= n; i++) printf( %d  , a[i]);       puts(  );       return 0;     }     now = 1;     for (int l = 1, r; l <= n; l = r + 1)       if (!a[l]) {         r = l;         while (r < n && !a[r + 1]) r++;         int x = a[l - 1], y = a[r + 1], len = r - l + 1;         if (l == 1) {           if (len & 1) {             for (int i = 1; i < r; i += 2) a[i] = a[i + 1] = GETNXT();             a[r] = a[r + 1];           } else {             for (int i = 1; i <= r; i += 2) a[i] = a[i + 1] = GETNXT();           }         } else if (r == n) {           if (len & 1) {             for (int i = l + 1; i <= n; i += 2) a[i] = a[i + 1] = GETNXT();             a[l] = a[l - 1];           } else {             for (int i = l; i <= n; i += 2) a[i] = a[i + 1] = GETNXT();           }         } else {           assert(x && y);           if (x == y) {             if (len & 1) {               a[l] = a[l - 1];               for (int i = l + 1; i <= r; i += 2) a[i] = a[i + 1] = GETNXT();             } else {               for (int i = l; i <= r; i += 2) a[i] = a[i + 1] = GETNXT();             }           } else {             V.push_back(make_pair(l, r));           }         }       } else         r = l;     for (int i = 1; i < n; i++)       if (a[i] && a[i + 1] && a[i] == a[i + 1] && a[i] <= mx) ban[a[i]] = 1;     for (pair<int, int> &A : V)       if ((A.second - A.first + 1) % 2 == 1)         BF::link(a[A.first - 1], a[A.second + 1]);     BF::solve();     for (int i = 1; i <= mx; i++) ban[i] = (BF::tim[i] != -1);     for (auto [l, r] : V) {       int x = a[l - 1], y = a[r + 1], len = r - l + 1;       if (ban[y] && (!ban[x] || BF::tim[y] <= BF::tim[x])) {         if (len & 1) {           for (int i = l + 1; i <= r; i += 2) a[i] = a[i + 1] = GETNXT();           a[l] = a[l - 1];         } else {           for (int i = l; i <= r; i += 2) a[i] = a[i + 1] = GETNXT();         }       } else if (ban[x] && (!ban[y] || BF::tim[y] >= BF::tim[x])) {         if (len & 1) {           for (int i = l; i < r; i += 2) a[i] = a[i + 1] = GETNXT();           a[r] = a[r + 1];         } else {           for (int i = l; i <= r; i += 2) a[i] = a[i + 1] = GETNXT();         }       } else         V2.push_back(make_pair(l, r));     }     for (int i = 0; i < V2.size(); i++) {       int l = V2[i].first, r = V2[i].second, x = a[l - 1], y = a[r + 1],           len = r - l + 1;       if (len & 1) Forest::add(x, y, i);     }     Forest::solve();     xyr::n = mx;     for (int i = 0; i < V2.size(); i++) {       int l = V2[i].first, r = V2[i].second, x = a[l - 1], y = a[r + 1],           len = r - l + 1;       if (len & 1 ^ 1) xyr::add(bel[x], bel[y], i + 1);     }     xyr::solve();     for (int i = 1; i <= mx; i++)       if (xyr::match[i] && xyr::match[i] < i) {         int z = xyr::id[i][xyr::match[i]] - 1;         MK[z] = 1;         int x = a[V2[z].first - 1], y = a[V2[z].second + 1];         Forest::insert(x, y);       }     Forest::solve_again();     for (int i = 0; i < V2.size(); i++) {       int l = V2[i].first, r = V2[i].second, x = a[l - 1], y = a[r + 1],           len = r - l + 1;       if (MK[i]) {         a[l] = a[l - 1], a[r] = a[r + 1];         for (int j = l + 1; j < r; j += 2) a[j] = a[j + 1] = GETNXT();       } else if (dir[i]) {         if (dir[i] == x) {           for (int j = l + 1; j <= r; j += 2) a[j] = a[j + 1] = GETNXT();           a[l] = a[l - 1];         } else {           for (int j = l; j < r; j += 2) a[j] = a[j + 1] = GETNXT();           a[r] = a[r + 1];         }       } else if (len & 1) {         for (int j = l; j < r; j += 2) a[j] = a[j + 1] = GETNXT();         a[r] = GETNXT();       } else {         for (int j = l; j <= r; j += 2) a[j] = a[j + 1] = GETNXT();       }     }     for (int i = 1; i <= n; i++) printf( %d  , a[i]);     puts(  );     return 0;   }