#include<iostream>
#include<vector>
#include<utility>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define v Next.first
#define w Next.second
#define INF 1000000
#define reg register
#define Maxn 2510<<2
using namespace std;
typedef long long ll;
ll val[Maxn >> 2];
int d[Maxn >> 2][Maxn >> 2];
ll ans = 0, dis[Maxn];
bool vis[Maxn];
int f[Maxn];
int pre[Maxn], n, m, k;
vector<pair<int, ll>> e[Maxn];
vector<int> G[Maxn >> 2];
inline ll read()
{
reg ll x = 0;
reg char c = getchar();
while (!isdigit(c))
c = getchar();
while (isdigit(c))
{
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
return x;
}
void dk(int s)
{
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> Q;
fill(vis, vis + n + 1,false);
fill(dis, dis + n + 1, INF);
dis[s] = 0;
Q.emplace(make_pair(0, s));
while (!Q.empty())
{
int u = Q.top().second;
Q.pop();
if (vis[u]) continue;
vis[u] = true;
if (dis[u] >k) continue;
for(auto x:G[u])
if (dis[u] + 1 < dis[x])
{
dis[x] = dis[u] + 1;
vis[x] = false;
Q.emplace(make_pair(dis[x], x));
}
}
for (int i = 1; i <= n; i++)
d[s][i] = dis[i]-1;
}
void djskstra()
{
for (reg int j = 0; j <= n << 1; j += n)
for (reg int i = 2 + j; i <= n + j; i++)
{
if (dis[i] == INF) continue;
//printf("%d\n", dis[i]);
for (auto Next : e[i])
{
if (dis[i] + w <= dis[v])
{
int u = i;
bool flag = true;
while (u != 1)
{
if (f[u] == f[v])
{
flag = false;
break;
}
u = pre[u];
}
if (flag)
{
pre[v] = i;
dis[v] = dis[i] + w;
}
}
}
}
}
void init()
{
cin >> n >> m >> k;
for (int i = 2; i <= n; i++)
cin >> val[i];
int x, y;
for (reg int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
d[i][j] = INF;
for (reg int i = 1; i <= m; i++)
{
x = read(), y = read();
G[x].emplace_back(y);
G[y].emplace_back(x);
// d[x][y] = d[y][x] = 1;
}
/*for (reg int i = 1; i <= n; i++)
for (reg int j = 1; j <= n; j++)
d[i][j]--;
*/
}
int main()
{
//FILE* fin;
//freopen_s(&fin, "holiday3.in", "r", stdin);
init();
//if (k) Floyd();
for (int i = 1; i <= n; i++)
{
dk(i);
}
fill(dis, dis + (Maxn), INF);
for (int i = 2; i <= n; i++)
{
if (d[1][i] > k)
vis[i] = true;
else
{
dis[i] = -val[i];
pre[i] = 1;
}
}
for (int i = 1; i <= n; i++)
f[i] = f[i + n] = f[i + 2 * n] = f[i + 3 * n] = i;
for (int i = 2; i <= n; i++)
for (int j = 2; j <= n; j++)
{
if (i == j) continue;
if (d[i][j] <= k)
{
for (int y = d[1][i] <= k ? 1 : 2; y <= 3; y++)
e[i + y * n - n].emplace_back(make_pair(j + y * n, -val[j]));
}
}
djskstra();
for (int i = 2; i <= n; i++)
{
if (d[1][i] > k) continue;
ans = max(ans, -dis[i + 3 * n]);
}
cout << ans;
return 0;
}
堆优化dk求连通性在#4寄了,求调。Orz