Problem:
Task Assignment to Two Employees
Hanako is the CEO of a small company with two employees. She currently has some number of tasks and aims to earn some profits by making the employees do the tasks. Employees can enhance their skills through the tasks and, with higher skills, a larger profit can be earned from the same task. Thus, assigning tasks to appropriate employees in an appropriate order is important for maximizing the total profit.
For each pair $(i, j)$ of employee $i$ and task $j$, two non-negative integers $v_{i,j}$ and $s_{i,j}$ are defined. Here, $v_{i,j}$ is the task compatibility and $s_{i,j}$ is the amount of skill growth. When task $j$ has been completed by employee $i$ whose skill point was $p$, a profit of $p \times v_{i,j}$ is earned, and his skill point increases to $p + s_{i,j}$. Initially, both employees have skill points of $p_0$.
Note that the skill points are individual, and completing a task by one employee does not change the skill point of the other. Each task must be done only once by only one employee. The order of tasks to carry out can be arbitrarily chosen.
Input
The input consists of a single test case of the following format.
$n$ $p_0$
$s_{1,1}$ ... $s_{1,n}$
$s_{2,1}$ ... $s_{2,n}$
$v_{1,1}$ ... $v_{1,n}$
$v_{2,1}$ ... $v_{2,n}$
All the input items are non-negative integers. The number of tasks n satisfies $1 \leq n \leq 100$. The initial skill point $p_0$ satisfies $0 \leq p_0 \leq 10^8$. Each $s_{i,j}$ is the amount of skill growth for the employee $i$ by completing the task $j$, which satisfies $0 \leq s_{i,j} \leq 10^6$. Each $v_{i,j}$ is the task compatibility of the employee $i$ with the task $j$, which satisfies $0 \leq v_{i,j} \leq 10^6$.
Output
Output the maximum possible total profit in one line.
Sample Input 1
4 0
10000 1 1 1
1 1 10000 1
1 10000 1 1
1 1 1 10000
Sample Output 1
200000000
Sample Input 2
3 1
1 1 1
2 2 2
2 2 2
1 1 1
Sample Output 2
12

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i, n) for (ll i=0; i<ll(n); i++)
template <class T> using V = vector<T>;
template<class A, class B>
bool chmax(A &a, B b) { return a < b && (a = b, true); }
template<class A, class B>
bool chmin(A &a, B b) { return b < a && (a = b, true); }

