#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
typedef long long ll;
#define LLINF (1LL<<60)
template<class T,class C> T max(T a,C b){ return std::max(a, (T)b); }
template<class T,class C> T min(T a,C b){ return std::min(a, (T)b); }
//TSPここから
struct TSP{//n<=17
  int n;
  vector<vector<ll> > dist;
  vector<vector<ll> > dp;
  TSP() : n(17){
    init();
  }
  TSP(int n_){
    n = n_;
    init();
  }
  void init(){//全体初期化
    ll i;
    dist.resize(n);
    for(i=0;i<dist.size();i++){
      dist[i].assign(n,LLINF);
    }
    dp_init();
  }
  void dp_init(){//dpのみ初期化
    ll i;
    dp.resize(1<<n);
    for(i=0;i<dp.size();i++){
      dp[i].assign(n,LLINF);
    }
  }
  void create_edge(ll s,ll t,ll d){//有向辺生成
    //s!=t,0<=s,t<n,d>=1
    dist[s][t] = min(dist[s][t],d);
  }
  void create_edge_each(ll a,ll b,ll d){//無向辺生成
    create_edge(a,b,d);
    create_edge(b,a,d);
  }
  void delete_edge(ll s,ll t){//辺の削除
    dist[s][t] = LLINF;
  }
  ll find_shortest_path(ll s){//最短距離(巡回)取得 O(N^2 2^N)
    //0<=s<n,-1=notfound
    ll i,j,k;
    dp_init();
    dp[0][s] = 0;
    for(i=0;i<(1<<n);i++){
      for(j=0;j<n;j++){
        for(k=0;k<n;k++){
          dp[i|1<<k][k] = min(dp[i|1<<k][k], dp[i][j]+dist[j][k]);
        }
      }
    }
    ll res = dp[(1<<n)-1][s];
    return (res>=LLINF ? -1 : res);
  }
  ll find_shortest_path_2(){//最短距離(パス,始点任意)取得 O(N^2 2^N)
    //0<=s<n,-1=notfound
    ll i,j,k;
    dp_init();
    for(ll s=0;s<n;s++) dp[1<<s][s] = 0;
    
    for(i=0;i<(1<<n);i++){
      for(j=0;j<n;j++){
        for(k=0;k<n;k++){
          dp[i|1<<k][k] = min(dp[i|1<<k][k], dp[i][j]+dist[j][k]);
        }
      }
    }
    ll res = dp[(1<<n)-1][0];
    for(i=1;i<n;i++){
      res = min(res, dp[(1<<n)-1][i]);
    }
    return (res>=LLINF ? -1 : res);
  }
  ll find_shortest_path_2(ll s){//最短距離(パス,始点固定)取得 O(N^2 2^N)
    //0<=s<n,-1=notfound
    ll i,j,k;
    dp_init();
    dp[1<<s][s] = 0;
    for(i=0;i<(1<<n);i++){
      for(j=0;j<n;j++){
        for(k=0;k<n;k++){
          dp[i|1<<k][k] = min(dp[i|1<<k][k], dp[i][j]+dist[j][k]);
        }
      }
    }
    ll res = dp[(1<<n)-1][0];
    for(i=1;i<n;i++){
      res = min(res, dp[(1<<n)-1][i]);
    }
    return (res>=LLINF ? -1 : res);
  }
};
//TSPここまで
vector<ll> edgeA[100010];
ll edgeB[20][20]={};
ll getEdge(ll s,ll t){
  return edgeB[s][t];
}
ll dist[100010]={};
int main(){
  ll i,j,n,m,a,b,k,c[20];
  queue<ll> que;
  cin >> n >> m;
  for(i=0;i<m;i++){
    //a=i+1;b=i+2;
    cin >> a >> b;
    a--;b--;
    edgeA[a].push_back(b);
    edgeA[b].push_back(a);
  }
  cin >> k;
  for(i=0;i<k;i++){
    //if(i==k-1) c[i]=n;
    //else c[i]=i+1;
    cin >> c[i];
    c[i]--;
  }
  for(i=0;i<k;i++){
    ll tmp = c[i];
    que.push(tmp);
    for(j=0;j<n;j++){
      dist[j]=LLINF;
    }
    dist[tmp]=0;
    while(!que.empty()){
      auto p = que.front();
      que.pop();
      //cout << p << endl;
      for(auto q :edgeA[p]){
        if(dist[q]==LLINF){
          dist[q] = dist[p]+1;
          que.push(q);
        }
      }
    }
    for(j=0;j<k;j++){
      ll tmp2 = c[j];
      if(i==j) continue;
      edgeB[i][j] = dist[tmp2];
    }
  }
  TSP tsp(k);
  for(i=0;i<k;i++){
    for(j=0;j<k;j++){
      if(i==j) continue;
      tsp.create_edge(i,j,getEdge(i,j));
    }
  }
  ll res = tsp.find_shortest_path_2();
  cout << (res==-1 ? -1 : res+1) << endl;
  return 0;
}

#include <bits/stdc++.h>

using namespace std;

void solve() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> adj_list(n);
    vector<vector<bool>> adj_matrix(n, vector<bool>(n, 0));
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u;
        --v;
        adj_list[u].push_back(v);
        adj_list[v].push_back(u);
        adj_matrix[u][v] = true;
        adj_matrix[v][u] = true;
    }
    vector<bool> is_complete(1 << n, false);
    is_complete[0] = true;
    for (int mask = 1; mask < (1 << n); ++mask) {
        int i = 0;
        while (!(mask & (1 << i))) {
            ++i;
        }
        if (!is_complete[mask ^ (1 << i)]) {
            continue;
        }
        is_complete[mask] = true;
        for (int j = i + 1; j < n; ++j) {
            if ((mask & (1 << j)) && !adj_matrix[i][j]) {
                is_complete[mask] = false;
            }
        }
    }
    vector<int> components(1 << n, 2 * n + 1);
    components[0] = 0;
    for (int mask = 1; mask < (1 << n); ++mask) {
        if (is_complete[mask]) {
            components[mask] = 1;
            continue;
        }
        int i = 0;
        while (!((1 << i) & mask)) {
            ++i;
        }
        int smaller_mask = mask ^ (1 << i);
        for (int lower_mask = smaller_mask; lower_mask != 0; lower_mask = (lower_mask - 1) & smaller_mask) {
            if (is_complete[mask ^ lower_mask]) {
                components[mask] = min(components[mask], 1 + components[lower_mask]);
            }
        }
    }
    cout << components[(1 << n) - 1] << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    solve();
    return 0;
}