#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct Edge {
int to;
int id;
};
int n, m, k;
vector<int> special_vertices;
vector<ll> c;
vector<ll> w_edge;
vector<int> U, V; // original edges
/* ---------- 1. bridges (Tarjan) ---------- */
vector<vector<Edge>> g;
vector<int> tin, low;
vector<char> is_bridge;
int timerDFS = 0;
void dfs_bridge(int v, int p_edge) {
tin[v] = low[v] = ++timerDFS;
for (auto e : g[v]) {
if (e.id == p_edge) continue;
int to = e.to;
if (tin[to]) {
low[v] = min(low[v], tin[to]);
} else {
dfs_bridge(to, e.id);
low[v] = min(low[v], low[to]);
if (low[to] > tin[v]) {
is_bridge[e.id] = 1;
}
}
}
}
/* ---------- 2. DSU for components ---------- */
struct DSU {
vector<int> p, sz;
DSU(int n = 0) { init(n); }
void init(int n) {
p.resize(n);
sz.assign(n, 1);
iota(p.begin(), p.end(), 0);
}
int find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }
void unite(int a, int b) {
a = find(a); b = find(b);
if (a == b) return;
if (sz[a] < sz[b]) swap(a, b);
p[b] = a;
sz[a] += sz[b];
}
};
/* ---------- 3. tree DP ---------- */
struct TreeEdge {
int to;
ll w;
bool critical; // separates specials
};
int Ncomp; // number of components
vector<ll> compVal; // sum of c_i
vector<int> compSpec; // 0/1
vector<vector<TreeEdge>> tree;
vector<int> subSpec; // number of special components in subtree
vector<ll> dp; // profit of subtree
vector<char> hasSpecialComp; // bool per component
ll totalSpec;
/* first DFS β compute subSpec and dp */
void dfs1(int v, int parent, ll wpar, bool critpar) {
subSpec[v] = compSpec[v];
ll sum = compVal[v];
for (auto &e : tree[v]) {
if (e.to == parent) continue;
dfs1(e.to, v, e.w, e.critical);
subSpec[v] += subSpec[e.to];
ll gain = dp[e.to];
if (e.critical) gain -= e.w;
if (gain < 0) gain = 0;
sum += gain;
}
dp[v] = sum;
}
/* second DFS β reroot and compute answer for every component */
vector<ll> answerComp;
void dfs2(int v, int parent,
ll upProfitSide, // profit of the rest of the tree (excluding subtree v)
ll wpar, bool critpar) {
// contribution from parent side to v
ll contribParent = 0;
if (parent != -1) {
ll tmp = upProfitSide;
if (critpar) tmp -= wpar;
if (tmp < 0) tmp = 0;
contribParent = tmp;
}
// compute answer for v
ll ans = compVal[v] + contribParent;
// store contributions of children for later prefix/suffix sums
int deg = tree[v].size();
vector<ll> childContrib;
childContrib.reserve(deg);
vector<int> childs;
childs.reserve(deg);
for (auto &e : tree[v]) {
if (e.to == parent) continue;
ll gain = dp[e.to];
if (e.critical) gain -= e.w;
if (gain < 0) gain = 0;
childContrib.push_back(gain);
childs.push_back(e.to);
ans += gain;
}
answerComp[v] = ans;
// prefix sums of child contributions to obtain rest profit quickly
int sz = childContrib.size();
vector<ll> pref(sz + 1, 0), suff(sz + 1, 0);
for (int i = 0; i < sz; ++i) pref[i + 1] = pref[i] + childContrib[i];
for (int i = sz - 1; i >= 0; --i) suff[i] = suff[i + 1] + childContrib[i];
// go to children
for (int idx = 0; idx < sz; ++idx) {
int to = childs[idx];
// profit of the rest of the tree when edge vβto is cut
ll rest = compVal[v] + contribParent + pref[idx] + suff[idx + 1];
// pass it to child
// find the edge data to know weight and critical flag
ll w = 0; bool crit = false;
for (auto &e : tree[v]) if (e.to == to) { w = e.w; crit = e.critical; break; }
dfs2(to, v, rest, w, crit);
}
}
/* ---------- main ---------- */
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m >> k;
special_vertices.resize(k);
for (int i = 0; i < k; ++i) {
cin >> special_vertices[i];
--special_vertices[i];
}
c.resize(n);
for (int i = 0; i < n; ++i) cin >> c[i];
w_edge.resize(m);
for (int i = 0; i < m; ++i) cin >> w_edge[i];
U.resize(m);
V.resize(m);
g.assign(n, {});
for (int i = 0; i < m; ++i) {
int x, y;
cin >> x >> y;
--x; --y;
U[i] = x; V[i] = y;
g[x].push_back({y, i});
g[y].push_back({x, i});
}
/* bridges */
tin.assign(n, 0);
low.assign(n, 0);
is_bridge.assign(m, 0);
for (int i = 0; i < n; ++i)
if (!tin[i]) dfs_bridge(i, -1);
/* components */
DSU dsu(n);
for (int i = 0; i < m; ++i)
if (!is_bridge[i])
dsu.unite(U[i], V[i]);
vector<int> compId(n);
unordered_map<int,int> mapId; // root -> 0..Ncomp-1
Ncomp = 0;
for (int i = 0; i < n; ++i) {
int r = dsu.find(i);
auto it = mapId.find(r);
if (it == mapId.end()) {
mapId[r] = Ncomp++;
}
compId[i] = mapId[r];
}
compVal.assign(Ncomp, 0);
compSpec.assign(Ncomp, 0);
for (int i = 0; i < n; ++i) {
int id = compId[i];
compVal[id] += c[i];
}
for (int v : special_vertices) {
compSpec[compId[v]] = 1;
}
/* build bridge tree */
tree.assign(Ncomp, {});
for (int i = 0; i < m; ++i) if (is_bridge[i]) {
int a = compId[U[i]];
int b = compId[V[i]];
ll w = w_edge[i];
tree[a].push_back({b, w, false}); // critical will be set later
tree[b].push_back({a, w, false});
}
/* total number of special components */
totalSpec = 0;
for (int i = 0; i < Ncomp; ++i) if (compSpec[i]) ++totalSpec;
/* compute subSpec to know which bridges are critical */
subSpec.assign(Ncomp, 0);
function<void(int,int)> dfsCount = [&](int v, int p){
subSpec[v] = compSpec[v];
for (auto &e : tree[v]) if (e.to != p) {
dfsCount(e.to, v);
subSpec[v] += subSpec[e.to];
}
};
dfsCount(0, -1);
// set critical flag
for (int v = 0; v < Ncomp; ++v) {
for (auto &e : tree[v]) {
if (e.critical) continue; // already set from other side
// we need subSpec of the side that is e.to's subtree
// we have it because we performed dfsCount with root 0
// Determine which side is child
// If subSpec[e.to] < subSpec[v] then e.to is child, else v is child
int child = e.to;
int parent = v;
// ensure child is the deeper node in the rooted tree (0 as root)
// we can compare depths using subSpec, but safer to store parent during dfsCount.
}
}
// To know parent direction we redo dfs with parent array
vector<int> parent(Ncomp, -1);
vector<ll> weightToParent(Ncomp, 0);
function<void(int,int)> dfsParent = [&](int v, int p){
for (auto &e : tree[v]) if (e.to != p) {
parent[e.to] = v;
weightToParent[e.to] = e.w;
dfsParent(e.to, v);
}
};
dfsParent(0, -1);
// now set critical flag for each edge (once)
for (int v = 1; v < Ncomp; ++v) {
int p = parent[v];
ll w = weightToParent[v];
bool critical = (subSpec[v] > 0 && totalSpec - subSpec[v] > 0);
// set in both adjacency lists
for (auto &e : tree[v]) if (e.to == p) { e.critical = critical; e.w = w; }
for (auto &e : tree[p]) if (e.to == v) { e.critical = critical; e.w = w; }
}
/* DP on tree */
dp.assign(Ncomp, 0);
dfs1(0, -1, 0, false);
answerComp.assign(Ncomp, 0);
dfs2(0, -1, 0, 0, false);
/* output for original vertices */
for (int i = 0; i < n; ++i) {
if (i) cout << ' ';
cout << answerComp[ compId[i] ];
}
cout << '\n';
return 0;
}