template <class C>
struct MaxFlow {
    C flow;
    V<char> dual;
};
template <class C, class E>
struct MFExec {
    static constexpr C INF = numeric_limits<C>::max();
    C eps;
    V<V<E>>& g;
    int s, t;
    V<int> level, iter;
    C dfs(int v, C f) {
        if(v == t) return f;
        C res = 0;
        for(int& i = iter[v]; i < int(g[v].size()); i++) {
            E& e = g[v][i];
            if(e.cap <= eps || level[v] >= level[e.to])
                continue;
            C d = dfs(e.to, min(f, e.cap));
            e.cap -= d;
            g[e.to][e.rev].cap += d;
            res += d;
            f -= d;
            if(f == 0) break;
        }
        return res;
    }
    MaxFlow<C> info;
    MFExec(V<V<E>>& _g, int _s, int _t, C _eps)
        : eps(_eps), g(_g), s(_s), t(_t) {
        int N = int(g.size());
        C& flow = (info.flow = 0);
        while(true) {
            queue<int> que;
            level = V<int>(N, -1);
            level[s] = 0;
            que.push(s);
            while(!que.empty()) {
                int v = que.front();
                que.pop();
                for(E e : g[v]) {
                    if(e.cap <= eps || level[e.to] >= 0) continue;
                    level[e.to] = level[v] + 1;
                    que.push(e.to);
                }
            }
            if(level[t] == -1) break;
            while(true) {
                iter = V<int>(N, 0);
                C f = dfs(s, INF);
                if(!f) break;
                flow += f;
            }
        }
        for(int i = 0;  i< N; i++)
            info.dual.push_back(level[i] == -1);
        }
};
template <class C, class E>
MaxFlow<C> get_mf(V<V<E>>& g, int s, int t, C eps) {
    return MFExec<C, E>(g, s, t, eps).info;
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    int n; ll p0; cin >> n >> p0;
    V<ll> s0(n), s1(n), v0(n), v1(n);
    REP(i, n) cin >> s0[i];
    REP(i, n) cin >> s1[i];
    REP(i, n) cin >> v0[i];
    REP(i, n) cin >> v1[i];
    // 0,0 -> max(s[0][i]*v[0][j], s[0][j]*v[0][i])
    struct E {
        int to, rev; ll cap;
    };
    int nij = n*(n-1);
    V<V<E>> g(nij+n+2);
    int s = nij+n, t = nij+n+1;
    auto add_edge = [&](int from, int to, ll cap) {
        g[from].push_back(E{to, (int)ssize(g[to]), cap});
        g[to].push_back(E{from, (int)ssize(g[from])-1, 0LL});
    };
    int idx = 0;
    ll ans = 0;
    REP(i, n) REP(j, i) {
        {
            int k = idx++;
            ll c = max(s0[i]*v0[j], s0[j]*v0[i]);
            ans += c;
            add_edge(s, k, c);
            add_edge(k, nij+i, INF);
            add_edge(k, nij+j, INF);
        }
        {
            int k = idx++;
            ll c = max(s1[i]*v1[j], s1[j]*v1[i]);
            ans += c;
            add_edge(k, t, c);
            add_edge(nij+i, k, INF);
            add_edge(nij+j, k, INF);
        }
    }
    REP(i, n) {
        {
            ll c = p0*v0[i];
            ans += c;
            add_edge(s, nij+i, c);
        }
        {
            ll c = p0*v1[i];
            ans += c;
            add_edge(nij+i, t, c);
        }
    }
    assert(idx == nij);
    cout << ans - get_mf(g, s, t, 0LL).flow << '\n';
}
accuracy: 1
time_ms: 20
memory_kb: 5120
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pi;
typedef vector<ll> vi;
typedef vector<vi> vvi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define sz(A) (ll)(A.size())
const ll mod=998244353;
ll pow_mod(ll a,ll n){
    ll res=1;a%=mod;
    while(n){
        if(n%2)res=res*a%mod;
        a=a*a%mod;n/=2;
    }
    if(res<0)res+=mod;
    return res;
}
ll inv_mod(ll a){return pow_mod(a,mod-2);}
//Dinic's algorithm O(N^2M)
template<typename T>
struct max_flow{
    struct edge{
        int from,to;
        T cap,flow;
    };
    int N;
    vector<edge>es;
    max_flow(int _N):N(_N){}
    void add_edge(int from,int to,T cap){
        es.emplace_back(edge{from,to,cap,0});
    }
    T flow(int s,int t){
        assert(s!=t);
        T total_flow=0;
        while(1){
            vector<int>level(N,N);
            {
                vector<vector<int>>E(N);
                for(auto e:es){
                    if(e.flow<e.cap)E[e.from].emplace_back(e.to);
                    if(e.flow)E[e.to].emplace_back(e.from);
                }
                level[s]=0;
                queue<int>Q;
                Q.emplace(s);
                while(!Q.empty()){
                    int v=Q.front();Q.pop();
                    for(auto u:E[v])if(level[u]>level[v]+1){
                        level[u]=level[v]+1;
                        Q.emplace(u);
                    }
                }
            }
            if(level[t]==N)return total_flow;
            vector<vector<int>>E(N);
            for(int i=0;i<es.size();i++){
                auto e=es[i];
                if(e.flow<e.cap&&level[e.from]+1==level[e.to])E[e.from].emplace_back(i);
                if(e.flow&&level[e.from]==level[e.to]+1)E[e.to].emplace_back(-i-1);
            }
            vector<int>idx(N);
            iota(idx.begin(),idx.end(),0);
            sort(idx.begin(),idx.end(),[&](int i,int j){return level[i]<level[j];});
            while(1){
                vector<T>dp(N,0);
                vector<int>pre(N);
                dp[s]=numeric_limits<T>::max();
                for(auto v:idx){
                    for(int i:E[v]){
                        if(i>=0){
                            if(dp[es[i].to]<min(dp[v],es[i].cap-es[i].flow)){
                                dp[es[i].to]=min(dp[v],es[i].cap-es[i].flow);
                                pre[es[i].to]=i;
                            }
                        }
                        else if(dp[es[-1-i].from]<min(dp[v],es[-1-i].flow)){
                            dp[es[-1-i].from]=min(dp[v],es[-1-i].flow);
                            pre[es[-1-i].from]=i;
                        }
                    }
                }
                if(!dp[t])break;
                T f=dp[t];
                total_flow+=f;
                int v=t;
                while(v!=s){
                    int i=pre[v];
                    if(i>=0){
                        v=es[i].from;
                        es[i].flow+=f;
                    }
                    else{
                        v=es[-1-i].to;
                        es[-1-i].flow-=f;
                    }
                }
            }
        }
    }
};
int main(){
    ll N,p;cin>>N>>p;
    vvi S(2,vi(N)),V(2,vi(N));
    REP(i,N)cin>>S[0][i];
    REP(i,N)cin>>S[1][i];
    REP(i,N)cin>>V[0][i];
    REP(i,N)cin>>V[1][i];
    max_flow<ll>G(2*N+2);
    ll pad=0;
    vi A(N),B(N);
    REP(j,N)REP(i,j){
        ll a=max(S[0][i]*V[0][j],S[0][j]*V[0][i]);
        ll b=max(S[1][i]*V[1][j],S[1][j]*V[1][i]);
        pad+=a+b;
        A[i]+=a;B[i]+=b;
        G.add_edge(i,j,a);
        G.add_edge(j+N,i+N,a);
        G.add_edge(j,i,b);
        G.add_edge(i+N,j+N,b);
    }
    REP(i,N){
        pad+=p*(V[0][i]+V[1][i]);
        A[i]+=p*V[0][i];
        B[i]+=p*V[1][i];
        ll c=min(A[i],B[i]);
        pad-=c;
        A[i]-=c;B[i]-=c;
        G.add_edge(2*N,i,A[i]);
        G.add_edge(i+N,2*N+1,A[i]);
        G.add_edge(2*N,i+N,B[i]);
        G.add_edge(i,2*N+1,B[i]);
    }
    cout<<pad-G.flow(2*N,2*N+1)/2<<endl;
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 4080
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=300005;
const ll INF=15LL<<58;

// フローのみ

// from: https://gist.github.com/yosupo06/ddd51afb727600fd95d9d8ad6c3c80c9
// (based on AtCoder STL)

#ifndef ATCODER_INTERNAL_QUEUE_HPP
#define ATCODER_INTERNAL_QUEUE_HPP 1
#include <vector>
namespace atcoder {
    namespace internal {
        template <class T> struct simple_queue {
            std::vector<T> payload;
            int pos = 0;
            void reserve(int n) { payload.reserve(n); }
            int size() const { return int(payload.size()) - pos; }
            bool empty() const { return pos == int(payload.size()); }
            void push(const T& t) { payload.push_back(t); }
            T& front() { return payload[pos]; }
            void clear() {
                payload.clear();
                pos = 0;
            }
            void pop() { pos++; }
        };
    }  // namespace internal
}  // namespace atcoder
#endif  // ATCODER_INTERNAL_QUEUE_HPP

#ifndef ATCODER_MAXFLOW_HPP
#define ATCODER_MAXFLOW_HPP 1
#include <algorithm>
#include <cassert>
#include <limits>
#include <queue>
#include <vector>
namespace atcoder {
    template <class Cap> struct mf_graph {
    public:
        mf_graph() : _n(0) {}
        mf_graph(int n) : _n(n), g(n) {}
        int add_edge(int from, int to, Cap cap) {
            assert(0 <= from && from < _n);
            assert(0 <= to && to < _n);
            assert(0 <= cap);
            int m = int(pos.size());
            pos.push_back({from, int(g[from].size())});
            g[from].push_back(_edge{to, int(g[to].size()), cap});
            g[to].push_back(_edge{from, int(g[from].size()) - 1, 0});
            return m;
        }
        struct edge {
            int from, to;
            Cap cap, flow;
        };
        edge get_edge(int i) {
            int m = int(pos.size());
            assert(0 <= i && i < m);
            auto _e = g[pos[i].first][pos[i].second];
            auto _re = g[_e.to][_e.rev];
            return edge{pos[i].first, _e.to, _e.cap + _re.cap, _re.cap};
        }
        std::vector<edge> edges() {
            int m = int(pos.size());
            std::vector<edge> result;
            for (int i = 0; i < m; i++) {
                result.push_back(get_edge(i));
            }
            return result;
        }
        void change_edge(int i, Cap new_cap, Cap new_flow) {
            int m = int(pos.size());
            assert(0 <= i && i < m);
            assert(0 <= new_flow && new_flow <= new_cap);
            auto& _e = g[pos[i].first][pos[i].second];
            auto& _re = g[_e.to][_e.rev];
            _e.cap = new_cap - new_flow;
            _re.cap = new_flow;
        }
        Cap flow(int s, int t) {
            return flow(s, t, std::numeric_limits<Cap>::max());
        }
        Cap flow(int s, int t, Cap flow_limit) {
            assert(0 <= s && s < _n);
            assert(0 <= t && t < _n);
            std::vector<int> level(_n), iter(_n);
            internal::simple_queue<int> que;
            auto bfs = [&]() {
                std::fill(level.begin(), level.end(), -1);
                level[s] = 0;
                que.clear();
                que.push(s);
                while (!que.empty()) {
                    int v = que.front();
                    que.pop();
                    for (auto e : g[v]) {
                        if (e.cap == 0 || level[e.to] >= 0) continue;
                        level[e.to] = level[v] + 1;
                        if (e.to == t) return;
                        que.push(e.to);
                    }
                }
            };
            auto dfs = [&](auto self, int v, Cap up) {
                if (v == s) return up;
                Cap res = 0;
                int level_v = level[v];
                for (int& i = iter[v]; i < int(g[v].size()); i++) {
                    _edge& e = g[v][i];
                    if (level_v <= level[e.to] || g[e.to][e.rev].cap == 0) continue;
                    Cap d =
                    self(self, e.to, std::min(up - res, g[e.to][e.rev].cap));
                    if (d <= 0) continue;
                    g[v][i].cap += d;
                    g[e.to][e.rev].cap -= d;
                    res += d;
                    if (res == up) break;
                }
                return res;
            };
            Cap flow = 0;
            while (flow < flow_limit) {
                bfs();
                if (level[t] == -1) break;
                std::fill(iter.begin(), iter.end(), 0);
                while (flow < flow_limit) {
                    Cap f = dfs(dfs, t, flow_limit - flow);
                    if (!f) break;
                    flow += f;
                }
            }
            return flow;
        }
        std::vector<bool> min_cut(int s) {
            std::vector<bool> visited(_n);
            internal::simple_queue<int> que;
            que.push(s);
            while (!que.empty()) {
                int p = que.front();
                que.pop();
                visited[p] = true;
                for (auto e : g[p]) {
                    if (e.cap && !visited[e.to]) {
                        visited[e.to] = true;
                        que.push(e.to);
                    }
                }
            }
            return visited;
        }
    private:
        int _n;
        struct _edge {
            int to, rev;
            Cap cap;
        };
        std::vector<std::pair<int, int>> pos;
        std::vector<std::vector<_edge>> g;
    };
}  // namespace atcoder
#endif  // ATCODER_MAXFLOW_HPP
#ifndef ATCODER_MINCOSTFLOW_HPP
#define ATCODER_MINCOSTFLOW_HPP 1
#include <algorithm>
#include <cassert>
#include <limits>
#include <queue>
#include <vector>
namespace atcoder {
    template <class Cap, class Cost> struct mcf_graph {
    public:
        mcf_graph() {}
        mcf_graph(int n) : _n(n), g(n) {}
        int add_edge(int from, int to, Cap cap, Cost cost) {
            assert(0 <= from && from < _n);
            assert(0 <= to && to < _n);
            int m = int(pos.size());
            pos.push_back({from, int(g[from].size())});
            g[from].push_back(_edge{to, int(g[to].size()), cap, cost});
            g[to].push_back(_edge{from, int(g[from].size()) - 1, 0, -cost});
            return m;
        }
        struct edge {
            int from, to;
            Cap cap, flow;
            Cost cost;
        };
        edge get_edge(int i) {
            int m = int(pos.size());
            assert(0 <= i && i < m);
            auto _e = g[pos[i].first][pos[i].second];
            auto _re = g[_e.to][_e.rev];
            return edge{
                pos[i].first, _e.to, _e.cap + _re.cap, _re.cap, _e.cost,
            };
        }
        std::vector<edge> edges() {
            int m = int(pos.size());
            std::vector<edge> result(m);
            for (int i = 0; i < m; i++) {
                result[i] = get_edge(i);
            }
            return result;
        }
        std::pair<Cap, Cost> flow(int s, int t) {
            return flow(s, t, std::numeric_limits<Cap>::max());
        }
        std::pair<Cap, Cost> flow(int s, int t, Cap flow_limit) {
            return slope(s, t, flow_limit).back();
        }
        std::vector<std::pair<Cap, Cost>> slope(int s, int t) {
            return slope(s, t, std::numeric_limits<Cap>::max());
        }
        std::vector<std::pair<Cap, Cost>> slope(int s, int t, Cap flow_limit) {
            assert(0 <= s && s < _n);
            assert(0 <= t && t < _n);
            assert(s != t);
            // variants (C = maxcost):
            // -(n-1)C <= dual[s] <= dual[i] <= dual[t] = 0
            // reduced cost (= e.cost + dual[e.from] - dual[e.to]) >= 0 for all edge
            std::vector<Cost> dual(_n, 0), dist(_n);
            std::vector<int> pv(_n), pe(_n);
            std::vector<bool> vis(_n);
            auto dual_ref = [&]() {
                std::fill(dist.begin(), dist.end(),
                          std::numeric_limits<Cost>::max());
                std::fill(pv.begin(), pv.end(), -1);
                std::fill(pe.begin(), pe.end(), -1);
                std::fill(vis.begin(), vis.end(), false);
                struct Q {
                    Cost key;
                    int to;
                    bool operator<(Q r) const { return key > r.key; }
                };
                std::priority_queue<Q> que;
                dist[s] = 0;
                que.push(Q{0, s});
                while (!que.empty()) {
                    int v = que.top().to;
                    que.pop();
                    if (vis[v]) continue;
                    vis[v] = true;
                    if (v == t) break;
                    // dist[v] = shortest(s, v) + dual[s] - dual[v]
                    // dist[v] >= 0 (all reduced cost are positive)
                    // dist[v] <= (n-1)C
                    for (int i = 0; i < int(g[v].size()); i++) {
                        auto e = g[v][i];
                        if (vis[e.to] || !e.cap) continue;
                        // |-dual[e.to] + dual[v]| <= (n-1)C
                        // cost <= C - -(n-1)C + 0 = nC
                        Cost cost = e.cost - dual[e.to] + dual[v];
                        if (dist[e.to] - dist[v] > cost) {
                            dist[e.to] = dist[v] + cost;
                            pv[e.to] = v;
                            pe[e.to] = i;
                            que.push(Q{dist[e.to], e.to});
                        }
                    }
                }
                if (!vis[t]) {
                    return false;
                }
                for (int v = 0; v < _n; v++) {
                    if (!vis[v]) continue;
                    // dual[v] = dual[v] - dist[t] + dist[v]
                    //         = dual[v] - (shortest(s, t) + dual[s] - dual[t]) + (shortest(s, v) + dual[s] - dual[v])
                    //         = - shortest(s, t) + dual[t] + shortest(s, v)
                    //         = shortest(s, v) - shortest(s, t) >= 0 - (n-1)C
                    dual[v] -= dist[t] - dist[v];
                }
                return true;
            };
            Cap flow = 0;
            Cost cost = 0, prev_cost = -1;
            std::vector<std::pair<Cap, Cost>> result;
            result.push_back({flow, cost});
            while (flow < flow_limit) {
                if (!dual_ref()) break;
                Cap c = flow_limit - flow;
                for (int v = t; v != s; v = pv[v]) {
                    c = std::min(c, g[pv[v]][pe[v]].cap);
                }
                for (int v = t; v != s; v = pv[v]) {
                    auto& e = g[pv[v]][pe[v]];
                    e.cap -= c;
                    g[v][e.rev].cap += c;
                }
                Cost d = -dual[s];
                flow += c;
                cost += c * d;
                if (prev_cost == d) {
                    result.pop_back();
                }
                result.push_back({flow, cost});
                prev_cost = d;
            }
            return result;
        }
    private:
        int _n;
        struct _edge {
            int to, rev;
            Cap cap;
            Cost cost;
        };
        std::vector<std::pair<int, int>> pos;
        std::vector<std::vector<_edge>> g;
    };
}  // namespace atcoder
#endif  // ATCODER_MINCOSTFLOW_HPP

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    ll N,P;cin>>N>>P;
    vector<ll> A(N),B(N),C(N),D(N);
    for(int i=0;i<N;i++) cin>>A[i];
    for(int i=0;i<N;i++) cin>>B[i];
    for(int i=0;i<N;i++) cin>>C[i];
    for(int i=0;i<N;i++) cin>>D[i];
    
    ll s=N+N*N*2,t=s+1;
    atcoder::mf_graph<ll> G(s+2);
    
    ll ans=0;
    
    for(int i=0;i<N;i++){
        if(C[i]<=D[i]){
            ans+=P*D[i];
            G.add_edge(i,t,P*(D[i]-C[i]));
        }else{
            ans+=P*C[i];
            G.add_edge(s,i,P*(C[i]-D[i]));
        }
    }
    
    for(int i=0;i<N;i++){
        for(int j=i+1;j<N;j++){
            
            {
                ll K=max(A[i]*C[j],A[j]*C[i]);
                ans+=K;
                int x=N+i*N+j;
                G.add_edge(s,x,K);
                G.add_edge(x,i,INF);
                G.add_edge(x,j,INF);
            }
            
            {
                ll K=max(B[i]*D[j],B[j]*D[i]);
                ans+=K;
                int x=N+N*N+i*N+j;
                G.add_edge(x,t,K);
                G.add_edge(i,x,INF);
                G.add_edge(j,x,INF);
            }
        }
    }
    
    cout<<ans-G.flow(s,t)<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 5460
final_rank: 3

code_snippet: #include<iostream>
#include<vector>
#include<queue>

using namespace std;
using Int = long long;
const Int LINF = 1ll << 61;

struct Edge{
  Int limit, to, rev;
  Edge(Int to, Int limit, Int rev):limit(limit), to(to), rev(rev){

  }   
};

const int S = 10000, T = 10001;
vector<Edge> edges[10002];
const int center = 0, left_offset = 100, right_offset = 100 + (100 * 99) / 2;

void add_edge(int from, int to, Int limit){
  edges[from].push_back(Edge(to, limit, edges[to].size()));
  edges[to].push_back(Edge(from, 0, edges[from].size() - 1));
}

vector<Int> iter(10002);
vector<Int> level(10002);

Int flow(Int s, Int t, Int limit = LINF){
  if(s == t)return limit;
  for(Int &i = iter[s]; i < edges[s].size();i++){
    auto &e = edges[s][i];
    if(level[s] + 1 != level[e.to])continue;
    if(e.limit == 0)continue;
    Int val = flow(e.to, t, min(limit, e.limit));
    if(val == 0)continue;
    e.limit -= val;
    edges[e.to][e.rev].limit += val;
    return val;
  }
  return 0;
}

Int max_flow(Int s, Int t){
  Int ans = 0;
  while(true){
    fill(iter.begin(), iter.end(), 0);
    fill(level.begin(), level.end(), LINF);
    queue<Int> q;
    level[S] = 0;
    q.push(S);
    while(!q.empty()){
      Int from = q.front();q.pop();
      for(auto &e: edges[from]){
	if(e.limit == 0)continue;
	if(level[e.to] == LINF){
	  level[e.to] = level[from] + 1;
	  q.push(e.to);
	}
      }
    }

    if(level[T] == LINF)break;
    
    while(true){
      Int val = flow(s, t);
      if(val == 0)break;
      ans += val;
    }    
  }

  return ans;
  
}


int main(){
  Int n, p0;
  cin >> n >> p0;
  vector<Int> s[2], v[2];
  for(int i = 0;i < 2;i++){
    s[i].resize(n);
    for(int j = 0;j < n;j++){
      cin >> s[i][j];
    }
  }
  for(int i = 0;i < 2;i++){
    v[i].resize(n);
    for(int j = 0;j < n;j++){
      cin >> v[i][j];
    }
  }

  Int ans = 0;

  for(int i = 0;i < n;i++){
    Int lcost = p0 * v[0][i];
    add_edge(S, i, lcost);
    ans += lcost;
    
    Int rcost = p0 * v[1][i];
    add_edge(i, T, rcost);
    ans += rcost;
  }

  Int ind = 0;
  for(int i = 0;i < n;i++){
    for(int j = i+1;j < n;j++){
      Int lind = left_offset + ind;
      Int lcost = max(s[0][i] * v[0][j], s[0][j] * v[0][i]);
      add_edge(S, lind, lcost);
      add_edge(lind, i, LINF);
      add_edge(lind, j, LINF);
      ans += lcost;
      
      Int rind = right_offset + ind;
      Int rcost = max(s[1][i] * v[1][j], s[1][j] * v[1][i]);      
      add_edge(rind, T, rcost);
      add_edge(i,rind, LINF);
      add_edge(j, rind, LINF);
      ans += rcost;
      ind++;
    }
  }
  ans -= max_flow(S, T);
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 5640
final_rank: 4

code_snippet: #include<bits/stdc++.h>
//#include<unistd.h>
#pragma GCC optimize("Ofast")
//#pragma GCC target("avx2")
#pragma GCC optimize("unroll-loops")
using namespace std;
//#include<boost/multiprecision/cpp_int.hpp>
//#include<boost/multiprecision/cpp_dec_float.hpp>
//namespace mp=boost::multiprecision;
//#define mulint mp::cpp_int
//#define mulfloat mp::cpp_dec_float_100
struct __INIT{__INIT(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}} __init;
//#define INF (1<<30)
#define LINF (lint)(1LL<<62)
#define MINF (lint)(2e18)
#define endl "\n"
#define rep(i,n) for(lint (i)=0;(i)<(n);(i)++)
#define reprev(i,n) for(lint (i)=(n-1);(i)>=0;(i)--)
#define flc(x) __builtin_popcountll(x)
#define pint pair<int,int>
#define pdouble pair<double,double>
#define plint pair<lint,lint>
#define fi first
#define se second
#define all(x) x.begin(),x.end()
//#define vec vector<lint>
#define nep(x) next_permutation(all(x))
typedef long long lint;
//int dx[8]={1,1,0,-1,-1,-1,0,1};
//int dy[8]={0,1,1,1,0,-1,-1,-1};
const int MAX_N=3e5+5;
template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return 1;}return 0;}
//vector<int> bucket[MAX_N/1000];
//constexpr int MOD=1000000007;
constexpr int MOD=998244353;
/*#include<atcoder/all>
using namespace atcoder;
typedef __int128_t llint;*/

