#include<bits/stdc++.h>
using namespace std;
const int N = 1009,B = 29,M = N * B;
int nl,nr;
int s,t;
int rnk[N][B];
int cap[B];
int l = 1,r = 1,ans;
bool check(int i,int j){
if(i > j)
swap(i,j);
j -= nl;
return rnk[i][j] >= l && rnk[i][j] <= r;
}
struct Graph{
struct edge{
int to,cap,nex;
int typ;
} e[M << 1];
int head[N + B],ecnt = 1;
int head2[N + B];
void addedge(int u,int v,int c,int typ){
ecnt++;
e[ecnt] = (edge){v,c,head[u],typ};
head[u] = ecnt;
}
} G,tmp;
queue<int> q;
int dep[N << 1];
bool bfs(){
memset(dep,0,sizeof dep);
q.push(s);
dep[s] = 1;
G.head2[s] = G.head[s];
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = G.head[u];i;i = G.e[i].nex){
int v = G.e[i].to,c = G.e[i].cap;
if(G.e[i].typ == 1 && !check(u,v))
continue;
if(dep[v] || !c)
continue;
G.head2[v] = G.head[v];
dep[v] = dep[u] + 1;
q.push(v);
}
}
return dep[t];
}
int dfs(int u,int flow){
if(u == t)
return flow;
int rest = flow,tmp;
for(int i = G.head2[u];i && rest;i = G.e[i].nex){
G.head2[u] = i;
int v = G.e[i].to,c = G.e[i].cap;
if(dep[v] != dep[u] + 1 || !c)
continue;
if(G.e[i].typ == 1 && !check(u,v))
continue;
tmp = dfs(v,min(rest,c));
if(!tmp)
dep[v] = 0;
G.e[i].cap -= tmp;
G.e[i ^ 1].cap += tmp;
rest -= tmp;
}
return flow - rest;
}
int dinic(){
G = tmp;
int flow = 0,ret = 0;
while(bfs())
while(flow = dfs(s,nl + 1))
ret += flow;
return ret;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> nl >> nr;
for(int i = 1;i <= nl;i++){
for(int j = 1;j <= nr;j++){
int tmp;
cin >> tmp;
rnk[i][tmp] = j;
}
}
for(int i = 1;i <= nr;i++)
cin >> cap[i];
s = 0;t = nl + nr + 1;
for(int i = 1;i <= nl;i++){
for(int j = 1;j <= nr;j++){
G.addedge(i,j + nl,1,1);
G.addedge(j + nl,i,0,1);
}
}
for(int i = 1;i <= nl;i++){
G.addedge(s,i,1,2);
G.addedge(i,s,0,2);
}
for(int i = nl + 1;i <= nl + nr;i++){
G.addedge(i,t,cap[i - nl],2);
G.addedge(t,i,0,2);
}
tmp = G;
ans = nr;
while(l <= nr){
while(r <= nr && dinic() < nl)
r++;
ans = min(ans,r - l + 1);
l++;
}
cout << ans;
return 0;
}