#include <bits/stdc++.h>

#define rep(i, n) for(int i = 0; i < n; i++)
using namespace std;

typedef long long ll;

const int INF = 1 << 30;
const ll LLINF = 1LL << 60;

int mod = 1000000007;

int dp[3030][10][50];

void init(){
    rep(i, 3030) rep(j, 10) rep(k, 50) dp[i][j][k] = 0;
    dp[0][0][0] = 1;
}

int main(void){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int N; cin >> N;
    vector<int> A(N), B(N), C(N), D(N), E(N);
    rep(i, N) cin >> A[i] >> B[i] >> C[i] >> D[i] >> E[i];
    int ok = 0, ng = INF;
    int m = (ok+ng)/2;
    while(abs(ok-ng) > 1){
        //cout << "m: " << m << endl;
        init();
        rep(i, N){
            int val = 0;
            if(A[i] >= m) val += (1 << 4);
            if(B[i] >= m) val += (1 << 3);
            if(C[i] >= m) val += (1 << 2);
            if(D[i] >= m) val += (1 << 1);
            if(E[i] >= m) val += (1 << 0);
            //cout << i << ": " << val << endl;
            for(int ninzuu = 0; ninzuu < 5; ninzuu++){
                rep(now_state, (1 << 5)){
                    dp[i+1][ninzuu][now_state] = max(dp[i+1][ninzuu][now_state], dp[i][ninzuu][now_state]);
                    dp[i+1][ninzuu+1][now_state|val] = max(dp[i+1][ninzuu+1][now_state|val], dp[i][ninzuu][now_state]);
                }
            }
        }
        if(dp[N][3][(1 << 5)-1] == 1) ok = m;
        else ng = m;
        m = (ok+ng)/2;
    }
    cout << ok << endl;
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef pair<int,int> pii;
typedef long long ll;
const long long MOD=1000000007;
#define rep(i,n) for(ll i=0;i<(n);i++)
#define rep2(i,m,n) for(ll i=(m);i<(n);i++)
#define ALL(v) v.begin(), v.end()
#define pb push_back

const int INF=1e9;

int n,m,k;

vector<int> c(20);

vector<vector<int>> graph(200000,vi(0));

vector<vector<int>> dp(1<<20,vi(20,INF));

vector<vector<int>> dis(20,vi(20));




int bfs(int s, int t){
    vi seen(n,-1);
    seen[s]=0;

    queue<int> q;
    q.push(s);
    while (!q.empty()){
        int x=q.front();
        q.pop();
        for (int next:graph[x]){
            if (seen[next]==-1) {
                seen[next]=seen[x]+1;
                q.push(next);
            }
        }
    }

    return seen[t];



}

int rec(int S, int v){
    if (dp[S][v]!=INF) return dp[S][v];

    if (S==(1<<v)) return dp[S][v]=0;


    rep(i,k){
        if ((S>>i & 1) and (i!=v)){
            dp[S][v]=min(rec(S & ~(1<<v),i)+dis[v][i], dp[S][v]);
        }
    }
    
    return dp[S][v];

}


int main(){


    cin>>n>>m;

    rep(i,m){
        int a,b;
        cin>>a>>b;
        a--;
        b--;
        graph[a].pb(b);
        graph[b].pb(a);
    }

    cin>>k;

    rep(i,k){
        int tmp;
        cin>>tmp;
        tmp--;
        c[i]=tmp;
    }



    rep(i,k){
        rep(j,k){
            if (i<=j) dis[i][j]=bfs(c[i],c[j]);
            else dis[i][j]=dis[j][i];
        }
    }




    int ans=1e9;

    rep(i,k){
        rep(j,k){
            if (dis[i][j]==-1) ans=-1;
        }
    }


    if (ans!=-1){
        rep(i,k){
            ans=min(ans,rec((1<<k)-1,i)+1);
        }
    }

    cout<<ans<<endl;












}