#pragma GCC optimize("O3,inline")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
using ll = long long;
#define int ll
using ii = pair<int, int>;
using iii = pair<ii, int>;
constexpr int INF = 1e18 + 5;
constexpr int MAXN = 300000 + 5;
constexpr int MOD = 1e9 + 7;
template <class T>
struct SegTree {
int n; T id; std::vector<T> seg; std::function<T(T,T)> fn;
SegTree(int sz=0,T idv=INF,std::function<T(T,T)> f = [](T a,T b){ return min(a,b); }): n(sz),id(idv),fn(f) {
seg.assign(2*n,id);
}
void set(int p,T v) {
for (seg[p+=n]=v; p>1; p>>=1) seg[p>>1] = fn(seg[p],seg[p^1]);
}
T query(int l,int r) {
T lv=id,rv=id; l+=n; r+=n+1;
while (l<r) {
if (l&1) lv = fn(lv,seg[l++]);
if (r&1) rv = fn(seg[--r],rv);
l>>=1; r>>=1;
}
return fn(lv,rv);
}
};
struct HLD {
int n=0,lg=0,root=0,tim=0;
std::vector<int> par,dep,sz,hv,head,pos;
std::vector<std::vector<int>> up;
SegTree<long long> st;
HLD() = default;
HLD(const std::vector<std::vector<int>>& adj,const std::vector<long long>& a,int baseRoot=0) { build(adj,a,baseRoot); }
void build(const std::vector<std::vector<int>>& adj,const std::vector<long long>& a,int baseRoot=0) {
n=(int)adj.size(); root=baseRoot;
par.assign(n,-1); dep.assign(n,0); sz.assign(n,0);
hv.assign(n,-1); head.assign(n,0); pos.assign(n,0);
std::vector<int> order; order.reserve(n);
std::vector<int> stk(1,baseRoot);
while (!stk.empty()) {
int u=stk.back(); stk.pop_back();
order.push_back(u);
for (int v : adj[u]) if (v!=par[u]) {
par[v]=u; dep[v]=dep[u]+1;
stk.push_back(v);
}
}
for (int i=(int)order.size()-1;i>=0;i--) {
int u=order[i], best=0;
sz[u]=1; hv[u]=-1;
for (int v : adj[u]) if (v!=par[u]) {
sz[u]+=sz[v];
if (sz[v]>best) best=sz[v], hv[u]=v;
}
}
lg=1; while ((1<<lg) <= n) lg++;
up.assign(lg,std::vector<int>(n,-1));
for (int u=0;u<n;u++) up[0][u]=par[u];
for (int j=1;j<lg;j++)
for (int u=0;u<n;u++)
up[j][u]= up[j-1][u]==-1 ? -1 : up[j-1][up[j-1][u]];
tim=0;
std::vector<std::pair<int,int>> st2(1,{baseRoot,baseRoot});
while (!st2.empty()) {
auto [u,h]=st2.back(); st2.pop_back();
for (int x=u; x!=-1; x=hv[x]) {
head[x]=h; pos[x]=tim++;
for (int v : adj[x]) if (v!=par[x] && v!=hv[x]) st2.push_back({v,v});
}
}
st = SegTree<int>(n);
for (int u=0;u<n;u++) st.set(pos[u],a[u]);
}
void setRoot(int r) { root=r; }
void pointSet(int u, int v) {
st.set(pos[u], v);
}
long long pathMin(int u,int v) {
long long res=INF;
while (head[u]!=head[v]) {
if (dep[head[u]]<dep[head[v]]) std::swap(u,v);
res = min(res, st.query(pos[head[u]],pos[u]));
u=par[head[u]];
}
if (dep[u]>dep[v]) std::swap(u,v);
if (pos[u] < pos[v])
res = min(res, st.query(pos[u] + 1,pos[v]));
return res;
}
private:
int in(int u) const { return pos[u]; }
int out(int u) const { return pos[u] + sz[u] - 1; }
bool isAnc(int u,int v) const { return in(u)<=in(v) && in(v)<=out(u); } // u ancestor of v (baseRoot)
int jump(int u,int k) const {
for (int j=0;j<lg && u!=-1;j++) if (k>>j&1) u=up[j][u];
return u;
}
};
vector<vector<int>> adjlist;
vector<int> labels;
int labelsToNodes[MAXN];
int depth[MAXN];
void dfs1(int x, int pa) {
for (int ch : adjlist[x]) {
if (ch == pa) continue;
depth[ch] = depth[x] + 1;
dfs1(ch, x);
}
}
signed main() {
ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int N, E; cin >> N >> E;
adjlist.resize(N);
labels.resize(N);
vector<ii> edges(E);
for (int i = 0; i < E; ++i) {
int u, v; cin >> u >> v;
u--, v--;
edges[i] = ii{u, v};
}
vector<bool> inUse(E);
for (int i = 1; i < N; ++i) {
int x; cin >> x;
x--;
inUse[x] = true;
auto [u, v] = edges[x];
adjlist[u].emplace_back(v);
adjlist[v].emplace_back(u);
}
dfs1(0, -1);
labels[0] = INF;
for (int i = 0; i < E; ++i) {
if (inUse[i]) {
auto [u, v] = edges[i];
if (depth[u] < depth[v]) swap(u, v);
labels[u] = i;
labelsToNodes[i] = u;
}
}
HLD hld(adjlist, labels);
vector<int> ans(E);
int ctr = 1;
for (int i = 0; i < E; ++i) {
if (ans[i]) continue;
if (inUse[i]) {
ans[i] = ctr++;
auto [u, v] = edges[i];
if (depth[u] < depth[v]) swap(u, v);
hld.pointSet(u, INF);
continue;
}
int mn;
while ((mn = hld.pathMin(edges[i].first, edges[i].second)) != INF) {
ans[mn] = ctr++;
int u = labelsToNodes[mn];
hld.pointSet(u, INF);
}
ans[i] = ctr++;
}
for (int i = 0; i < E; ++i) cout << ans[i] << ' ';
}