#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
#define MAXN 2500
#define MAXM 10000
using namespace std;
int n,m,k;//0<=k<=100
int x,y;
ll w[MAXN+1];
int dis[MAXN+1];
bool connected[MAXN+1][MAXN+1];
vector<int> edge[MAXN+1];
struct node{
int num,dis;
bool operator<(const node &tmp)const{
return dis>tmp.dis;
}
};
vector<int> f[MAXN+1];
ll ans;
inline ll read(){
ll x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9') ch=='-'?f=-f:false;
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
bool cmp(int a, int b){
return w[a]>w[b];
}
void dijkstra(int x){
memset(dis,-1,sizeof(dis));
dis[x]=0;
queue<node> q;
q.push(node{x,0});
node u;
while(!q.empty()){
u=q.front();
q.pop();
if(u.num!=x){
connected[x][u.num]=true;
if(x!=1&&connected[1][u.num]){
f[x].push_back(u.num);
sort(f[x].begin(),f[x].end(),cmp);
if(f[x].size()>3){
f[x].pop_back();
}
}
}
if(u.dis==k+1) continue;
for(int i=0;i<edge[u.num].size();i++){
if(dis[edge[u.num][i]]==-1){
dis[edge[u.num][i]]=dis[u.num]+1;
q.push(node{edge[u.num][i],dis[edge[u.num][i]]});
}
}
}
}
int main(){
n=read(); m=read(); k=read();
for(int i=2;i<=n;i++){
w[i]=read();
}
for(int i=1;i<=m;i++){
x=read(); y=read();
edge[x].push_back(y);
edge[y].push_back(x);
}
for(int i=1;i<=n;i++) dijkstra(i);
for(int B=2;B<=n;B++){
for(int C=2;C<=n;C++){
if(connected[B][C]){
for(int i=0;i<f[B].size();i++){
for(int j=0;j<f[C].size();j++){
int A=f[B][i],D=f[C][j];
if(A!=C&&B!=D&&A!=D){
ans=max(ans,w[A]+w[B]+w[C]+w[D]);
}
}
}
}
}
}
printf("%lld\n",ans);
}
subtask#0全AC subtask#1部分TLE subtask#2全TLE