#include
#include
#include
using
namespace
std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
typedef
long
long
LL;
typedef
unsigned
long
long
ULL;
const
int
maxn = 111111;
const
int
inf = 0x7f7f7f7f;
int
h[] = {0, 24, 6, 2, 1, 1};
struct
node {
int
a[6];
node() {
for
(
int
i = 1; i <= 5; i++) {
a[i] = i;
}
}
node(
int
tp[]) {
for
(
int
i = 1; i <= 5; i++) {
a[i] = tp[i];
}
}
node(
int
val) {
int
sta = 0;
for
(
int
i = 1; i <= 5; i++) {
int
k = val / h[i];
val %= h[i];
int
cnt = 0;
for
(
int
j = 1; j <= 5; j++) {
if
( (sta & (1 << j)) == 0 ) {
if
(cnt == k) {
sta |= (1 << j);
a[i] = j;
break
;
}
else
{
cnt++;
}
}
}
}
}
node operator * (
const
node &tp)
const
{
node ret;
for
(
int
i = 1; i <= 5; i++) {
ret.a[i] = tp.a[ a[i] ];
}
return
ret;
}
node operator = (
const
node &tp) {
for
(
int
i = 1; i <= 5; i++) {
a[i] = tp.a[i];
}
return
(*
this
);
}
void
show() {
for
(
int
i = 1; i <= 5; i++) {
if
(i != 1) cout <<
' '
;
cout << a[i];
}
cout << endl;
}
void
input() {
for
(
int
i = 1; i <= 5; i++) {
scanf
(
"%d"
, a + i);
}
}
};
node room[maxn];
struct
SegTree {
node num[maxn << 2];
bool
flag;
void
build(
int
l,
int
r,
int
rt) {
if
(l == r) {
num[rt] = room[l];
return
;
}
int
m = (l + r) >> 1;
if
(flag) {
build(lson);
build(rson);
num[rt] = num[rt << 1] * num[rt << 1 | 1];
}
else
{
build(rson);
build(lson);
num[rt] = num[rt << 1 | 1] * num[rt << 1];
}
}
node query(
int
ll,
int
rr,
int
l,
int
r,
int
rt) {
if
(ll <= l && r <= rr) {
return
num[rt];
}
int
m = (l + r) >> 1;
node ret;
if
(flag) {
if
(ll <= m) ret = ret * query(ll, rr, lson);
if
(rr > m) ret = ret * query(ll, rr, rson);
}
else
{
if
(rr > m) ret = ret * query(ll, rr, rson);
if
(ll <= m) ret = ret * query(ll, rr, lson);
}
return
ret;
}
}tree[2];
int
get_hash(
int
num[]) {
int
ret = 0;
for
(
int
i = 1; i <= 5; i++) {
int
cnt = 0;
for
(
int
j = i + 1; j <= 5; j++) {
if
(num[i] > num[j]) {
cnt++;
}
}
ret += cnt * h[i];
}
return
ret;
}
int
dp[111][133];
node op[111];
node start;
int
cnt[111];
int
main() {
int
n, m;
while
(~
scanf
(
"%d %d"
, &n, &m)) {
for
(
int
i = 1; i <= n; i++) {
room[i].input();
}
tree[0].flag = 0;
tree[1].flag = 1;
tree[0].build(1, n, 1);
tree[1].build(1, n, 1);
for
(
int
i = 1; i <= m; i++) {
int
l, r;
scanf
(
"%d%d"
, &l, &r);
op[i] = tree[l < r].query(min(l, r), max(l, r), 1, n, 1);
cnt[i] = max(l, r) - min(l, r) + 1;
}
start.input();
memset
(dp, 0x7f,
sizeof
(dp));
dp[0][ get_hash(start.a) ] = 0;
for
(
int
i = 1; i <= m; i++) {
for
(
int
j=0;j<120;j++) dp[i][j]=dp[i-1][j];
for
(
int
j = 0; j < 120; j++) {
if
(dp[i-1][j] == inf)
continue
;
node now(j);
node next = now * op[i];
int
sta = get_hash(next.a);
dp[i][sta] = min(dp[i][sta], dp[i-1][j] + cnt[i]);
}
}
if
(dp[m][0] == inf) dp[m][0] = -1;
printf
(
"%d\n"
, dp[m][0]);
}
return
0;
}