#pragma GCC optimize("Ofast")
#define _USE_MATH_DEFINES
#include "bits/stdc++.h"

using namespace std;

using ll = int64_t;
using db = double;
using ld = long double;
using vi = vector<int>;
using vl = vector<ll>;
using vvi = vector<vector<int>>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vpii = vector<pii>;
using vpll = vector<pll>;

constexpr char newl = '\n';
constexpr double eps = 1e-10;

#define FOR(i,a,b) for (int i = (a); i < (b); i++)
#define F0R(i,b) FOR(i,0,b)
#define RFO(i,a,b) for (int i = ((b)-1); i >=(a); i--)
#define RF0(i,b) RFO(i,0,b)
#define show(x) cout << #x << " = " << x << '\n';
#define rng(a) a.begin(),a.end()
#define rrng(a) a.rbegin(),a.rend()
#define sz(x) (int)(x).size()
#define YesNo {cout<<"Yes";}else{cout<<"No";}
#define YESNO {cout<<"YES";}else{cout<<"NO";}
#define v(T) vector<T>
#define vv(T) vector<vector<T>>

template<typename T1, typename T2> inline void chmin(T1& a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }
template<class T> bool lcmp(const pair<T, T>& l, const pair<T, T>& r) {
  return l.first < r.first;
}
template<class T> istream& operator>>(istream& i, v(T)& v) {
  F0R(j, sz(v)) i >> v[j];
  return i;
}
template<class A, class B> istream& operator>>(istream& i, pair<A, B>& p) {
  return i >> p.first >> p.second;
}
template<class A, class B, class C> istream& operator>>(istream& i, tuple<A, B, C>& t) {
  return i >> get<0>(t) >> get<1>(t) >> get<2>(t);
}
template<class T> ostream& operator<<(ostream& o, const pair<T, T>& v) {
  o << "(" << v.first << "," << v.second << ")";
  return o;
}
template<class T> ostream& operator<<(ostream& o, const vector<T>& v) {
  F0R(i, v.size()) {
    o << v[i] << ' ';
  }
  o << newl;
  return o;
}
template<class T> ostream& operator<<(ostream& o, const set<T>& v) {
  for (auto e : v) {
    o << e << ' ';
  }
  o << newl;
  return o;
}
template<class T1, class T2> ostream& operator<<(ostream& o, const map<T1, T2>& m) {
  for (auto& p : m) {
    o << p.first << ": " << p.second << newl;
  }
  o << newl;
  return o;
}

#if 1

/*
グループにできない、相性の悪い頂点ペアが複数ある
（相性が悪い＝辺がない）

相性の悪いペアが別のグループになるようにグループ分けしたときの、
最小のグループ数を求めよ。

1<=N<=18

2^18 = 262,144

*/

// INSERT ABOVE HERE
signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N, M; cin >> N >> M;
  vv(bool) as(N, v(bool)(N, true));
  F0R(i, M) {
    int a, b; cin >> a >> b;
    a--; b--;
    as[a][b] = as[b][a] = false;
  }
  vi dp(1 << N, N);
  dp[0] = 0;
  F0R(b, 1 << N) {
    F0R(i, N) {
      if ((b >> i) & 1) {
        int b2 = b ^ (1 << i);
        if (dp[b2] == 0) {
          dp[b] = 1;
          break;
        }
        if (dp[b2] == 1) {
          bool ok = true;
          F0R(j, N) {
            if ((b2 >> j) & 1 && as[i][j]) {
              ok = false;
              break;
            }
          }
          if (ok) {
            dp[b] = 1;
            break;
          }
          dp[b] = 2;
        }
      }
    }
    if (dp[b] > 2) {
      int ib = ~b;
      for (auto c = 0; c < b; c = (c + 1 + ib) & b) {
        auto c2 = c ^ b;
        chmin(dp[b], dp[c] + dp[c2]);
      }
    }
  }
  //cout << dp;
  cout << dp[(1 << N) - 1] << newl;
}
#endif

#include <bits/stdc++.h>


#ifdef _DEBUG_
#define debug(x) cerr<<#x<<" : "<<x<<" "
#define cout_n cerr<<endl
#else
#define debug(x) 
#define cout_n
#endif
using namespace std;
const int MAXN=1e5+100;
vector<int>G[MAXN];
void add(int u,int v){
	G[u].push_back(v);G[v].push_back(u);
}
int n,m,k;
int c2v[20],v2c[MAXN];
int f[20][20];
bool vis[MAXN];
void bfs(int u){
	memset(vis,false,sizeof(vis));
	vis[u]=true;
	queue<int>q;q.push(u);
	int d=0;
	while(!q.empty()){
		int sz=q.size();
		++d;
		while(sz--){
			int nowu=q.front();q.pop();
			// debug(nowu);
			for(auto v:G[nowu]){
				if(!vis[v]){
					q.push(v);
					vis[v]=true;
					if(v2c[v]){
						// debug(v);
						// debug(c2v[u]);debug(c2v[v]);cout_n;
						f[v2c[u]][v2c[v]]=d;
					}
				}
			}
		}
	}
	// cout_n;
}
int dp[(1<<19)][20];
const int INF=0x3f3f3f3f;
int get1idx(int idx){
	return 1<<(idx-1);
}
int work(){
	int condmax=(1<<k)-1;
	memset(dp,INF,sizeof(dp));
	for(int i=1;i<=k;++i){
		dp[get1idx(i)][i]=0;
	}
	for(int i=1;i<=condmax;++i){
		for(int x=1;x<=k;++x){
			// debug(x);debug(get1idx(x));cout_n;
			if(!(i&(get1idx(x)))){
				continue;
			}
			int cond=(i&(~get1idx(x)));
			for(int y=1;y<=k;++y){
				if(!(cond&(get1idx(y)))){
					continue;
				}
				debug(i);debug(c2v[x]);debug(c2v[y]);debug(cond);cout_n;
				debug(dp[i][x]);debug(dp[cond][y]);debug(f[y][x]);cout_n;
				dp[i][x]=min(dp[i][x],dp[cond][y]+f[y][x]);
				debug(dp[i][x]);cout_n;cout_n;
			}
		}
	}
	int res=INF;
	for(int i=1;i<=k;++i){
		res=min(res,dp[condmax][i]);
	}
	return res==INF?-1:res+1;
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#ifdef _DEBUG_
	freopen("E.in","r",stdin);
	freopen("E.out","w",stdout);
#endif
	cin>>n>>m;
	debug(n);debug(m);cout_n;
	for(int i=1;i<=m;++i){
		int u,v;cin>>u>>v;
		add(u,v);
	}
	cin>>k;
	for(int i=1;i<=k;++i){
		cin>>c2v[i];v2c[c2v[i]]=i;
	}
	
//	for(int i=1;i<=n;++i){
//		debug(i);debug(v2c[i]);cout_n;
//	}
	memset(f,INF,sizeof(f));
	for(int u=1;u<=n;++u){
		if(v2c[u]){
			bfs(u);
		}
	}
	for(int i=1;i<=k;++i){
		for(int j=1;j<=k;++j){
			debug(i);debug(j);debug(f[i][j]);cout_n;
		}
	}
	cout<<work()<<'\n';
	return 0;
}