#include <bits/stdc++.h>
using namespace std;
template <typename T>
void to_min(T &_x, const T &_y) {
  _x = min(_x, _y);
}
template <typename T>
void to_max(T &_x, const T &_y) {
  _x = max(_x, _y);
}
const int MAXN = 2005;
const int MAXS = 100005;
struct Position {
  int x, y;
  Position(int _x = 0, int _y = 0) : x(_x), y(_y) {}
  bool operator<(const Position &opp) const {
    return x < opp.x || (x == opp.x && y < opp.y);
  }
};
int n, m, k, s;
int a[MAXN][MAXN];
vector<Position> plist[9];
int r[MAXS];
bool vis[9][9] = {};
int dp[MAXN][MAXN];
inline int myabs(int x) { return x >= 0 ? x : -x; }
void input() {
  scanf("%d%d%d%d", &n, &m, &k, &s);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      scanf("%d", &a[i][j]);
      a[i][j]--;
    }
  }
  for (int i = 0; i < s; i++) {
    scanf("%d", &r[i]);
    r[i]--;
  }
}
int check(int x, int y) {
  int res = -1;
  memset(dp, -1, sizeof(dp));
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      to_max(dp[i][j], a[i][j] == x ? 0 : -1);
      if (dp[i][j - 1] != -1) to_max(dp[i][j], dp[i][j - 1] + 1);
      if (dp[i - 1][j] != -1) to_max(dp[i][j], dp[i - 1][j] + 1);
      if (a[i][j] == y) to_max(res, dp[i][j]);
    }
  }
  memset(dp, -1, sizeof(dp));
  for (int i = 1; i <= n; i++) {
    for (int j = m; j >= 1; j--) {
      to_max(dp[i][j], a[i][j] == x ? 0 : -1);
      if (dp[i][j + 1] != -1) to_max(dp[i][j], dp[i][j + 1] + 1);
      if (dp[i - 1][j] != -1) to_max(dp[i][j], dp[i - 1][j] + 1);
      if (a[i][j] == y) to_max(res, dp[i][j]);
    }
  }
  return res;
}
void solve() {
  for (int i = 1; i < s; i++) {
    vis[r[i - 1]][r[i]] = true;
    vis[r[i]][r[i - 1]] = true;
  }
  int res = -1;
  for (int i = 0; i < k; i++) {
    for (int j = 0; j < k; j++) {
      if (!vis[i][j]) continue;
      to_max(res, check(i, j));
    }
  }
  cout << res << endl;
}
int main() {
  input();
  solve();
  return 0;
}
