//#undef DEBUG
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll llinf = (1ll<<61)-1;
#define sz(a) int(a.size())
#define all(x) begin(x), end(x)
#ifdef DEBUG
const int DEBUG_END = 26;
#define DOS cout
#include <debug.h>
#else
#define bug(args...) void()
#define cbug(a, args...)
#endif
#define ASSERT(a, o, b, args...) if (!((a)o(b))) bug(a, b, ##args), assert((a)o(b));
#define fi first
#define se second
const int inf = 1000000007, N=600005;
int TC = 1, CN, n, k, root, p[N], in[N], nxt[N], prv[N];
list<int> g[N];


// Following command is for Linux. You can change this command for a different OS or for a different image viewer.
const char COMMAND[] = "(ulimit -Sv unlimited; dot -Tpng graph.dot -o graph.png && nohup chromium-browser graph.png)";


/*! Converts unweighted graph to dot format
 *\param directed is whether graph is directed or not */
void show_graph_unweighted(const bool directed = 0) { // requires installing graphviz
    ofstream os{"graph.dot"};
    os << (directed ? "digraph" : "graph");
    os << " g {" << endl;
    for(int u = 0; u <= 26; ++u) {
        for (const auto &v : g[u]) {
            if (directed || u <= v) {
                os << "\t" << u << (directed ? " -> " : " -- ") << v << endl;
            }
        }
    }
    os << "}" << endl;
    os.close();
    system(COMMAND);
}
#define edge(u, v) g[u].push_back(v), ++in[v]

signed main() { cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit); cout.precision(11), cout.setf(ios::fixed);
/*
Plan is to collapse chains of q: for 7-4-2, add edge p[4]->7, p[2]->7, 7->4 and 4->2.
*/
    auto kase = [&]()->void {
        cin >> n >> k;
        for (int i = 1; i <= n; i++) {
            cin >> p[i];
            if (p[i]) edge(p[i], i);
            else root = i;
        }

        for (int i = 0, x, y; i < k; i++) {
            cin >> x >> y;
            nxt[x] = y, prv[y] = x;
        }

        bitset<N> vstd;
        for (int i = 1; i <= n; i++) {
            if (!prv[i] and nxt[i]) {
                vector<int> v;
                int x = i;
                while (vstd[x] = 1, v.push_back(x), nxt[x]) {
                    if (p[nxt[x]] != i and !vstd[p[nxt[x]]]) edge(p[nxt[x]], i);
                    x = nxt[x];
                }
                for (auto &j : v) {
                    vstd[j] = 0;
                }
            }
        }
        for (int i = 1; i <= n; i++) {
            if (nxt[i]) edge(i, nxt[i]);
        }
        // show_graph_unweighted(1);

        vector<int> ans;
        deque<int> dq;
        dq.push_front(root);
        while (!dq.empty()) {
            int u = dq.front();
            dq.pop_front();

            ans.push_back(u);
            for (auto &i : g[u]) {
                if (--in[i] == 0) {
                    dq.push_front(i);
                }
            }
        }

        if (sz(ans) != n) cout << "0\n";
        else {
            for (auto &i : ans) {
                cout << i << ' ';
            }
            cout << '\n';
        }
    };
    while (CN++!=TC) kase();
}