#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstring>
#include <functional>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <istream>

#include <map>
#include <math.h>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

namespace asl
{
    typedef long long i64;

#include <stdint.h>

    template <typename T>
    using vec = std::vector<T>;

    class DisjointSet
    {
        bool with_path_compression;

    public:
        std::vector<int> ds;

        DisjointSet(int n, bool with_path_compression = true) : with_path_compression(with_path_compression)
        {
            ds = std::vector<int>(n, -1);
        }

        int root(int a)
        {
            if (ds[a] < 0)
                return a;
            else
            {
                if (with_path_compression)
                    return ds[a] = root(ds[a]);
                else
                    return root(ds[a]);
            }
        }

        bool join(int u, int v)
        {
            u = root(u), v = root(v);

            if (u == v)
            {
                on_equal(u);
                return false;
            }

            if (ds[u] < ds[v])
                std::swap(u, v);

            on_join(u, v);

            ds[v] += ds[u];
            ds[u] = v;

            return true;
        }

        virtual void on_join(int u, int v)
        {
        }

        virtual void on_equal(int u)
        {
        }
    };
} // namespace asl

namespace asl
{

    template <typename T>
    std::vector<std::vector<T>> board(int n, int m, T def)
    {
        return std::vector<std::vector<T>>(n, std::vector<T>(m, def));
    }

    template <typename T>
    std::vector<std::vector<T>> board(int n = 0, int m = 0)
    {
        return std::vector<std::vector<T>>(n, std::vector<T>(m));
    }

} // namespace asl

#include <utility>

#include <tuple>

#include <random>

#define endl '\n'

using namespace std;
using namespace asl;

vec<int> base3(int num)
{
    vec<int> res;
    for (int i = 0; i < 3; ++i)
    {
        res.push_back(num % 3);
        num /= 3;
    }
    return res;
}

bool valid(vec<int> &row)
{
    int p = 0;

    for (int i = 0; i < 3; ++i)
    {
        if (row[i] > p)
            return false;
        if (row[i] == p)
            ++p;
    }

    return true;
}

bool test(int mask, int bit)
{
    return mask >> bit & 1;
}

vec<int> canonic(vec<int> order)
{
    map<int, int> m;
    int p = 0;

    for (int i = 0; i < 3; ++i)
    {
        if (!m.count(order[i]))
            m[order[i]] = p++;
        order[i] = m[order[i]];
    }
    return order;
}

struct state
{
    vec<int> order;
    int mask;

    bool is_end()
    {
        int t = 0;
        for (int x = 0; x < 3; ++x)
            if (test(mask, x))
            {
                ++t;
                for (int y = 0; y < x; ++y)
                    if (order[x] != order[y] && test(mask, y))
                        return false;
            }
        return t > 0;
    }

    bool operator==(const state &s) const
    {
        return order == s.order && mask == s.mask;
    }

} S[100];

int TOTAL;
bool END[100];
bool VALID[100][1 << 5][1 << 3];
int GO[100][1 << 5][1 << 3];

void calc(int state_id, int wall, int person)
{
    state s = S[state_id];
    DisjointSet ds(7);

    for (int x = 0; x < 3; ++x)
        for (int y = 0; y < 3; ++y)
            if (s.order[x] == s.order[y])
                ds.join(x, y);

    for (int i = 0; i < 3; ++i)
        if (wall >> i & 1)
            ds.join(i, i + 3);

    if (wall >> 3 & 1)
        ds.join(3, 4);

    if (wall >> 4 & 1)
        ds.join(4, 5);

    auto tmp = ds;
    for (int i = 0; i < 3; ++i)
        tmp.join(i + 3, 6);

    int r = tmp.root(6);
    for (int i = 0; i < 3; ++i)
        if ((s.mask >> i & 1) && tmp.root(i) != r)
        {
            VALID[state_id][wall][person] = false;
            return;
        }

    vec<bool> per(6);
    for (int i = 0; i < 3; ++i)
    {
        if (s.mask >> i & 1)
            per[ds.root(i)] = true;

        if (person >> i & 1)
            per[ds.root(i + 3)] = true;
    }

    int new_mask = 0;
    vec<int> tmp_ord(3);

    for (int i = 0; i < 3; ++i)
    {
        tmp_ord[i] = ds.root(i + 3);
        if (per[ds.root(i + 3)])
            new_mask |= 1 << i;
    }

    state ns = {canonic(tmp_ord), new_mask};
    int id = -1;

    for (int i = 0; i < TOTAL; ++i)
        if (ns == S[i])
        {
            id = i;
            break;
        }

    assert(id >= 0);
    VALID[state_id][wall][person] = true;
    GO[state_id][wall][person] = id;
}

void pre()
{
    TOTAL = 0;
    for (int i = 0; i < 27; ++i)
    {
        auto row = base3(i);

        if (!valid(row))
            continue;

        for (int mask = 0; mask < 8; ++mask)
        {
            bool good = true;
            for (int x = 0; x < 3 && good; ++x)
                for (int y = 0; y < x && good; ++y)
                    if (row[x] == row[y])
                        good &= test(mask, x) == test(mask, y);

            if (!good)
                continue;

            S[TOTAL] = {row, mask};

            END[TOTAL] = S[TOTAL].is_end();
            TOTAL++;
        }
    }

    int good = 0;
    int bad = 0;

    for (int s = 0; s < TOTAL; ++s)
        for (int wall = 0; wall < (1 << 5); ++wall)
            for (int person = 0; person < (1 << 3); ++person)
            {
                calc(s, wall, person);

                if (VALID[s][wall][person])
                    good++;
                else
                    bad++;
            }
}

void solve()
{
    pre();

    int n, m;
    cin >> n >> m;

    auto a = board<i64>(3, n, 1e18);
    auto b = board<i64>(2, n);

    for (int i = 0; i < 3; ++i)
        for (int j = 1; j < n; ++j)
            cin >> a[i][j];

    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < n; ++j)
            cin >> b[i][j];

    vec<int> people(n);
    int last = -1;

    for (int i = 0; i < m; ++i)
    {
        int x, y;
        cin >> x >> y;
        --x;
        --y;

        people[y] |= 1 << x;
        last = max(last, y);
    }

    auto cost = [&](int p, int wall) {
        i64 r = 0;
        for (int i = 0; i < 3; ++i)
            if (wall >> i & 1)
                r += a[i][p];
        if (wall >> 3 & 1)
            r += b[0][p];
        if (wall >> 4 & 1)
            r += b[1][p];
        return r;
    };

    const i64 inf = 1e18;

    vec<i64> dp(TOTAL, inf);
    vec<i64> memo(1 << 5);
    dp[0] = 0;

    i64 res = inf;

    for (int i = 0; i < n; ++i)
    {
        vec<i64> ndp(TOTAL, inf);
        int p = people[i];

        for (int wall = 0; wall < (1 << 5); ++wall)
            memo[wall] = cost(i, wall);

        for (int s = 0; s < TOTAL; ++s)
            for (int wall = 0; wall < (1 << 5); ++wall)
            {

                if (VALID[s][wall][p])
                {
                    int ns = GO[s][wall][p];
                    ndp[ns] = min(ndp[ns], dp[s] + memo[wall]);
                }
            }

        dp.swap(ndp);

        if (i >= last)
            for (int s = 0; s < TOTAL; ++s)
                if (END[s])
                    res = min(res, dp[s]);
    }

    cout << res << endl;
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int t = 1;

    for (int i = 1; i <= t; ++i)
    {
        solve();
    }

    return 0;
}
