// 记忆化搜索 100pts:在深搜基础上添加f数组做标记
// 每次搜索记录结果到f[x] 若f[x] != 负无穷说明已搜过
// #include <bits/stdc++.h>
// using namespace std;
// #define ll long long
// ll n,m,a[101],b[10005],f[10005];
// ll dfs(int x){
// if(x >= n){
// return 0;
// }
// if(f[x] != -0x3f3f3f3f3f3f3f3f) return f[x];
// for(int i=0;i<m;i++){
// f[x] = max(f[x],dfs(x+a[i]) + b[x]);
// }
// return f[x];
// }
// int main()
// {
// cin>>n>>m;
// for(int i=0;i<m;i++) cin>>a[i];
// for(int i=0;i<n;i++) cin>>b[i] , f[i] = -0x3f3f3f3f3f3f3f3f;
// cout<<dfs(0);
// return 0;
// }
//dp[i] 表示离开第i关时的最高得分 初始为b[0]
// 这样不用考虑关卡 > n 的情况
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m,a[105],b[20005],dp[20005],ans=-1e9;
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++) cin>>a[i];
for(int i=0;i<n;i++) cin>>b[i] , dp[i] = -1e9;
dp[0] = b[0];
for(int i=1;i<n;i++){ //求dp数组
for(int j=0;j<m;j++){
int tmp = i - a[j]; //可以从哪来
if(tmp < 0) continue; //小于0说明不存在跳过
dp[i] = max(dp[i],dp[tmp] + b[i]); //第tmp关的最优解 + 当前关的分 找最大值
}
}
for(int i=0;i<n;i++) ans = max(ans,dp[i]);
cout<<ans;
return 0;
}