#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<tuple>
#define rep(i, start, end) for (int i = (int)start; i < (int)end; ++i)
#define rrep(i, start, end) for (int i = (int)start - 1; i >= (int)end; --i)
#define all(x) (x).begin(), (x).end()
using namespace std;
using ll = long long;
template<typename T> inline bool chmax(T& a, T b) {if (a < b) {a = b; return true;} return 0;}
template<typename T> inline bool chmin(T& a, T b) {if (a > b) {a = b; return true;} return 0;}

using state = tuple<ll, int, int>;

const ll INF = 1LL << 50;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int R, C;
    cin >> R >> C;
    vector<vector<int>> A(R, vector<int>(C - 1));
    vector<vector<int>> B(R - 1, vector<int>(C));
    rep(i, 0, R) rep(j, 0, C - 1) {
        cin >> A[i][j];
    }
    rep(i, 0, R - 1) rep(j, 0, C) {
        cin >> B[i][j];
    }
    priority_queue<state, vector<state>, greater<state>> que;
    vector<vector<ll>> dp(R, vector<ll>(C, INF));
    dp[0][0] = 0;
    que.emplace(0, 0, 0);
    while (!que.empty()) {
        state now = que.top();
        que.pop();
        ll cost = get<0>(now);
        int r = get<1>(now);
        int c = get<2>(now);
        if (dp[r][c] < cost) {
            continue;
        }
        if (c + 1 < C && chmin(dp[r][c + 1], cost + A[r][c])) {
            que.emplace(dp[r][c + 1], r, c + 1);
        }
        if (c - 1 >= 0 && chmin(dp[r][c - 1], cost + A[r][c - 1])) {
            que.emplace(dp[r][c - 1], r, c - 1);
        }
        if (r + 1 < R && chmin(dp[r + 1][c], cost + B[r][c])) {
            que.emplace(dp[r + 1][c], r + 1, c);
        }
        rep(i, 0, r) {
            if (chmin(dp[r - i - 1][c], cost + 1 + i + 1)) {
                que.emplace(dp[r - i - 1][c], r - i - 1, c);
            }
        }
    }
    cout << dp[R - 1][C - 1] << endl;
    return 0;
}
#include<bits/stdc++.h>
#define ll long long
#define N 400005
using namespace std;
int read() {
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while('0'<=c&&c<='9'){x=x*10+c-'0';c=getchar();}
	return x*f;
}
int n,m,K,cnt,h[N],c[N],fp[N];
struct Edge {
	int to,next;
}a[N*2];
void Add(int x,int y) {
	cnt++;a[cnt].to = y;a[cnt].next = h[x];h[x] = cnt;
}
int ind;
ll ans = 0;
#define inf 0x7fffffff/2
queue<int>q;
int d[20][N],inq[N];
void bfs(int id) {
	
	for(int i=1; i<=n; ++i)d[id][i] = inf;
	
	q.push(c[id]);d[id][c[id]] = 0;
	
	inq[c[id]] = 1;
	
	while(!q.empty()) {
		
		int x = q.front();q.pop();
		for(int i=h[x]; i; i=a[i].next) {
			int y = a[i].to;
			if(!inq[y])d[id][y] = d[id][x]+1,q.push(y),inq[y] = 1;
		}
	}
	memset(inq,0,sizeof(inq));
}
ll f[1<<17][18];
int sta;
int fl;
void deal() {
//	fl++;
//	if(fl>=20)
//	{
//		vector<int>v;
//		cout<<v[2313132]<<endl;
//		exit(0);
//	}
	for(int i=1; i<=K; ++i)bfs(i);
//	for(int i=1; i<=K; ++i){ 
//		
//		for(int j=1; j<=n; ++j) 
//		cout << d[i][j] << ' ';
//		cout << '\n';
//	}
	memset(f,0x3f,sizeof(f));
	for(int i=1; i<=K; ++i)f[1<<i-1][i] = 0;
	for(int i=0;i<(1<<K);i++)
	{
		for(int j=1;j<=K;j++)
		{
			if(f[i][j]>1e9)continue;
			for(int t=1;t<=K;t++)
			{
				if(i&(1<<t-1))continue;
				f[i+(1<<t-1)][t]=min(f[i+(1<<t-1)][t],f[i][j]+d[j][c[t]]);
			}
		}
	}
	for(int j=1;j<=K;j++)
	{
		ans=min(ans,f[(1<<K)-1][j]);
	}
	
}
bool vst[N];
void dfs(int x) {
	vst[x] = 1;
	if(fp[x])ind |= 1 << fp[x]-1;
	for(int i=h[x]; i; i=a[i].next) {
		int y = a[i].to;
		if(!vst[y])dfs(y);
	}
}
int main() {
	n = read();m = read();
	for(int i=1; i<=m; ++i) {
		int x = read(),y = read();
		Add(x,y);Add(y,x);
	}
	K = read();sta = 0;
	for(int i=1; i<=K; ++i) {
		sta |= 1<<i-1;
	}
	ans = 1LL<<40;
	for(int i=1; i<=K; ++i)c[i] = read(),fp[c[i]] = i;
	for(int i=1; i<=n; ++i)if(!vst[i]) {
		ind = 0;
		dfs(i);
		if(ind == sta)
		{
			deal();
			for(int j=1;j<=K;j++)if(!vst[c[j]])exit(0);
		}
	}
	if(ans >= 1e9)puts("-1");
	else cout << ans+1;
}