template< typename flow_t >
struct Dinic {
  const flow_t INF;

  struct edge {
    int to;
    flow_t cap;
    int rev;
    bool isrev;
    int idx;
  };

  vector< vector< edge > > graph;
  vector< int > min_cost, iter;

  Dinic(int V) : INF(numeric_limits< flow_t >::max()), graph(V) {}

  void add_edge(int from, int to, flow_t cap, int idx = -1) {
    graph[from].emplace_back((edge) {to, cap, (int) graph[to].size(), false, idx});
    graph[to].emplace_back((edge) {from, 0, (int) graph[from].size() - 1, true, idx});
  }

  bool bfs(int s, int t) {
    min_cost.assign(graph.size(), -1);
    queue< int > que;
    min_cost[s] = 0;
    que.push(s);
    while(!que.empty() && min_cost[t] == -1) {
      int p = que.front();
      que.pop();
      for(auto &e : graph[p]) {
        if(e.cap > 0 && min_cost[e.to] == -1) {
          min_cost[e.to] = min_cost[p] + 1;
          que.push(e.to);
        }
      }
    }
    return min_cost[t] != -1;
  }

  flow_t dfs(int idx, const int t, flow_t flow) {
    if(idx == t) return flow;
    for(int &i = iter[idx]; i < graph[idx].size(); i++) {
      edge &e = graph[idx][i];
      if(e.cap > 0 && min_cost[idx] < min_cost[e.to]) {
        flow_t d = dfs(e.to, t, min(flow, e.cap));
        if(d > 0) {
          e.cap -= d;
          graph[e.to][e.rev].cap += d;
          return d;
        }
      }
    }
    return 0;
  }

  flow_t max_flow(int s, int t) {
    flow_t flow = 0;
    while(bfs(s, t)) {
      iter.assign(graph.size(), 0);
      flow_t f = 0;
      while((f = dfs(s, t, INF)) > 0) flow += f;
    }
    return flow;
  }

  void output() {
    for(int i = 0; i < graph.size(); i++) {
      for(auto &e : graph[i]) {
        if(e.isrev) continue;
        auto &rev_e = graph[e.to][e.rev];
        cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;
      }
    }
  }
};

int main(){
    lint N,P;
    cin >> N >> P;
    lint s[2][N],v[2][N];
    rep(i,2) rep(j,N) cin >> s[i][j];
    rep(i,2) rep(j,N) cin >> v[i][j];
    Dinic<lint> G(50000);
    lint from=49998,to=49999;
    lint add=N;
    lint ans=0;
    rep(i,N){
        ans+=P*v[0][i];
        G.add_edge(from,i,P*v[0][i]);
        ans+=P*v[1][i];
        G.add_edge(i,to,P*v[1][i]);
    }
    rep(i,N) for(int j=i+1;j<N;j++){
        G.add_edge(from,add,max(s[0][i]*v[0][j],s[0][j]*v[0][i]));
        G.add_edge(add,i,1e18);
        G.add_edge(add,j,1e18);
        ans+=max(s[0][i]*v[0][j],s[0][j]*v[0][i]);
        add++;
        G.add_edge(add,to,max(s[1][i]*v[1][j],s[1][j]*v[1][i]));
        G.add_edge(i,add,1e18);
        G.add_edge(j,add,1e18);
        ans+=max(s[1][i]*v[1][j],s[1][j]*v[1][i]);
        add++;
    }
    cout << ans-G.max_flow(from,to) << endl;

}
accuracy: 1
time_ms: 20
memory_kb: 7260
final_rank: 11

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
// #include <atcoder/convolution>
// #include <atcoder/modint>
// #include <atcoder/modint.hpp>
// #include <atcoder/lazysegtree>
// using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
//int dy[4] = {0,1,0,-1};
//int dx[4] = {1,0,-1,0};
// int dx[6] = {0,1,0,-1,-1,1};
// int dy[6] = {1,0,-1,-1,0,1};
const double pi = acos(-1);
const double eps = 1e-8;
//const int mod = 1e9 + 7;
const int mod = 998244353;

struct Dinic{
    struct edge{
        ll to, cap, rev;
    };
    vector<vector<edge>> G;
    vector<int> level, itr;
    ll n;
    const ll INF = 1<<30;
 
    Dinic(ll n) : n(n){
        G.resize(n);
        level.resize(n);
        itr.resize(n);
    }
 
    void add_edge(ll from, ll to, ll cap){
        G[from].push_back({to,cap,(ll)G[to].size()});
        G[to].push_back({from,0,(ll)G[from].size()-1});
    }
 
    void bfs(int s){
        fill(level.begin(), level.end(), -1);
        queue<int> q;
        level[s] = 0;
        q.push(s);
        while(!q.empty()){
            int u = q.front(); q.pop();
            for(auto &e : G[u]){
                if(e.cap > 0 && level[e.to] < 0){
                    level[e.to] = level[u] + 1;
                    q.push(e.to);
                }
            }
        }
    }

