#include <stdio.h>
#define MAX_MACHINES 20
#define MAX_JOBS 20
#define MAX_PROCESSES 20
#define MAX(x, y) ((x) > (y)) ? (x) : (y)
struct process{
int machine;
int cost_time;
int end_time;
};
struct machine_process{
int start_time;
int end_time;
int next_process;
};
int job_order[MAX_MACHINES * MAX_JOBS];
int done[MAX_JOBS] = {0};
int occupied[MAX_MACHINES] = {0};
int heads[MAX_MACHINES] = {0};
struct process jobs[MAX_JOBS][MAX_PROCESSES];
struct machine_process machines[MAX_MACHINES][MAX_JOBS * MAX_PROCESSES];
int main(void) {
int m, n;
scanf("%d %d", &m, &n);
for (int i = 0; i < m * n; ++i) {
scanf("%d", &job_order[i]);
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
scanf("%d", &jobs[i][j].machine);
}
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
scanf("%d", &jobs[i][j].cost_time);
}
}
for (int i = 0; i < m; ++i) {
machines[i][0].start_time = 0;
machines[i][0].end_time = 0;
machines[i][0].next_process = -1;
}
for (int i = 0; i < m * n; ++i) {
int job = job_order[i] - 1;
int process = done[job]++;
int machine = jobs[job][process].machine - 1;
int cost_time = jobs[job][process].cost_time;
int end_time = (process - 1 >= 0) ? jobs[job][process - 1].end_time : 0;
int tail = occupied[machine]++;
int p = heads[machine];
struct machine_process cur;
cur.next_process = -1;
cur.start_time = 0;
cur.end_time = 0;
machines[machine][tail] = cur;
if (tail == 0) {
machines[machine][tail].start_time = MAX(0, end_time);
machines[machine][tail].end_time = machines[machine][tail].start_time + cost_time;
jobs[job][process].end_time = machines[machine][tail].end_time;
continue;
} else if (machines[machine][p].start_time - (MAX(end_time, 0)) >= cost_time) {
machines[machine][tail].next_process = heads[machine];
heads[machine] = tail;
machines[machine][tail].start_time = MAX(0, end_time);
machines[machine][tail].end_time = machines[machine][tail].start_time + cost_time;
jobs[job][process].end_time = machines[machine][tail].end_time;
continue;
}
while (p != -1) {
int next_start = (machines[machine][p].next_process == -1) ? 1000000 : machines[machine][machines[machine][p].next_process].start_time;
int end = machines[machine][p].end_time;
if (next_start - (MAX(end, end_time)) >= cost_time) {
machines[machine][tail].next_process = machines[machine][p].next_process;
machines[machine][p].next_process = tail;
machines[machine][tail].start_time = MAX(end, end_time);
machines[machine][tail].end_time = machines[machine][tail].start_time + cost_time;
break;
}
p = machines[machine][p].next_process;
}
jobs[job][process].end_time = machines[machine][tail].end_time;
}
int max = 0;
for (int i = 0; i < m; ++i) {
int p = heads[i];
while (machines[i][p].next_process != -1) {
p = machines[i][p].next_process;
}
max = MAX(max, machines[i][p].end_time);
}
printf("%d", max);
return 0;
}