
//================code===================//

//#define TLE

#ifdef TLE
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#endif

#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <ctime>
#include <random>
#include <chrono>
//#include <stdint.h>

#define ci(t) cin>>t
#define co(t) cout<<t
#define LL long long
#define ld long double
#define fa(i,a,b) for(LL i=(a);i<(LL)(b);++i)
#define fd(i,a,b) for(LL i=(a);i>(LL)(b);--i)
#define setp tuple<LL,LL,LL>
#define setl pair<LL,LL>
#define micro 0.000000000001

using namespace std;

LL gcd(LL a, LL b)
{
	if (!(a && b)) return max(a, b);
	return a % b ? gcd(b, a % b) : b;
}

#ifdef OHSOLUTION
#define ce(t) cerr<<t
#define AT cerr << "\n=================ANS=================\n"
#define AE cerr << "\n=====================================\n"
#define DB(a) cerr << __LINE__ << ": " << #a << " = " << (a) << endl;
#define __builtin_popcount __popcnt
#define __builtin_popcountll __popcnt64
#else
#define AT
#define AE
#define ce(t)
#endif

pair <int, int> vu[9] = { {0,1},{1,0},{0,-1} ,{-1,0},{-1,0},{-1,-1}, {0,-1} , {1,-1},{-1,-1} }; //RDLU EWSN

template<typename T, typename U> void ckmax(T& a, U b) { a = a < b ? b : a; }
template<typename T, typename U> void ckmin(T& a, U b) { a = a > b ? b : a; }
struct gcmp { bool operator()(LL a, LL b) { return a < b; } bool operator()(setl& a, setl& b) { return a.second < b.second; } };
struct lcmp { bool operator()(LL a, LL b) { return a > b; } bool operator()(setl& a, setl& b) { return a.second > b.second; } };

const int max_v = 1e4 + 7;
const int max_k = 8e2 + 7;
const int bsz = (1ll << 10) + 7;
const int INF = 1e9 + 7;
const LL LNF = (LL)5e18 + 7ll;
LL mod = LNF; //998244353
template<typename T, typename U> void MOD(T& a, U b) { a += b; if (a < 0) a = a % mod + mod; if (a >= mod) a -= mod; };


LL arr[max_k][max_k];
LL p[max_k][max_k];

int main()
{
#ifdef OHSOLUTION
	freopen("input.txt", "r", stdin);
#endif
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	int n, k; ci(n >> k);

	struct node
	{
		LL r, c;
		LL v;
	};	

	vector<node> vi;
	fa(i, 1, n + 1) fa(j, 1, n + 1) ci(arr[i][j]), vi.push_back({ i,j,arr[i][j] });
	


	sort(vi.begin(), vi.end(), [&](node& a, node& b) {
		return a.v < b.v;
		});

	int l = 0;
	int r = vi.size();
	int tar = k*k - (k * k / 2ll + 1)+1;
	
	auto ck = [&](int m)
	{
		memset(p, 0, sizeof(p));
		fa(i, 0, m+1)
		{
			if (i >= vi.size()) continue;
			p[vi[i].r][vi[i].c] = 1;
		}

		fa(i, 1, n + 1) fa(j, 1, n + 1) p[i][j] += p[i][j - 1];
		fa(j, 1, n + 1) fa(i, 1, n + 1) p[i][j] += p[i-1][j];

		auto f = [&](int ar, int ac, int nr, int nc)
		{
			return p[nr][nc] + p[ar - 1][ac - 1] - p[nr][ac - 1] - p[ar - 1][nc];
		};	

		
		fa(i, 1, n - k + 2) fa(j, 1, n - k + 2)
		{
			if (f(i, j, i + k-1, j + k-1) >= tar) return true;
		}

		return false;
	};

	
	while (l ^ r)
	{
		int mid = l + r >> 1;

		if (ck(mid)) r = mid;
		else l = mid + 1;
	}

	co(vi[l].v);

	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for(int i = 0; i < n; i++)
#define REPR(i, n) for(int i = n - 1; i >= 0; i--)
#define FOR(i, m, n) for(int i = m; i <= n; i++)
#define FORR(i, m, n) for(int i = m; i >= n; i--)
#define SORT(v, n) sort(v, v+n);
#define VSORT(v) sort(v.begin(), v.end());
#define VSORTR(v) sort(v.rbegin(), v.rend());
#define ALL(v) (v).begin(),(v).end()
 
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll, ll>;

template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }

const ll MOD = 1e9 + 7;
const ll INF = 1e18;

int main(){
	cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    ll n, m;
    cin >> n >> m;
    ll a, b;
    vvll g(n);
    REP(i, m) {
        cin >> a >> b;
        a--, b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    ll k;
    cin >> k;
    vll c(k);
    REP(j, k) {
        cin >> c[j];
        c[j]--;
    }
    auto BFS = [&](int s){
        vll cost(n, INF);
        cost[s] = 0;
        queue<int> q;
        q.push(s);
        while(q.size()){
            int x = q.front();
            q.pop();
            for(int y : g[x]) if(chmin(cost[y], cost[x] + 1)) q.push(y);
        }
        for(int i = 0; i < k; i++) cost[i] = cost[c[i]];
        cost.resize(k);
        return cost;
    };
    
    vvll d(k);
    REP(i, k) d[i] = BFS(c[i]);

    vvll dp(k, vll(1 << k, INF));
    REP(i, k) dp[i][0] = 0;
    for(int bit = 1; bit < (1 << k); bit++){
        REP(j, k) if(bit >> j & 1) {
            REP(x, k){
                ll cost = dp[j][bit - (1 << j)] + d[j][x];
                if (bit == ((1 << k) - 1)) chmin(dp[x][bit], dp[j][bit - (1 << j)]);
                chmin(dp[x][bit], cost);
            }
        }
    }

    ll ans = INF;
    REP(i, k) chmin(ans, dp[i][(1 << k) - 1]);

    if(ans == INF) ans = -2;
    cout << ans + 1 << endl;
    return 0;
}