    ll dfs(int u, int t, ll f){
        if(u == t) return f;
        for(int &i = itr[u]; i < G[u].size(); i++){
            edge &e = G[u][i];
            if(e.cap > 0 && level[u] < level[e.to]){
                ll d = dfs(e.to, t, min(f, e.cap));
                if(d > 0){
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
 
    ll max_flow(ll s, ll t){
        ll flow = 0;
        while(1){
            bfs(s);
            if(level[t] < 0) return flow;
            fill(itr.begin(), itr.end(), 0);
            ll f;
            while((f = dfs(s, t, INF)) > 0){
                flow += f;
            }
        }
    }
};

int main(){
    int n,p0; cin >> n >> p0;
    vvl s(2,vl(n)), v(2,vl(n));
    rep(i,2) rep(j,n) cin >> s[i][j];
    rep(i,2) rep(j,n) cin >> v[i][j];

    vector<tapu> a(n),b(n);
    rep(i,n){
        a[i] = {s[0][i], v[0][i], i};
        b[i] = {s[1][i], v[1][i], i};
    }
    //sort(all(a), [](tapu x, tapu y){return get<0>(x)*get<1>(y) > get<1>(x)*get<0>(y);});
    //sort(all(b), [](tapu x, tapu y){return get<0>(x)*get<1>(y) > get<1>(x)*get<0>(y);});

    Dinic g(n+2);
    int S = n;
    int T = S + 1;
    ll ans = 0;
    rep(i,n){
        auto [si,vi,id] = a[i];
        ans += vi * p0;
        g.add_edge(S,id,vi*p0);

        rep(j,i){
            auto [sj,vj,idj] = a[j];
            ll z = max(vi*sj, vj*si);
            ans += z;
            g.add_edge(S,id,z);
            g.add_edge(id,idj,z);
        }
    }

    rep(i,n){
        auto [si,vi,id] = b[i];
        ans += vi * p0;
        g.add_edge(id,T,vi*p0);

        rep(j,i){
            auto [sj,vj,idj] = b[j];
            ll z = max(vi*sj, vj*si);
            ans += z;
            g.add_edge(idj,T,z);
            g.add_edge(id,idj,z);
        }
    }

    ll res = g.max_flow(S,T);
    ans -= res;
    cout << ans << endl;
}
accuracy: 1
time_ms: 110
memory_kb: 4708
final_rank: 10

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
// #include <atcoder/convolution>
// #include <atcoder/modint>
// #include <atcoder/modint.hpp>
// #include <atcoder/lazysegtree>
// using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
//int dy[4] = {0,1,0,-1};
//int dx[4] = {1,0,-1,0};
// int dx[6] = {0,1,0,-1,-1,1};
// int dy[6] = {1,0,-1,-1,0,1};
const double pi = acos(-1);
const double eps = 1e-8;
//const int mod = 1e9 + 7;
const int mod = 998244353;

struct Dinic{
    struct edge{
        ll to, cap, rev;
    };
    vector<vector<edge>> G;
    vector<int> level, itr;
    ll n;
    const ll INF = 1<<30;
 
    Dinic(ll n) : n(n){
        G.resize(n);
        level.resize(n);
        itr.resize(n);
    }
 
    void add_edge(ll from, ll to, ll cap){
        G[from].push_back({to,cap,(ll)G[to].size()});
        G[to].push_back({from,0,(ll)G[from].size()-1});
    }
 
    void bfs(int s){
        fill(level.begin(), level.end(), -1);
        queue<int> q;
        level[s] = 0;
        q.push(s);
        while(!q.empty()){
            int u = q.front(); q.pop();
            for(auto &e : G[u]){
                if(e.cap > 0 && level[e.to] < 0){
                    level[e.to] = level[u] + 1;
                    q.push(e.to);
                }
            }
        }
    }

    ll dfs(int u, int t, ll f){
        if(u == t) return f;
        for(int &i = itr[u]; i < G[u].size(); i++){
            edge &e = G[u][i];
            if(e.cap > 0 && level[u] < level[e.to]){
                ll d = dfs(e.to, t, min(f, e.cap));
                if(d > 0){
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
 
    ll max_flow(ll s, ll t){
        ll flow = 0;
        while(1){
            bfs(s);
            if(level[t] < 0) return flow;
            fill(itr.begin(), itr.end(), 0);
            ll f;
            while((f = dfs(s, t, INF)) > 0){
                flow += f;
            }
        }
    }
};

int main(){
    int n,p0; cin >> n >> p0;
    vvl s(2,vl(n)), v(2,vl(n));
    rep(i,2) rep(j,n) cin >> s[i][j];
    rep(i,2) rep(j,n) cin >> v[i][j];

    vector<tapu> a(n),b(n);
    rep(i,n){
        a[i] = {s[0][i], v[0][i], i};
        b[i] = {s[1][i], v[1][i], i};
    }
    //sort(all(a), [](tapu x, tapu y){return get<0>(x)*get<1>(y) > get<1>(x)*get<0>(y);});
    //sort(all(b), [](tapu x, tapu y){return get<0>(x)*get<1>(y) > get<1>(x)*get<0>(y);});

    Dinic g(n+n*n+2);
    int S = n;
    int T = S + 1;
    int w = T + 1;
    ll ans = 0;
    rep(i,n){
        auto [si,vi,id] = a[i];
        ans += vi * p0;
        g.add_edge(S,id,vi*p0);

        rep(j,i){
            auto [sj,vj,idj] = a[j];
            ll z = max(vi*sj, vj*si);
            ans += z;
            g.add_edge(S,w,z);
            g.add_edge(w,id,linf);
            g.add_edge(w,idj,linf);
            w++;
        }
    }

    rep(i,n){
        auto [si,vi,id] = b[i];
        ans += vi * p0;
        g.add_edge(id,T,vi*p0);

        rep(j,i){
            auto [sj,vj,idj] = b[j];
            ll z = max(vi*sj, vj*si);
            ans += z;
            g.add_edge(w,T,z);
            g.add_edge(id,w,linf);
            g.add_edge(idj,w,linf);
            w++;
        }
    }

    ll res = g.max_flow(S,T);
    ans -= res;
    cout << ans << endl;
}
accuracy: 1
time_ms: 150
memory_kb: 5492
final_rank: 12

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
// #include <atcoder/convolution>
// #include <atcoder/modint>
// #include <atcoder/modint.hpp>
// #include <atcoder/lazysegtree>
// using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
//int dy[4] = {0,1,0,-1};
//int dx[4] = {1,0,-1,0};
// int dx[6] = {0,1,0,-1,-1,1};
// int dy[6] = {1,0,-1,-1,0,1};
const double pi = acos(-1);
const double eps = 1e-8;
//const int mod = 1e9 + 7;
const int mod = 998244353;

struct Dinic{
    struct edge{
        ll to, cap, rev;
    };
    vector<vector<edge>> G;
    vector<int> level, itr;
    ll n;
    const ll INF = 1<<30;
 
    Dinic(ll n) : n(n){
        G.resize(n);
        level.resize(n);
        itr.resize(n);
    }
 
    void add_edge(ll from, ll to, ll cap){
        G[from].push_back({to,cap,(ll)G[to].size()});
        G[to].push_back({from,0,(ll)G[from].size()-1});
    }
 
    void bfs(int s){
        fill(level.begin(), level.end(), -1);
        queue<int> q;
        level[s] = 0;
        q.push(s);
        while(!q.empty()){
            int u = q.front(); q.pop();
            for(auto &e : G[u]){
                if(e.cap > 0 && level[e.to] < 0){
                    level[e.to] = level[u] + 1;
                    q.push(e.to);
                }
            }
        }
    }

    ll dfs(int u, int t, ll f){
        if(u == t) return f;
        for(int &i = itr[u]; i < G[u].size(); i++){
            edge &e = G[u][i];
            if(e.cap > 0 && level[u] < level[e.to]){
                ll d = dfs(e.to, t, min(f, e.cap));
                if(d > 0){
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
 
    ll max_flow(ll s, ll t){
        ll flow = 0;
        while(1){
            bfs(s);
            if(level[t] < 0) return flow;
            fill(itr.begin(), itr.end(), 0);
            ll f;
            while((f = dfs(s, t, INF)) > 0){
                flow += f;
            }
        }
    }
};

int main(){
    int n,p0; cin >> n >> p0;
    vvl s(2,vl(n)), v(2,vl(n));
    rep(i,2) rep(j,n) cin >> s[i][j];
    rep(i,2) rep(j,n) cin >> v[i][j];

    vector<tapu> a(n),b(n);
    rep(i,n){
        a[i] = {s[0][i], v[0][i], i};
        b[i] = {s[1][i], v[1][i], i};
    }
    sort(all(a), [](tapu x, tapu y){return get<0>(x)*get<1>(y) > get<1>(x)*get<0>(y);});
    sort(all(b), [](tapu x, tapu y){return get<0>(x)*get<1>(y) > get<1>(x)*get<0>(y);});

    Dinic g(n+n*n+2);
    int S = n;
    int T = S + 1;
    int w = T + 1;
    ll ans = 0;
    rep(i,n){
        auto [si,vi,id] = a[i];
        ans += vi * p0;
        g.add_edge(S,id,vi*p0);

        rep(j,i){
            auto [sj,vj,idj] = a[j];
            ll z = max(vi*sj, vj*si);
            ans += z;
            g.add_edge(S,w,z);
            g.add_edge(w,id,linf);
            g.add_edge(w,idj,linf);
            w++;
        }
    }

    rep(i,n){
        auto [si,vi,id] = b[i];
        ans += vi * p0;
        g.add_edge(id,T,vi*p0);

        rep(j,i){
            auto [sj,vj,idj] = b[j];
            ll z = max(vi*sj, vj*si);
            ans += z;
            g.add_edge(w,T,z);
            g.add_edge(id,w,linf);
            g.add_edge(idj,w,linf);
            w++;
        }
    }

    ll res = g.max_flow(S,T);
    ans -= res;
    cout << ans << endl;
}
accuracy: 1
time_ms: 150
memory_kb: 5504
final_rank: 13

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
// #include <atcoder/convolution>
// #include <atcoder/modint>
// #include <atcoder/modint.hpp>
// #include <atcoder/lazysegtree>
// using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
//int dy[4] = {0,1,0,-1};
//int dx[4] = {1,0,-1,0};
// int dx[6] = {0,1,0,-1,-1,1};
// int dy[6] = {1,0,-1,-1,0,1};
const double pi = acos(-1);
const double eps = 1e-8;
//const int mod = 1e9 + 7;
const int mod = 998244353;

struct Dinic{
    struct edge{
        ll to, cap, rev;
    };
    vector<vector<edge>> G;
    vector<int> level, itr;
    ll n;
    const ll INF = 1<<30;
 
    Dinic(ll n) : n(n){
        G.resize(n);
        level.resize(n);
        itr.resize(n);
    }
 
    void add_edge(ll from, ll to, ll cap){
        G[from].push_back({to,cap,(ll)G[to].size()});
        G[to].push_back({from,0,(ll)G[from].size()-1});
    }
 
    void bfs(int s){
        fill(level.begin(), level.end(), -1);
        queue<int> q;
        level[s] = 0;
        q.push(s);
        while(!q.empty()){
            int u = q.front(); q.pop();
            for(auto &e : G[u]){
                if(e.cap > 0 && level[e.to] < 0){
                    level[e.to] = level[u] + 1;
                    q.push(e.to);
                }
            }
        }
    }

    ll dfs(int u, int t, ll f){
        if(u == t) return f;
        for(int &i = itr[u]; i < G[u].size(); i++){
            edge &e = G[u][i];
            if(e.cap > 0 && level[u] < level[e.to]){
                ll d = dfs(e.to, t, min(f, e.cap));
                if(d > 0){
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
 
    ll max_flow(ll s, ll t){
        ll flow = 0;
        while(1){
            bfs(s);
            if(level[t] < 0) return flow;
            fill(itr.begin(), itr.end(), 0);
            ll f;
            while((f = dfs(s, t, INF)) > 0){
                flow += f;
            }
        }
    }
};

int main(){
    int n,p0; cin >> n >> p0;
    vvl s(2,vl(n)), v(2,vl(n));
    rep(i,2) rep(j,n) cin >> s[i][j];
    rep(i,2) rep(j,n) cin >> v[i][j];

    vector<tapu> a(n),b(n);
    rep(i,n){
        a[i] = {s[0][i], v[0][i], i};
        b[i] = {s[1][i], v[1][i], i};
    }
    sort(all(a), [](tapu x, tapu y){return get<0>(x)*get<1>(y) > get<1>(x)*get<0>(y);});
    sort(all(b), [](tapu x, tapu y){return get<0>(x)*get<1>(y) > get<1>(x)*get<0>(y);});

    Dinic g(n+n*n+2);
    int S = n;
    int T = S + 1;
    int w = T + 1;
    ll ans = 0;
    rep(i,n){
        auto [si,vi,id] = a[i];
        ans += vi * p0;
        g.add_edge(S,id,vi*p0);

        rep(j,i){
            auto [sj,vj,idj] = a[j];
            ll z = vi * sj;
            ans += z;
            g.add_edge(S,w,z);
            g.add_edge(w,id,linf);
            g.add_edge(w,idj,linf);
            w++;
        }
    }

    rep(i,n){
        auto [si,vi,id] = b[i];
        ans += vi * p0;
        g.add_edge(id,T,vi*p0);

        rep(j,i){
            auto [sj,vj,idj] = b[j];
            ll z = vi * sj;
            ans += z;
            g.add_edge(w,T,z);
            g.add_edge(id,w,linf);
            g.add_edge(idj,w,linf);
            w++;
        }
    }

    ll res = g.max_flow(S,T);
    ans -= res;
    cout << ans << endl;
}
accuracy: 0.3333333333333333
time_ms: 80
memory_kb: 5504
final_rank: 18

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
// #include <atcoder/convolution>
// #include <atcoder/modint>
// #include <atcoder/modint.hpp>
// #include <atcoder/lazysegtree>
// using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
//int dy[4] = {0,1,0,-1};
//int dx[4] = {1,0,-1,0};
// int dx[6] = {0,1,0,-1,-1,1};
// int dy[6] = {1,0,-1,-1,0,1};
const double pi = acos(-1);
const double eps = 1e-8;
//const int mod = 1e9 + 7;
const int mod = 998244353;

struct Dinic{
    struct edge{
        ll to, cap, rev;
    };
    vector<vector<edge>> G;
    vector<int> level, itr;
    ll n;
    const ll INF = 1<<30;
 
    Dinic(ll n) : n(n){
        G.resize(n);
        level.resize(n);
        itr.resize(n);
    }
 
    void add_edge(ll from, ll to, ll cap){
        G[from].push_back({to,cap,(ll)G[to].size()});
        G[to].push_back({from,0,(ll)G[from].size()-1});
    }
 
    void bfs(int s){
        fill(level.begin(), level.end(), -1);
        queue<int> q;
        level[s] = 0;
        q.push(s);
        while(!q.empty()){
            int u = q.front(); q.pop();
            for(auto &e : G[u]){
                if(e.cap > 0 && level[e.to] < 0){
                    level[e.to] = level[u] + 1;
                    q.push(e.to);
                }
            }
        }
    }

    ll dfs(int u, int t, ll f){
        if(u == t) return f;
        for(int &i = itr[u]; i < G[u].size(); i++){
            edge &e = G[u][i];
            if(e.cap > 0 && level[u] < level[e.to]){
                ll d = dfs(e.to, t, min(f, e.cap));
                if(d > 0){
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
 
    ll max_flow(ll s, ll t){
        ll flow = 0;
        while(1){
            bfs(s);
            if(level[t] < 0) return flow;
            fill(itr.begin(), itr.end(), 0);
            ll f;
            while((f = dfs(s, t, INF)) > 0){
                flow += f;
            }
        }
    }
};

int main(){
    int n,p0; cin >> n >> p0;
    vvl s(2,vl(n)), v(2,vl(n));
    rep(i,2) rep(j,n) cin >> s[i][j];
    rep(i,2) rep(j,n) cin >> v[i][j];

    vector<tapu> a(n),b(n);
    rep(i,n){
        a[i] = {s[0][i], v[0][i], i};
        b[i] = {s[1][i], v[1][i], i};
    }
    sort(all(a), [](tapu x, tapu y){return get<0>(x)*get<1>(y) > get<1>(x)*get<0>(y);});
    sort(all(b), [](tapu x, tapu y){return get<0>(x)*get<1>(y) > get<1>(x)*get<0>(y);});

    Dinic g(n+n*n);
    int S = n;
    int T = S + 1;
    int w = T + 1;
    ll ans = 0;
    rep(i,n){
        auto [si,vi,id] = a[i];
        ans += vi * p0;
        g.add_edge(S,id,vi*p0);

        rep(j,i){
            auto [sj,vj,idj] = a[j];
            ll z = vi * sj;
            ans += z;
            g.add_edge(S,w,z);
            g.add_edge(w,id,linf);
            g.add_edge(w,idj,linf);
            w++;
        }
    }

    rep(i,n){
        auto [si,vi,id] = b[i];
        ans += vi * p0;
        g.add_edge(id,T,vi*p0);

        rep(j,i){
            auto [sj,vj,idj] = b[j];
            ll z = vi * sj;
            ans += z;
            g.add_edge(w,T,z);
            g.add_edge(id,w,linf);
            g.add_edge(idj,w,linf);
            w++;
        }
    }

    ll res = g.max_flow(S,T);
    ans -= res;
    cout << ans << endl;
}
accuracy: 0.3333333333333333
time_ms: 80
memory_kb: 5480
final_rank: 17

code_snippet: #include <bits/stdc++.h>

#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <unordered_map>
#include <vector>
using namespace std;
using ll = long long;

template <typename flow_t>
struct Dinic {
    const flow_t INF;

    struct edge {
        int to;
        flow_t cap;
        int rev;
        bool isrev;
        int idx;
    };

    vector<vector<edge>> graph;
    vector<int> min_cost, iter;

    Dinic(int V) : INF(numeric_limits<flow_t>::max()), graph(V) {}

    void add_edge(int from, int to, flow_t cap, int idx = -1) {
        graph[from].emplace_back(
            (edge){to, cap, (int)graph[to].size(), false, idx});
        graph[to].emplace_back(
            (edge){from, 0, (int)graph[from].size() - 1, true, idx});
    }

    bool bfs(int s, int t) {
        min_cost.assign(graph.size(), -1);
        queue<int> que;
        min_cost[s] = 0;
        que.push(s);
        while (!que.empty() && min_cost[t] == -1) {
            int p = que.front();
            que.pop();
            for (auto &e : graph[p]) {
                if (e.cap > 0 && min_cost[e.to] == -1) {
                    min_cost[e.to] = min_cost[p] + 1;
                    que.push(e.to);
                }
            }
        }
        return min_cost[t] != -1;
    }

    flow_t dfs(int idx, const int t, flow_t flow) {
        if (idx == t) return flow;
        for (int &i = iter[idx]; i < graph[idx].size(); i++) {
            edge &e = graph[idx][i];
            if (e.cap > 0 && min_cost[idx] < min_cost[e.to]) {
                flow_t d = dfs(e.to, t, min(flow, e.cap));
                if (d > 0) {
                    e.cap -= d;
                    graph[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    flow_t max_flow(int s, int t) {
        flow_t flow = 0;
        while (bfs(s, t)) {
            iter.assign(graph.size(), 0);
            flow_t f = 0;
            while ((f = dfs(s, t, INF)) > 0) flow += f;
        }
        return flow;
    }

    void output() {
        for (int i = 0; i < graph.size(); i++) {
            for (auto &e : graph[i]) {
                if (e.isrev) continue;
                auto &rev_e = graph[e.to][e.rev];
                cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/"
                     << e.cap + rev_e.cap << ")" << endl;
            }
        }
    }
};

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    ll n, p;
    cin >> n >> p;
    vector<ll> s1(n), s2(n), v1(n), v2(n);
    for (int i = 0; i < n; i++) cin >> s1[i];
    for (int i = 0; i < n; i++) cin >> s2[i];
    for (int i = 0; i < n; i++) cin >> v1[i];
    for (int i = 0; i < n; i++) cin >> v2[i];
    ll ans = 0;
    vector<pair<ll, pair<int, int>>> aa, bb;
    vector<int> i1(n), i2(n);
    for (int i = 0; i < n; i++) i1[i] = i2[i] = i;
    vector<ll> a(n, 0), b(n, 0);
    for (int i = 0; i < n; i++) {
        ans += p * v1[i];
        ans += p * v2[i];
        a[i] += p * v1[i];
        b[i] += p * v2[i];
    }
    sort(i1.begin(), i1.end(),
                [&](int i, int j) { return s1[j] * v1[i] < s1[i] * v1[j]; });
    sort(i2.begin(), i2.end(),
                [&](int i, int j) { return s2[j] * v2[i] < s2[i] * v2[j]; });

    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            int ni = i1[i];
            int nj = i1[j];
            ll mx = s1[ni] * v1[nj];
            ans += mx;
            aa.push_back(make_pair(mx, make_pair(ni, nj)));
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            int ni = i2[i];
            int nj = i2[j];
            ll mx = s2[ni] * v2[nj];
            ans += mx;
            bb.push_back(make_pair(mx, make_pair(ni, nj)));
        }
    }
    int x = aa.size();
    int y = bb.size();
    Dinic<ll> dinic(n + 2 + x + y);
    int st = n + x + y;
    int tt = st + 1;
    for (int i = 0; i < n; i++) {
        dinic.add_edge(st, i, a[i]);
        dinic.add_edge(i, tt, b[i]);
    }
    for (int i = 0; i < x; i++) {
        dinic.add_edge(st, i + n, aa[i].first);
        dinic.add_edge(i + n, aa[i].second.first, 1e18);
        dinic.add_edge(i + n, aa[i].second.second, 1e18);
    }
    for (int i = 0; i < y; i++) {
        dinic.add_edge(i + x + n, tt, bb[i].first);
        dinic.add_edge(bb[i].second.first, i + x + n, 1e18);
        dinic.add_edge(bb[i].second.second, i + x + n, 1e18);
    }
    cout << ans - dinic.max_flow(st, tt) << endl;
}
accuracy: 0.3333333333333333
time_ms: 10
memory_kb: 6264
final_rank: 15

code_snippet: #include <bits/stdc++.h>

#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <unordered_map>
#include <vector>
using namespace std;
using ll = long long;

template <typename flow_t>
struct Dinic {
    const flow_t INF;

    struct edge {
        int to;
        flow_t cap;
        int rev;
        bool isrev;
        int idx;
    };

    vector<vector<edge>> graph;
    vector<int> min_cost, iter;

    Dinic(int V) : INF(numeric_limits<flow_t>::max()), graph(V) {}

    void add_edge(int from, int to, flow_t cap, int idx = -1) {
        graph[from].emplace_back(
            (edge){to, cap, (int)graph[to].size(), false, idx});
        graph[to].emplace_back(
            (edge){from, 0, (int)graph[from].size() - 1, true, idx});
    }

    bool bfs(int s, int t) {
        min_cost.assign(graph.size(), -1);
        queue<int> que;
        min_cost[s] = 0;
        que.push(s);
        while (!que.empty() && min_cost[t] == -1) {
            int p = que.front();
            que.pop();
            for (auto &e : graph[p]) {
                if (e.cap > 0 && min_cost[e.to] == -1) {
                    min_cost[e.to] = min_cost[p] + 1;
                    que.push(e.to);
                }
            }
        }
        return min_cost[t] != -1;
    }

    flow_t dfs(int idx, const int t, flow_t flow) {
        if (idx == t) return flow;
        for (int &i = iter[idx]; i < graph[idx].size(); i++) {
            edge &e = graph[idx][i];
            if (e.cap > 0 && min_cost[idx] < min_cost[e.to]) {
                flow_t d = dfs(e.to, t, min(flow, e.cap));
                if (d > 0) {
                    e.cap -= d;
                    graph[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    flow_t max_flow(int s, int t) {
        flow_t flow = 0;
        while (bfs(s, t)) {
            iter.assign(graph.size(), 0);
            flow_t f = 0;
            while ((f = dfs(s, t, INF)) > 0) flow += f;
        }
        return flow;
    }

    void output() {
        for (int i = 0; i < graph.size(); i++) {
            for (auto &e : graph[i]) {
                if (e.isrev) continue;
                auto &rev_e = graph[e.to][e.rev];
                cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/"
                     << e.cap + rev_e.cap << ")" << endl;
            }
        }
    }
};

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    ll n, p;
    cin >> n >> p;
    vector<ll> s1(n), s2(n), v1(n), v2(n);
    for (int i = 0; i < n; i++) cin >> s1[i];
    for (int i = 0; i < n; i++) cin >> s2[i];
    for (int i = 0; i < n; i++) cin >> v1[i];
    for (int i = 0; i < n; i++) cin >> v2[i];
    ll ans = 0;
    vector<pair<ll, pair<int, int>>> aa, bb;
    vector<int> i1(n), i2(n);
    for (int i = 0; i < n; i++) i1[i] = i2[i] = i;
    vector<ll> a(n, 0), b(n, 0);
    for (int i = 0; i < n; i++) {
        ans += p * v1[i];
        ans += p * v2[i];
        a[i] += p * v1[i];
        b[i] += p * v2[i];
    }
    stable_sort(i1.begin(), i1.end(),
                [&](int i, int j) { return s1[j] * v1[i] < s1[i] * v1[j]; });
    stable_sort(i2.begin(), i2.end(),
                [&](int i, int j) { return s2[j] * v2[i] < s2[i] * v2[j]; });

    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            int ni = i1[i];
            int nj = i1[j];
            ll mx = s1[ni] * v1[nj];
            ans += mx;
            aa.push_back(make_pair(mx, make_pair(ni, nj)));
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            int ni = i2[i];
            int nj = i2[j];
            ll mx = s2[ni] * v2[nj];
            ans += mx;
            bb.push_back(make_pair(mx, make_pair(ni, nj)));
        }
    }
    int x = aa.size();
    int y = bb.size();
    Dinic<ll> dinic(n + 2 + x + y);
    int st = n + x + y;
    int tt = st + 1;
    for (int i = 0; i < n; i++) {
        dinic.add_edge(st, i, a[i]);
        dinic.add_edge(i, tt, b[i]);
    }
    for (int i = 0; i < x; i++) {
        dinic.add_edge(st, i + n, aa[i].first);
        dinic.add_edge(i + n, aa[i].second.first, 1e18);
        dinic.add_edge(i + n, aa[i].second.second, 1e18);
    }
    for (int i = 0; i < y; i++) {
        dinic.add_edge(i + x + n, tt, bb[i].first);
        dinic.add_edge(bb[i].second.first, i + x + n, 1e18);
        dinic.add_edge(bb[i].second.second, i + x + n, 1e18);
    }
    cout << ans - dinic.max_flow(st, tt) << endl;
}
accuracy: 0.24074074074074073
time_ms: 10
memory_kb: 6296
final_rank: 19

code_snippet: #include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<cassert>
#include<set>
#include<queue>
#include<cstdint>
#include<unordered_map>
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

template< typename flow_t >
struct Dinic {
    const flow_t INF;

    struct edge {
        int to;
        flow_t cap;
        int rev;
        bool isrev;
        int idx;
    };

    vector< vector< edge > > graph;
    vector< int > min_cost, iter;

    Dinic(int V) : INF(numeric_limits< flow_t >::max()), graph(V) {}

    void add_edge(int from, int to, flow_t cap, int idx = -1) {
        graph[from].emplace_back((edge) {to, cap, (int) graph[to].size(), false, idx});
        graph[to].emplace_back((edge) {from, 0, (int) graph[from].size() - 1, true, idx});
    }

    bool bfs(int s, int t) {
        min_cost.assign(graph.size(), -1);
        queue< int > que;
        min_cost[s] = 0;
        que.push(s);
        while(!que.empty() && min_cost[t] == -1) {
            int p = que.front();
            que.pop();
            for(auto &e : graph[p]) {
                if(e.cap > 0 && min_cost[e.to] == -1) {
                    min_cost[e.to] = min_cost[p] + 1;
                    que.push(e.to);
                }
            }
        }
        return min_cost[t] != -1;
    }

    flow_t dfs(int idx, const int t, flow_t flow) {
        if(idx == t) return flow;
        for(int &i = iter[idx]; i < graph[idx].size(); i++) {
            edge &e = graph[idx][i];
            if(e.cap > 0 && min_cost[idx] < min_cost[e.to]) {
                flow_t d = dfs(e.to, t, min(flow, e.cap));
                if(d > 0) {
                    e.cap -= d;
                    graph[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    flow_t max_flow(int s, int t) {
        flow_t flow = 0;
        while(bfs(s, t)) {
            iter.assign(graph.size(), 0);
            flow_t f = 0;
            while((f = dfs(s, t, INF)) > 0) flow += f;
        }
        return flow;
    }

    void output() {
        for(int i = 0; i < graph.size(); i++) {
            for(auto &e : graph[i]) {
                if(e.isrev) continue;
                auto &rev_e = graph[e.to][e.rev];
                cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;
            }
        }
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    
    ll n,p;
    cin>>n>>p;
    vector<ll> s1(n),s2(n),v1(n),v2(n);
    for(int i = 0;i<n;i++) cin>>s1[i];
    for(int i = 0;i<n;i++) cin>>s2[i];
    for(int i = 0;i<n;i++) cin>>v1[i];
    for(int i = 0;i<n;i++) cin>>v2[i];
    ll ans = 0;
    vector<pair<ll,pair<int,int>>> aa,bb;
    vector<int> i1(n),i2(n);
    for(int i = 0;i<n;i++) i1[i] = i2[i] = i;
    vector<ll> a(n,0),b(n,0);
    for(int i = 0;i<n;i++){
        ans += p * v1[i];
        ans += p * v2[i];
        a[i] += p * v1[i];
        b[i] += p * v2[i];
    }
    sort(i1.begin(),i1.end(),[&](int i,int j){
        if(s1[i]==0) return false;
        if(s1[j]==0) return true;
        return s1[j] * v1[i] < s1[i] * v1[j];});
    sort(i2.begin(),i2.end(),[&](int i,int j){
        if(s2[i]==0) return false;
        if(s2[j]==0) return true;
        return s2[j] * v2[i] < s2[i] * v2[j];});

    for(int i = 0;i<n;i++){
        for(int j = i + 1;j<n;j++){
            int ni = i1[i];
            int nj = i1[j];
            ll mx = s1[ni] * v1[nj];
            ans += mx;
            aa.push_back(make_pair(mx,make_pair(ni,nj)));
        }
    }
    for(int i = 0;i<n;i++){
        for(int j = i + 1;j<n;j++){
            int ni = i2[i];
            int nj = i2[j];
            ll mx = s2[ni] * v2[nj];
            ans += mx;
            bb.push_back(make_pair(mx,make_pair(ni,nj)));
        }
    }
    int x = aa.size();
    int y = bb.size();
    Dinic<ll> dinic(n+2+x+y);
    int st = n + x + y;
    int tt = st + 1;
    for(int i = 0;i<n;i++){
        dinic.add_edge(st,i,a[i]);
        dinic.add_edge(i,tt,b[i]);
    }
    for(int i = 0;i<x;i++){
        dinic.add_edge(st,i+n,aa[i].first);
        dinic.add_edge(i+n,aa[i].second.first,1e18);
        dinic.add_edge(i+n,aa[i].second.second,1e18);
    }
    for(int i = 0;i<y;i++){
        dinic.add_edge(i+x+n,tt,bb[i].first);
        dinic.add_edge(bb[i].second.first,i+x+n,1e18);
        dinic.add_edge(bb[i].second.second,i+x+n,1e18);
    }
    cout<<ans-dinic.max_flow(st,tt)<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 6268
final_rank: 6

code_snippet: #include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<cassert>
#include<set>
#include<queue>
#include<cstdint>
#include<unordered_map>
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

template< typename flow_t >
struct Dinic {
    const flow_t INF;

    struct edge {
        int to;
        flow_t cap;
        int rev;
        bool isrev;
        int idx;
    };

    vector< vector< edge > > graph;
    vector< int > min_cost, iter;

    Dinic(int V) : INF(numeric_limits< flow_t >::max()), graph(V) {}

    void add_edge(int from, int to, flow_t cap, int idx = -1) {
        graph[from].emplace_back((edge) {to, cap, (int) graph[to].size(), false, idx});
        graph[to].emplace_back((edge) {from, 0, (int) graph[from].size() - 1, true, idx});
    }

    bool bfs(int s, int t) {
        min_cost.assign(graph.size(), -1);
        queue< int > que;
        min_cost[s] = 0;
        que.push(s);
        while(!que.empty() && min_cost[t] == -1) {
            int p = que.front();
            que.pop();
            for(auto &e : graph[p]) {
                if(e.cap > 0 && min_cost[e.to] == -1) {
                    min_cost[e.to] = min_cost[p] + 1;
                    que.push(e.to);
                }
            }
        }
        return min_cost[t] != -1;
    }

    flow_t dfs(int idx, const int t, flow_t flow) {
        if(idx == t) return flow;
        for(int &i = iter[idx]; i < graph[idx].size(); i++) {
            edge &e = graph[idx][i];
            if(e.cap > 0 && min_cost[idx] < min_cost[e.to]) {
                flow_t d = dfs(e.to, t, min(flow, e.cap));
                if(d > 0) {
                    e.cap -= d;
                    graph[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    flow_t max_flow(int s, int t) {
        flow_t flow = 0;
        while(bfs(s, t)) {
            iter.assign(graph.size(), 0);
            flow_t f = 0;
            while((f = dfs(s, t, INF)) > 0) flow += f;
        }
        return flow;
    }

    void output() {
        for(int i = 0; i < graph.size(); i++) {
            for(auto &e : graph[i]) {
                if(e.isrev) continue;
                auto &rev_e = graph[e.to][e.rev];
                cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;
            }
        }
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    
    ll n,p;
    cin>>n>>p;
    vector<ll> s1(n),s2(n),v1(n),v2(n);
    for(int i = 0;i<n;i++) cin>>s1[i];
    for(int i = 0;i<n;i++) cin>>s2[i];
    for(int i = 0;i<n;i++) cin>>v1[i];
    for(int i = 0;i<n;i++) cin>>v2[i];
    ll ans = 0;
    vector<pair<ll,pair<int,int>>> aa,bb;
    vector<int> i1(n),i2(n);
    for(int i = 0;i<n;i++) i1[i] = i2[i] = i;
    vector<ll> a(n,0),b(n,0);
    for(int i = 0;i<n;i++){
        ans += p * v1[i];
        ans += p * v2[i];
        a[i] += p * v1[i];
        b[i] += p * v2[i];
    }
    sort(i1.begin(),i1.end(),[&](int i,int j){
        return s1[j] * v1[i] < s1[i] * v1[j];});
    sort(i2.begin(),i2.end(),[&](int i,int j){
        return s2[j] * v2[i] < s2[i] * v2[j];});

    for(int i = 0;i<n;i++){
        for(int j = i + 1;j<n;j++){
            int ni = i1[i];
            int nj = i1[j];
            ll mx = s1[ni] * v1[nj];
            ans += mx;
            aa.push_back(make_pair(mx,make_pair(ni,nj)));
        }
    }
    for(int i = 0;i<n;i++){
        for(int j = i + 1;j<n;j++){
            int ni = i2[i];
            int nj = i2[j];
            ll mx = s2[ni] * v2[nj];
            ans += mx;
            bb.push_back(make_pair(mx,make_pair(ni,nj)));
        }
    }
    int x = aa.size();
    int y = bb.size();
    Dinic<ll> dinic(n+2+x+y);
    int st = n + x + y;
    int tt = st + 1;
    for(int i = 0;i<n;i++){
        dinic.add_edge(st,i,a[i]);
        dinic.add_edge(i,tt,b[i]);
    }
    for(int i = 0;i<x;i++){
        dinic.add_edge(st,i+n,aa[i].first);
        dinic.add_edge(i+n,aa[i].second.first,1e18);
        dinic.add_edge(i+n,aa[i].second.second,1e18);
    }
    for(int i = 0;i<y;i++){
        dinic.add_edge(i+x+n,tt,bb[i].first);
        dinic.add_edge(bb[i].second.first,i+x+n,1e18);
        dinic.add_edge(bb[i].second.second,i+x+n,1e18);
    }
    cout<<ans-dinic.max_flow(st,tt)<<endl;
}
accuracy: 0.3333333333333333
time_ms: 10
memory_kb: 6264
final_rank: 15

code_snippet: #include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<cassert>
#include<set>
#include<queue>
#include<cstdint>
#include<unordered_map>
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

template< typename flow_t >
struct Dinic {
    const flow_t INF;

    struct edge {
        int to;
        flow_t cap;
        int rev;
        bool isrev;
        int idx;
    };

    vector< vector< edge > > graph;
    vector< int > min_cost, iter;

    Dinic(int V) : INF(numeric_limits< flow_t >::max()), graph(V) {}

    void add_edge(int from, int to, flow_t cap, int idx = -1) {
        graph[from].emplace_back((edge) {to, cap, (int) graph[to].size(), false, idx});
        graph[to].emplace_back((edge) {from, 0, (int) graph[from].size() - 1, true, idx});
    }

    bool bfs(int s, int t) {
        min_cost.assign(graph.size(), -1);
        queue< int > que;
        min_cost[s] = 0;
        que.push(s);
        while(!que.empty() && min_cost[t] == -1) {
            int p = que.front();
            que.pop();
            for(auto &e : graph[p]) {
                if(e.cap > 0 && min_cost[e.to] == -1) {
                    min_cost[e.to] = min_cost[p] + 1;
                    que.push(e.to);
                }
            }
        }
        return min_cost[t] != -1;
    }

    flow_t dfs(int idx, const int t, flow_t flow) {
        if(idx == t) return flow;
        for(int &i = iter[idx]; i < graph[idx].size(); i++) {
            edge &e = graph[idx][i];
            if(e.cap > 0 && min_cost[idx] < min_cost[e.to]) {
                flow_t d = dfs(e.to, t, min(flow, e.cap));
                if(d > 0) {
                    e.cap -= d;
                    graph[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    flow_t max_flow(int s, int t) {
        flow_t flow = 0;
        while(bfs(s, t)) {
            iter.assign(graph.size(), 0);
            flow_t f = 0;
            while((f = dfs(s, t, INF)) > 0) flow += f;
        }
        return flow;
    }

    void output() {
        for(int i = 0; i < graph.size(); i++) {
            for(auto &e : graph[i]) {
                if(e.isrev) continue;
                auto &rev_e = graph[e.to][e.rev];
                cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;
            }
        }
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    
    ll n,p;
    cin>>n>>p;
    vector<ll> s1(n),s2(n),v1(n),v2(n);
    for(int i = 0;i<n;i++) cin>>s1[i];
    for(int i = 0;i<n;i++) cin>>s2[i];
    for(int i = 0;i<n;i++) cin>>v1[i];
    for(int i = 0;i<n;i++) cin>>v2[i];
    ll ans = 0;
    vector<pair<ll,pair<int,int>>> aa,bb;
    vector<int> i1(n),i2(n);
    for(int i = 0;i<n;i++) i1[i] = i2[i] = i;
    vector<ll> a(n,0),b(n,0);
    for(int i = 0;i<n;i++){
        ans += p * v1[i];
        ans += p * v2[i];
        a[i] += p * v1[i];
        b[i] += p * v2[i];
    }
    sort(i1.begin(),i1.end(),[&](int i,int j){
        return s1[j] * v1[i] < s1[i] * v1[j];});
    sort(i2.begin(),i2.end(),[&](int i,int j){
        return s2[j] * v2[i] < s2[i] * v2[j];});

    for(int i = 0;i<n;i++){
        for(int j = i + 1;j<n;j++){
            int ni = i1[i];
            int nj = i1[j];
            ll mx = max(s1[ni]*v1[nj],s1[nj]*v1[ni]);
            ans += mx;
            aa.push_back(make_pair(mx,make_pair(ni,nj)));
        }
    }
    for(int i = 0;i<n;i++){
        for(int j = i + 1;j<n;j++){
            int ni = i2[i];
            int nj = i2[j];
            ll mx = max(s2[ni]*v2[nj],s2[nj]*v2[ni]);
            ans += mx;
            bb.push_back(make_pair(mx,make_pair(ni,nj)));
        }
    }
    int x = aa.size();
    int y = bb.size();
    Dinic<ll> dinic(n+2+x+y);
    int st = n + x + y;
    int tt = st + 1;
    for(int i = 0;i<n;i++){
        dinic.add_edge(st,i,a[i]);
        dinic.add_edge(i,tt,b[i]);
    }
    for(int i = 0;i<x;i++){
        dinic.add_edge(st,i+n,aa[i].first);
        dinic.add_edge(i+n,aa[i].second.first,1e18);
        dinic.add_edge(i+n,aa[i].second.second,1e18);
    }
    for(int i = 0;i<y;i++){
        dinic.add_edge(i+x+n,tt,bb[i].first);
        dinic.add_edge(bb[i].second.first,i+x+n,1e18);
        dinic.add_edge(bb[i].second.second,i+x+n,1e18);
    }
    cout<<ans-dinic.max_flow(st,tt)<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 6272
final_rank: 7

code_snippet: #include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<cassert>
#include<set>
#include<queue>
#include<cstdint>
#include<unordered_map>
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

template< typename flow_t >
struct Dinic {
    const flow_t INF;

    struct edge {
        int to;
        flow_t cap;
        int rev;
        bool isrev;
        int idx;
    };

    vector< vector< edge > > graph;
    vector< int > min_cost, iter;

    Dinic(int V) : INF(numeric_limits< flow_t >::max()), graph(V) {}

    void add_edge(int from, int to, flow_t cap, int idx = -1) {
        graph[from].emplace_back((edge) {to, cap, (int) graph[to].size(), false, idx});
        graph[to].emplace_back((edge) {from, 0, (int) graph[from].size() - 1, true, idx});
    }

    bool bfs(int s, int t) {
        min_cost.assign(graph.size(), -1);
        queue< int > que;
        min_cost[s] = 0;
        que.push(s);
        while(!que.empty() && min_cost[t] == -1) {
            int p = que.front();
            que.pop();
            for(auto &e : graph[p]) {
                if(e.cap > 0 && min_cost[e.to] == -1) {
                    min_cost[e.to] = min_cost[p] + 1;
                    que.push(e.to);
                }
            }
        }
        return min_cost[t] != -1;
    }

    flow_t dfs(int idx, const int t, flow_t flow) {
        if(idx == t) return flow;
        for(int &i = iter[idx]; i < graph[idx].size(); i++) {
            edge &e = graph[idx][i];
            if(e.cap > 0 && min_cost[idx] < min_cost[e.to]) {
                flow_t d = dfs(e.to, t, min(flow, e.cap));
                if(d > 0) {
                    e.cap -= d;
                    graph[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    flow_t max_flow(int s, int t) {
        flow_t flow = 0;
        while(bfs(s, t)) {
            iter.assign(graph.size(), 0);
            flow_t f = 0;
            while((f = dfs(s, t, INF)) > 0) flow += f;
        }
        return flow;
    }

    void output() {
        for(int i = 0; i < graph.size(); i++) {
            for(auto &e : graph[i]) {
                if(e.isrev) continue;
                auto &rev_e = graph[e.to][e.rev];
                cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;
            }
        }
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    
    ll n,p;
    cin>>n>>p;
    vector<ll> s1(n),s2(n),v1(n),v2(n);
    for(int i = 0;i<n;i++) cin>>s1[i];
    for(int i = 0;i<n;i++) cin>>s2[i];
    for(int i = 0;i<n;i++) cin>>v1[i];
    for(int i = 0;i<n;i++) cin>>v2[i];
    ll ans = 0;
    vector<pair<ll,pair<int,int>>> aa,bb;
    vector<int> i1(n),i2(n);
    for(int i = 0;i<n;i++) i1[i] = i2[i] = i;
    vector<ll> a(n,0),b(n,0);
    for(int i = 0;i<n;i++){
        ans += p * v1[i];
        ans += p * v2[i];
        a[i] += p * v1[i];
        b[i] += p * v2[i];
    }
    sort(i1.begin(),i1.end(),[&](int i,int j){
        return s1[j] * v1[i] < s1[i] * v1[j];});
    sort(i2.begin(),i2.end(),[&](int i,int j){
        return s2[j] * v2[i] < s2[i] * v2[j];});

    for(int i = 0;i<n;i++){
        for(int j = i + 1;j<n;j++){
            int ni = i;
            int nj = j;
            ll mx = max(s1[ni]*v1[nj],s1[nj]*v1[ni]);
            ans += mx;
            aa.push_back(make_pair(mx,make_pair(ni,nj)));
        }
    }
    for(int i = 0;i<n;i++){
        for(int j = i + 1;j<n;j++){
            int ni = i;
            int nj = j;
            ll mx = max(s2[ni]*v2[nj],s2[nj]*v2[ni]);
            ans += mx;
            bb.push_back(make_pair(mx,make_pair(ni,nj)));
        }
    }
    int x = aa.size();
    int y = bb.size();
    Dinic<ll> dinic(n+2+x+y);
    int st = n + x + y;
    int tt = st + 1;
    for(int i = 0;i<n;i++){
        dinic.add_edge(st,i,a[i]);
        dinic.add_edge(i,tt,b[i]);
    }
    for(int i = 0;i<x;i++){
        dinic.add_edge(st,i+n,aa[i].first);
        dinic.add_edge(i+n,aa[i].second.first,1e18);
        dinic.add_edge(i+n,aa[i].second.second,1e18);
    }
    for(int i = 0;i<y;i++){
        dinic.add_edge(i+x+n,tt,bb[i].first);
        dinic.add_edge(bb[i].second.first,i+x+n,1e18);
        dinic.add_edge(bb[i].second.second,i+x+n,1e18);
    }
    cout<<ans-dinic.max_flow(st,tt)<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 6260
final_rank: 5

code_snippet: #include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<cassert>
#include<set>
#include<queue>
#include<cstdint>
#include<unordered_map>
#include<bits/stdc++.h>
using namespace std;
using ll = long long;

template< typename flow_t >
struct Dinic {
    const flow_t INF;

    struct edge {
        int to;
        flow_t cap;
        int rev;
        bool isrev;
        int idx;
    };

    vector< vector< edge > > graph;
    vector< int > min_cost, iter;

    Dinic(int V) : INF(numeric_limits< flow_t >::max()), graph(V) {}

    void add_edge(int from, int to, flow_t cap, int idx = -1) {
        graph[from].emplace_back((edge) {to, cap, (int) graph[to].size(), false, idx});
        graph[to].emplace_back((edge) {from, 0, (int) graph[from].size() - 1, true, idx});
    }

    bool bfs(int s, int t) {
        min_cost.assign(graph.size(), -1);
        queue< int > que;
        min_cost[s] = 0;
        que.push(s);
        while(!que.empty() && min_cost[t] == -1) {
            int p = que.front();
            que.pop();
            for(auto &e : graph[p]) {
                if(e.cap > 0 && min_cost[e.to] == -1) {
                    min_cost[e.to] = min_cost[p] + 1;
                    que.push(e.to);
                }
            }
        }
        return min_cost[t] != -1;
    }

    flow_t dfs(int idx, const int t, flow_t flow) {
        if(idx == t) return flow;
        for(int &i = iter[idx]; i < graph[idx].size(); i++) {
            edge &e = graph[idx][i];
            if(e.cap > 0 && min_cost[idx] < min_cost[e.to]) {
                flow_t d = dfs(e.to, t, min(flow, e.cap));
                if(d > 0) {
                    e.cap -= d;
                    graph[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    flow_t max_flow(int s, int t) {
        flow_t flow = 0;
        while(bfs(s, t)) {
            iter.assign(graph.size(), 0);
            flow_t f = 0;
            while((f = dfs(s, t, INF)) > 0) flow += f;
        }
        return flow;
    }

    void output() {
        for(int i = 0; i < graph.size(); i++) {
            for(auto &e : graph[i]) {
                if(e.isrev) continue;
                auto &rev_e = graph[e.to][e.rev];
                cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;
            }
        }
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    
    ll n,p;
    cin>>n>>p;
    vector<ll> s1(n),s2(n),v1(n),v2(n);
    for(int i = 0;i<n;i++) cin>>s1[i];
    for(int i = 0;i<n;i++) cin>>s2[i];
    for(int i = 0;i<n;i++) cin>>v1[i];
    for(int i = 0;i<n;i++) cin>>v2[i];
    ll ans = 0;
    vector<pair<ll,pair<int,int>>> aa,bb;
    vector<int> i1(n),i2(n);
    for(int i = 0;i<n;i++) i1[i] = i2[i] = i;
    vector<ll> a(n,0),b(n,0);
    for(int i = 0;i<n;i++){
        ans += p * v1[i];
        ans += p * v2[i];
        a[i] += p * v1[i];
        b[i] += p * v2[i];
    }
    sort(i1.begin(),i1.end(),[&](int i,int j){
        return s1[j] * v1[i] < s1[i] * v1[j];});
    sort(i2.begin(),i2.end(),[&](int i,int j){
        return s2[j] * v2[i] < s2[i] * v2[j];});

    for(int i = 0;i<n;i++){
        for(int j = i + 1;j<n;j++){
            int ni = i1[i];
            int nj = i1[j];
            ans += s1[ni] * v1[nj];
            aa.push_back(make_pair(s1[ni]*v1[nj],make_pair(ni,nj)));
        }
    }
    for(int i = 0;i<n;i++){
        for(int j = i + 1;j<n;j++){
            int ni = i2[i];
            int nj = i2[j];
            ans += s2[ni] * v2[nj];
            bb.push_back(make_pair(s2[ni]*v2[nj],make_pair(ni,nj)));
        }
    }
    int x = aa.size();
    int y = bb.size();
    Dinic<ll> dinic(n+2+x+y);
    int st = n + x + y;
    int tt = st + 1;
    for(int i = 0;i<n;i++){
        dinic.add_edge(st,i,a[i]);
        dinic.add_edge(i,tt,b[i]);
    }
    for(int i = 0;i<x;i++){
        dinic.add_edge(st,i+n,aa[i].first);
        dinic.add_edge(i+n,aa[i].second.first,1e18);
        dinic.add_edge(i+n,aa[i].second.second,1e18);
    }
    for(int i = 0;i<y;i++){
        dinic.add_edge(i+x+n,tt,bb[i].first);
        dinic.add_edge(bb[i].second.first,i+x+n,1e18);
        dinic.add_edge(bb[i].second.second,i+x+n,1e18);
    }
    cout<<ans-dinic.max_flow(st,tt)<<endl;
}
accuracy: 0.3333333333333333
time_ms: 10
memory_kb: 6224
final_rank: 14

code_snippet: #include<iostream>
#include<vector>
#include<queue>
#include<cassert>
using namespace std;
struct edge{
	int to,rev;
	long long cap;
};
int n;
vector<edge>G[202];
int level[202],iter[202];
void add_edge(int from,int to,long long cap)
{
	G[from].push_back({to,(int)G[to].size(),cap});
	G[to].push_back({from,(int)G[from].size()-1,0LL});
}
long long dfs(int u,int t,long long f)
{
	if(u==t)return f;
	for(;iter[u]<G[u].size();iter[u]++)
	{
		edge&e=G[u][iter[u]];
		if(e.cap>0&&level[u]<level[e.to])
		{
			long long d=dfs(e.to,t,min(f,e.cap));
			if(d>0)
			{
				e.cap-=d;
				G[e.to][e.rev].cap+=d;
				return d;
			}
		}
	}
	return 0LL;
}
long long max_flow(int s,int t)
{
	long long ret=0;
	for(;;)
	{
		for(int i=0;i<n;i++)level[i]=-1;
		queue<int>P;
		level[s]=0;
		P.push(s);
		while(!P.empty())
		{
			int u=P.front();P.pop();
			for(edge e:G[u])
			{
				if(e.cap>0&&level[e.to]<0)
				{
					level[e.to]=level[u]+1;
					P.push(e.to);
				}
			}
		}
		if(level[t]<0)return ret;
		for(int i=0;i<n;i++)iter[i]=0;
		for(long long f;(f=dfs(s,t,(long long)1e18))>0;)ret+=f;
	}
}
int N;
long long P0;
long long S[2][100],V[2][100];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cin>>N>>P0;
	for(int i=0;i<N;i++)cin>>S[0][i];
	for(int i=0;i<N;i++)cin>>S[1][i];
	for(int i=0;i<N;i++)cin>>V[0][i];
	for(int i=0;i<N;i++)cin>>V[1][i];
	n=N+2;
	int s=N,t=N+1;
	long long ALL=0;
	for(int i=0;i<N;i++)
	{
		ALL+=2*P0*(V[0][i]+V[1][i]);
		add_edge(s,i,2*P0*V[0][i]);
		add_edge(i,t,2*P0*V[1][i]);
		for(int j=0;j<i;j++)
		{
			long long a=max(S[0][i]*V[0][j],S[0][j]*V[0][i]);
			long long b=max(S[1][i]*V[1][j],S[1][j]*V[1][i]);
			ALL+=2*(a+b);
			add_edge(i,j,a+b);
			add_edge(j,i,a+b);
			add_edge(s,i,a);
			add_edge(s,j,a);
			add_edge(i,t,b);
			add_edge(j,t,b);
		}
	}
	cout<<(ALL-max_flow(s,t))/2<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 4284
final_rank: 1

code_snippet: //#define _GLIBCXX_DEBUG

//#pragma GCC target("avx2")
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")

#include<bits/stdc++.h>
using namespace std;


#ifdef LOCAL
#include <debug_print.hpp>
#define OUT(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)
#else
#define OUT(...) (static_cast<void>(0))
#endif

#define endl '\n'
#define lfs cout<<fixed<<setprecision(15)
#define ALL(a)  (a).begin(),(a).end()
#define ALLR(a)  (a).rbegin(),(a).rend()
#define UNIQUE(a) (a).erase(unique((a).begin(),(a).end()),(a).end())
#define spa << " " <<
#define fi first
#define se second
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define EB emplace_back
#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
using ll = long long;
using ld = long double;
const ll MOD1 = 1e9+7;
const ll MOD9 = 998244353;
const ll INF = 1e18;
using P = pair<ll, ll>;
template<typename T> using PQ = priority_queue<T>;
template<typename T> using QP = priority_queue<T,vector<T>,greater<T>>;
template<typename T1, typename T2>bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}
template<typename T1, typename T2>bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}
ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}
void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}
void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}
template<typename T1,typename T2>void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}  
template<typename T1,typename T2,typename T3>void anss(T1 x,T2 y,T3 z){ans(x!=y,x,z);};  
template<typename T>void debug(const T &v,ll h,ll w,string sv=" "){for(ll i=0;i<h;i++){cout<<v[i][0];for(ll j=1;j<w;j++)cout<<sv<<v[i][j];cout<<endl;}};
template<typename T>void debug(const T &v,ll n,string sv=" "){if(n!=0)cout<<v[0];for(ll i=1;i<n;i++)cout<<sv<<v[i];cout<<endl;};
template<typename T>void debug(const vector<T>&v){debug(v,v.size());}
template<typename T>void debug(const vector<vector<T>>&v){for(auto &vv:v)debug(vv,vv.size());}
template<typename T>void debug(stack<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(queue<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(deque<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop_front();}cout<<endl;}
template<typename T>void debug(PQ<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(QP<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(const set<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T>void debug(const multiset<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T,size_t size>void debug(const array<T, size> &a){for(auto z:a)cout<<z<<" ";cout<<endl;}
template<typename T,typename V>void debug(const map<T,V>&v){for(auto z:v)cout<<"["<<z.first<<"]="<<z.second<<",";cout<<endl;}
template<typename T>vector<vector<T>>vec(ll x, ll y, T w){vector<vector<T>>v(x,vector<T>(y,w));return v;}
vector<ll>dx={1,-1,0,0,1,1,-1,-1};vector<ll>dy={0,0,1,-1,1,-1,1,-1};
template<typename T>vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
template<typename... Ts>auto make_v(size_t a,Ts... ts){return vector<decltype(make_v(ts...))>(a,make_v(ts...));}
template<typename T1, typename T2>ostream &operator<<(ostream &os, const pair<T1, T2>&p){return os << "(" << p.first << "," << p.second << ")";}
template<typename T>ostream &operator<<(ostream &os, const vector<T> &v){os<<"[";for(auto &z:v)os << z << ",";os<<"]"; return os;}
template<typename T>void rearrange(vector<int>&ord, vector<T>&v){
  auto tmp = v;
  for(int i=0;i<tmp.size();i++)v[i] = tmp[ord[i]];
}
template<typename Head, typename... Tail>void rearrange(vector<int>&ord,Head&& head, Tail&&... tail){
  rearrange(ord, head);
  rearrange(ord, tail...);
}
template<typename T> vector<int> ascend(const vector<T>&v){
  vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
  sort(ord.begin(),ord.end(),[&](int i,int j){return make_pair(v[i],i)<make_pair(v[j],j);});
  return ord;
}
template<typename T> vector<int> descend(const vector<T>&v){
  vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
  sort(ord.begin(),ord.end(),[&](int i,int j){return make_pair(v[i],-i)>make_pair(v[j],-j);});
  return ord;
}
template<typename T> vector<T> inv_perm(const vector<T>&ord){
  vector<T>inv(ord.size());
  for(int i=0;i<ord.size();i++)inv[ord[i]] = i;
  return inv;
}
ll FLOOR(ll n,ll div){assert(div>0);return n>=0?n/div:(n-div+1)/div;}
ll CEIL(ll n,ll div){assert(div>0);return n>=0?(n+div-1)/div:n/div;}
ll digitsum(ll n){ll ret=0;while(n){ret+=n%10;n/=10;}return ret;}
ll modulo(ll n,ll d){return (n%d+d)%d;};
template<typename T>T min(const vector<T>&v){return *min_element(v.begin(),v.end());}
template<typename T>T max(const vector<T>&v){return *max_element(v.begin(),v.end());}
template<typename T>T acc(const vector<T>&v){return accumulate(v.begin(),v.end(),T(0));};
template<typename T>T reverse(const T &v){return T(v.rbegin(),v.rend());};
//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
int popcount(ll x){return __builtin_popcountll(x);};
int poplow(ll x){return __builtin_ctzll(x);};
int pophigh(ll x){return 63 - __builtin_clzll(x);};
template<typename T>T poll(queue<T> &q){auto ret=q.front();q.pop();return ret;};
template<typename T>T poll(priority_queue<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(QP<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(stack<T> &s){auto ret=s.top();s.pop();return ret;};
ll MULT(ll x,ll y){if(LLONG_MAX/x<=y)return LLONG_MAX;return x*y;}
ll POW2(ll x, ll k){ll ret=1,mul=x;while(k){if(mul==LLONG_MAX)return LLONG_MAX;if(k&1)ret=MULT(ret,mul);mul=MULT(mul,mul);k>>=1;}return ret;}
ll POW(ll x, ll k){ll ret=1;for(int i=0;i<k;i++){if(LLONG_MAX/x<=ret)return LLONG_MAX;ret*=x;}return ret;}
std::ostream &operator<<(std::ostream &dest, __int128_t value) {
  std::ostream::sentry s(dest);
  if (s) {
    __uint128_t tmp = value < 0 ? -value : value;
    char buffer[128];
    char *d = std::end(buffer);
    do {
      --d;
      *d = "0123456789"[tmp % 10];
      tmp /= 10;
    } while (tmp != 0);
    if (value < 0) {
      --d;
      *d = '-';
    }
    int len = std::end(buffer) - d;
    if (dest.rdbuf()->sputn(d, len) != len) {
      dest.setstate(std::ios_base::badbit);
    }
  }
  return dest;
}
namespace converter{
  int dict[500];
  const string lower="abcdefghijklmnopqrstuvwxyz";
  const string upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  const string digit="0123456789";
  const string digit1="123456789";
  void regi_str(const string &t){
    for(int i=0;i<t.size();i++){
      dict[t[i]]=i;
    }
  }
  void regi_int(const string &t){
    for(int i=0;i<t.size();i++){
      dict[i]=t[i];
    }
  }
  vector<int>to_int(const string &s,const string &t){
    regi_str(t);
    vector<int>ret(s.size());
    for(int i=0;i<s.size();i++){
      ret[i]=dict[s[i]];
    }
    return ret;
  }
  vector<int>to_int(const string &s){
    auto t=s;
    sort(t.begin(),t.end());
    t.erase(unique(t.begin(),t.end()),t.end());
    return to_int(s,t);
  }
  
  vector<vector<int>>to_int(const vector<string>&s,const string &t){
    regi_str(t);
    vector<vector<int>>ret(s.size(),vector<int>(s[0].size()));
    for(int i=0;i<s.size();i++){
      for(int j=0;j<s[0].size();j++){
        ret[i][j]=dict[s[i][j]];
      }
    }
    return ret;
  }
  vector<vector<int>>to_int(const vector<string>&s){
    string t;
    for(int i=0;i<s.size();i++){
      t+=s[i];
    }
    sort(t.begin(),t.end());t.erase(unique(t.begin(),t.end()),t.end());
    return to_int(s,t);
  }
  string to_str(const vector<int>&s,const string &t){
    regi_int(t);
    string ret;
    for(auto z:s)ret+=dict[z];
    return ret;
  }
  vector<string> to_str(const vector<vector<int>>&s,const string &t){
    regi_int(t);
    vector<string>ret(s.size());
    for(int i=0;i<s.size();i++){
      for(auto z:s[i])ret[i]+=dict[z];
    }
    return ret;
  }
}
template< typename T = int >
struct edge {
  int to;
  T cost;
  int id;
  edge():to(-1),id(-1){};
  edge(int to, T cost = 1, int id = -1):to(to), cost(cost), id(id){}
  operator int() const { return to; }
};

template<typename T>
using Graph = vector<vector<edge<T>>>;
template<typename T>
Graph<T>revgraph(const Graph<T> &g){
  Graph<T>ret(g.size());
  for(int i=0;i<g.size();i++){
    for(auto e:g[i]){
      int to = e.to;
      e.to = i;
      ret[to].push_back(e);
    }
  }
  return ret;
}
template<typename T>
Graph<T> readGraph(int n,int m,int indexed=1,bool directed=false,bool weighted=false){
  Graph<T> ret(n);
  for(int es = 0; es < m; es++){
    int u,v;
    T w=1;
    cin>>u>>v;u-=indexed,v-=indexed;
    if(weighted)cin>>w;
    ret[u].emplace_back(v,w,es);
    if(!directed)ret[v].emplace_back(u,w,es);
  }
  return ret;
}
template<typename T>
Graph<T> readParent(int n,int indexed=1,bool directed=true){
  Graph<T>ret(n);
  for(int i=1;i<n;i++){
    int p;cin>>p;
    p-=indexed;
    ret[p].emplace_back(i);
    if(!directed)ret[i].emplace_back(p);
  }
  return ret;
}
template< typename flow_t >
struct Dinic {
  const flow_t INF;

  struct edge {
    ll to;
    flow_t cap;
    ll rev;
    bool isrev;
  };

  vector< vector< edge > > graph;
  vector< ll > min_cost, iter;

  Dinic(ll V) : INF(numeric_limits< flow_t >::max()), graph(V) {}

  void add_edge(ll from, ll to, flow_t cap) {
    graph[from].emplace_back((edge) {to, cap, (ll) graph[to].size(), false});
    graph[to].emplace_back((edge) {from, 0, (ll) graph[from].size() - 1, true});
  }

  bool bfs(ll s, ll t) {
    min_cost.assign(graph.size(), -1);
    queue< ll > que;
    min_cost[s] = 0;
    que.push(s);
    while(!que.empty() && min_cost[t] == -1) {
      ll p = que.front();
      que.pop();
      for(auto &e : graph[p]) {
        if(e.cap > 0 && min_cost[e.to] == -1) {
          min_cost[e.to] = min_cost[p] + 1;
          que.push(e.to);
        }
      }
    }
    return min_cost[t] != -1;
  }

  flow_t dfs(ll idx, const ll t, flow_t flow) {
    if(idx == t) return flow;
    for(ll &i = iter[idx]; i < graph[idx].size(); i++) {
      edge &e = graph[idx][i];
      if(e.cap > 0 && min_cost[idx] < min_cost[e.to]) {
        flow_t d = dfs(e.to, t, min(flow, e.cap));
        if(d > 0) {
          e.cap -= d;
          graph[e.to][e.rev].cap += d;
          return d;
        }
      }
    }
    return 0;
  }

  flow_t max_flow(ll s, ll t) {
    flow_t flow = 0;
    while(bfs(s, t)) {
      iter.assign(graph.size(), 0);
      flow_t f = 0;
      while((f = dfs(s, t, INF)) > 0) flow += f;
    }
    return flow;
  }

  void output() {
    for(ll i = 0; i < graph.size(); i++) {
      for(auto &e : graph[i]) {
        if(e.isrev) continue;
        auto &rev_e = graph[e.to][e.rev];
        cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;
      }
    }
  }
  //<(from->to),flow>
  using R=vector<pair<pair<ll,ll>,flow_t>>;
  R restore() {
    R ret;
    for(ll i = 0; i < graph.size(); i++) {
      for(auto &e : graph[i]) {
        if(e.isrev) continue;
        auto &rev_e = graph[e.to][e.rev];
        ret.emplace_back(make_pair(i,e.to),rev_e.cap);
      }
    }
    return ret;
  }
  vector<bool>min_cut(int s){
    vector<bool>used(graph.size());
    queue<int>que;
    que.push(s);
    used[s] = true;
    while(!que.empty()){
      auto v = que.front();
      que.pop();
      for(auto e: graph[v]){
        if(e.cap && !used[e.to]){
          used[e.to] = true;
          que.push(e.to);
        }
      }
    }
    return used;
  }
};
int main(){
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  ll res=0,buf=0;
  bool judge = true;
  ll n,p0;cin>>n>>p0;
  auto s=vec(2,n,0LL);
  auto v=vec(2,n,0LL);
  rep(i,0,2)rep(j,0,n)cin>>s[i][j];
  rep(i,0,2)rep(j,0,n)cin>>v[i][j];
  Dinic<ll>dinic(n+2+2*n*n);
  ll S=n,T=n+1;
  ll ret=0;
  ll idx=T+1;
  rep(i,0,n){
    ret+=p0*(v[0][i]+v[1][i]);
    dinic.add_edge(S,i,p0*v[0][i]);
    dinic.add_edge(i,T,p0*v[1][i]);
    rep(j,i+1,n){
      rep(o,0,2){
        ll mx=max(s[o][i]*v[o][j],s[o][j]*v[o][i]);
        ret+=mx;
        ll k=idx++;
        OUT(i,j,mx);
        if(o==0){
          dinic.add_edge(S,idx,mx);
          dinic.add_edge(idx,i,INF);
          dinic.add_edge(idx,j,INF);
        }
        else{
          dinic.add_edge(idx,T,mx);
          dinic.add_edge(i,idx,INF);
          dinic.add_edge(j,idx,INF);
        }
      }
    }
  }
  cout<<ret-dinic.max_flow(S,T)<<endl;
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 6616
final_rank: 9