You are given a tree (a graph with n vertices and n - 1 edges in which it's possible to reach any vertex from any other vertex using only its edges).

A vertex can be destroyed if this vertex has even degree. If you destroy a vertex, all edges connected to it are also deleted.

Destroy all vertices in the given tree or determine that it is impossible.

Input

The first line contains integer n (1 ≤ n ≤ 2·105) — number of vertices in a tree.

The second line contains n integers p1, p2, ..., pn (0 ≤ pi ≤ n). If pi ≠ 0 there is an edge between vertices i and pi. It is guaranteed that the given graph is a tree.

Output

If it's possible to destroy all vertices, print "YES" (without quotes), otherwise print "NO" (without quotes).

If it's possible to destroy all vertices, in the next n lines print the indices of the vertices in order you destroy them. If there are multiple correct answers, print any.

Examples

Input

5
0 1 2 1 2


Output

YES
1
2
3
5
4


Input

4
0 1 2 3


Output

NO

Note

In the first example at first you have to remove the vertex with index 1 (after that, the edges (1, 2) and (1, 4) are removed), then the vertex with index 2 (and edges (2, 3) and (2, 5) are removed). After that there are no edges in the tree, so you can remove remaining vertices in any order.

<image>
#include <bits/stdc++.h>
#pragma GCC diagnostic ignored "-Wunused-const-variable"
#pragma GCC diagnostic ignored "-Wunused-variable"
using namespace std;
clock_t __start;
mt19937_64 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
const long double eps = 1e-8l;
const long long INF = 1e9 + 10;
const long long MOD = 1e9 + 7;
const long double Pi = acosl(-1.0l);
int __loc = 1;
int __io_opt = 1;
int __fileIO = 0;
int __MulTest = 0;
const char* __fin = "in";
const char* __fout = "out";
const char* __err = "err";
void prec();
void load();
void solve();
void __time(string s) {
  if (!__loc) return;
  cerr << s + ". Time: " << ((long double)clock() - __start) / CLOCKS_PER_SEC
       << '\n';
}
struct app {
  void __io_set() {
    __loc = 0;
    if (__io_opt) {
      ios_base::sync_with_stdio(0);
      cin.tie(0);
      cout.tie(0);
    }
    cout.precision(9);
    cout.setf(ios::fixed | ios::showpoint);
    if (__loc || __fileIO) {
      freopen(__fin, "r", stdin);
      freopen(__fout, "w", stdout);
    }
    if (__loc) freopen(__err, "w", stderr);
  }
  app() {
    __io_set();
    __start = clock();
    prec();
    __time("Precalc finised");
    int ts = 1;
    if (__MulTest) cin >> ts;
    while (ts--) {
      load();
      solve();
    }
    __time("Program finished");
  }
};
int main() { app x; }
void prec() {}
set<int> gr[200100];
bitset<200100> was;
vector<int> ans1, ans2;
vector<int> par;
vector<pair<int, int> > rtd;
int n, rt;
void dfs(int v, int d = 0) {
  was[v] = 1;
  rtd.push_back(make_pair(d, v));
  for (auto i : gr[v])
    if (!was[i]) dfs(i, d + 1);
}
void load() {
  cin >> n;
  par.resize(n + 1);
  for (int i = 0; i < n; i++) {
    int t;
    cin >> t;
    par[i + 1] = t;
    if (t) {
      gr[t].insert(i + 1);
      gr[i + 1].insert(t);
    } else
      rt = i + 1;
  }
}
void solve() {
  dfs(rt);
  sort((rtd).begin(), (rtd).end());
  reverse((rtd).begin(), (rtd).end());
  if (0) cerr << "dfsed\n";
  for (int i = 1; i <= n; i++)
    if (0) cerr << i << ' ' << gr[i].size() << '\n';
  for (int i = 0; i < n; i++) {
    int v = rtd[i].second;
    if (0) log(v);
    if (gr[v].size() & 1) {
      if (0) cerr << "pushed ass\n";
      ans2.push_back(v);
    } else {
      for (auto i : gr[v]) {
        gr[i].erase(v);
      }
      gr[par[v]].erase(v);
      ans1.push_back(v);
    }
  }
  reverse((ans2).begin(), (ans2).end());
  for (auto i : ans2) {
    if (gr[i].size() & 1) {
      cout << "NO";
      return;
    }
    for (auto j : gr[i]) {
      if (gr[j].count(i)) gr[j].erase(i);
    }
    if (gr[par[i]].count(i)) gr[par[i]].erase(i);
  }
  cout << "YES\n";
  for (auto i : ans1) cout << i << '\n';
  for (auto i : ans2) cout << i << '\n';
}
