#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rint register int
#define min(a,b) (a<b? a:b)
using namespace std;
struct node{int x,y,z;}a[100];
int f[100][100][100];
int n,K;
inline int read()
{
int w=1,ans=0;
char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') w=-1; ch=getchar();}
while(isdigit(ch)) {ans=(ans<<3)+(ans<<1)+(ch^48); ch=getchar();}
return ans*w;
}
inline bool cmp(node a,node b)
{
return a.y<b.y;
}
inline bool cmp2(node a,node b)
{
return a.x<b.x;
}
int main()
{
//freopen("tree.in","r",stdin);
//freopen("tree.out","w",stdout);
n=read();K=read();
for (int i=1;i<=n;i++) a[i].x=read();//数据
for (int i=1;i<=n;i++) a[i].y=read();//权值
for (int i=1;i<=n;i++) a[i].z=read();//访问频度
sort(a+1,a+n+1,cmp);//按权值排序,离散化
for (int i=1;i<=n;i++) a[i].y=i;//将权值离散化
sort(a+1,a+n+1,cmp2);
for (int i=1;i<=n;i++) a[i].z+=a[i-1].z;//前缀和
memset(f,0x7f,sizeof f);
for (int i=1;i<=n+1;i++)
for (int w=0;w<=n;w++)
f[i][i-1][w]=0;
for (rint w=n;~w;w--)//~w指w非零,区间内所有权值大于w
for (rint i=n;i;i--)
for (rint j=i;j<=n;j++)
for (rint k=i;k<=j;k++)//区间dp枚举根节点位置
{
if (a[k].y>=w)
f[i][j][w]=min(f[i][j][w],f[i][k-1][a[k].y]+f[k+1][j][a[k].y]+a[j].z-a[i-1].z);
//a[j].z-a[i-1].z:当树深加1,把每个访问频度都再加一次
f[i][j][w]=min(f[i][j][w],f[i][k-1][w]+f[k+1][j][w]+a[j].z-a[i-1].z+K);
}
printf("%d",f[1][n][1]);
return 0;
}