#include <bits/stdc++.h>
template <typename Y>
inline bool updmin(Y &a, Y b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename Y>
inline bool updmax(Y &a, Y b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename Y>
inline Y abs(Y a) {
  if (a < 0) a = -a;
  return a;
}
template <typename Y>
inline Y sqr(Y a) {
  return a * a;
}
int read() {
  int w = 1, q = 0, ch = ' ';
  for (; ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-') w = -1;
  for (; ch >= '0' && ch <= '9'; ch = getchar()) q = q * 10 + ch - 48;
  return q * w;
}
inline void FileIO() {
  freopen(
      ""
      ".in",
      "r", stdin);
  freopen(
      ""
      ".out",
      "w", stdout);
}
std::set<int> st;
const int N = 1000100;
int m, n, val[N];
int pre[N], nxt[N], las[N], vis[N];
inline int New() {
  if (st.empty()) {
    throw "No More Numbers";
  }
  int x = *st.begin();
  st.erase(st.begin());
  return x;
}
inline void solve(int l, int r) {
  for (int p = l; nxt[p] != r;) {
    if (~val[p] && val[p] && val[nxt[p]] && !val[nxt[nxt[p]]]) {
      val[nxt[nxt[p]]] = val[p];
      vis[nxt[p]] = vis[nxt[nxt[p]]] = 1;
      nxt[p] = nxt[nxt[nxt[p]]];
      pre[nxt[p]] = p;
      if (p ^ l) p = pre[p];
    } else if (!val[p] && val[nxt[p]] && val[nxt[nxt[p]]] &&
               ~val[nxt[nxt[p]]]) {
      val[p] = val[nxt[nxt[p]]];
      vis[p] = vis[nxt[p]] = 1;
      p = pre[p];
      nxt[p] = nxt[nxt[nxt[p]]];
      pre[nxt[p]] = p;
      if (p ^ l) p = pre[p];
    } else {
      p = nxt[p];
    }
  }
  int bound = val[l];
  int a = nxt[l], b = pre[r];
  while (1) {
    if (a == b) {
      if (val[a] == 0) {
        val[a] = New();
      }
      break;
    }
    if (!val[a] && !val[b]) {
      val[a] = New();
    }
    if (!val[a] || !val[b]) {
      int x = val[a] ^ val[b];
      val[a] = val[b] = x;
      a = nxt[a];
      b = pre[b];
      bound = x;
      continue;
    }
    if (!val[nxt[a]]) {
      val[nxt[a]] = bound;
      a = nxt[nxt[a]];
      continue;
    }
    if (!val[pre[b]]) {
      val[pre[b]] = bound;
      b = pre[pre[b]];
      continue;
    }
    if (!~bound) {
      bound = val[nxt[a]];
      for (int i = 1; i <= n; i++) {
        if (!~val[i]) {
          val[i] = bound;
        }
      }
      a = nxt[nxt[a]];
      continue;
    }
    throw "Can't Place Element";
  }
}
int main() {
  m = read();
  n = m * 2 - 1;
  for (int i = 1; i <= m; i++) {
    st.insert(i);
  }
  for (int i = 1; i <= n; i++) {
    val[i] = read();
    if (st.find(val[i]) != st.end()) {
      st.erase(val[i]);
    }
    pre[i] = i - 1;
    nxt[i] = i + 1;
  }
  nxt[0] = 1;
  pre[n + 1] = n;
  try {
    if (val[1] && val[n] && val[1] != val[n]) {
      throw "Head Tail Not Equal";
    }
    if ((val[1] || val[n]) && (val[1] ^ val[n])) {
      int x = val[1] ^ val[n];
      val[1] = val[n] = x;
    }
    if (!val[1]) {
      val[1] = val[n] = -1;
    }
    val[0] = val[n + 1] = -1;
    for (int i = 1; i <= n; i++) {
      if (!val[i] || !~val[i]) continue;
      if (las[val[i]]) {
        int j = las[val[i]];
        if (vis[j]) {
          throw "Intersected Segment";
        }
        if ((j + i) & 1) {
          throw "Odd Segment";
        }
        solve(j, i);
        for (int k = nxt[j]; k != i + 1; k = nxt[k]) {
          vis[k] = 1;
        }
        nxt[j] = i + 1;
        pre[i + 1] = j;
      } else {
        las[val[i]] = i;
      }
    }
    if (!~val[1]) solve(1, n);
    if (!~val[1]) {
      val[1] = New();
      for (int i = 1; i <= n; i++) {
        if (!~val[i]) {
          val[i] = val[1];
        }
      }
    }
  } catch (const char *s) {
    fprintf(stderr, "No Solution: [%s]\n", s);
    puts("no");
    return 0;
  }
  puts("yes");
  for (int i = 1; i <= n; i++) {
    printf("%d ", val[i]);
  }
  return 0;
}
