#include <cstdio>
#include <queue>
using namespace std;
typedef long long ll;
const int N = 2505;
const int M = 10005;
struct Edge {
int v, next;
} edge[2 * M];
int head[N];
int cnt;
void add_edge(int u, int v) {
cnt++;
edge[cnt].v = v;
edge[cnt].next = head[u];
head[u] = cnt;
}
ll val[N];
int dis[N][N];
bool vis[N];
void bfs(int s) {
for (int i = 0; i < N; i++) {
vis[i] = false;
}
queue < int > q;
q.push(s);
dis[s][s] = -1;
vis[s] = true;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int v, i = head[u]; i != 0; i = edge[i].next) {
v = edge[i].v;
if (!vis[v]) {
dis[s][v] = dis[s][u] + 1;
q.push(v);
vis[v] = true;
}
}
}
}
int best[N][3];
int main() {
int n, m, k;
scanf("%d %d %d", &n, &m, &k);
val[1] = -4000000000000000000;
for (int i = 2; i <= n; i++) {
scanf("%lld", &val[i]);
}
for (int u, v, i = 1; i <= m; i++) {
scanf("%d %d", &u, &v);
add_edge(u, v);
add_edge(v, u);
}
for (int i = 1; i <= n; i++) {
bfs(i);
}
for (int i = 2; i <= n; i++) {
best[i][0] = best[i][1] = best[i][2] = 1;
for (int j = 2; j <= n; j++) {
if (i != j && dis[1][j] <= k && dis[j][i] <= k) {
if (val[j] > val[best[i][0]]) {
best[i][2] = best[i][1];
best[i][1] = best[i][0];
best[i][0] = j;
} else if (val[j] > val[best[i][1]]) {
best[i][2] = best[i][1];
best[i][1] = j;
} else if (val[j] > val[best[i][2]]) {
best[i][2] = j;
}
}
}
}
ll ans = 0;
int a, b, c, d;
for (b = 2; b <= n; b++) {
for (c = 2; c <= n; c++) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
a = best[b][i];
d = best[c][j];
if (a != 1 && a != c && a != d && b != c && d != 1 && d != b && dis[b][c] <= k) {
ans = max(ans, val[a] + val[b] + val[c] + val[d]);
}
}
}
}
}
printf("%lld", ans);
return 0;
}