//#include <bits/stdc++.h>/*
#include <unordered_map>
#include <functional> //greater
#include <algorithm> //sort
#include <iostream>
#include <iterator>
#include <utility> //pair
#include <sstream>
#include <cstring> //memset
#include <complex>
#include <cassert>
#include <random>
#include <cstdio>
#include <string>
#include <vector>
#include <cctype> //isaplha, tolower
#include <deque>
#include <queue>
#include <stack>
#include <array>
#include <cmath> //sqrt, sin
#include <ctime>
#include <list>
#include <map>
#include <set>
//*/

#define int long long
#define uns unsigned
#define ll long long
#define vi vector<int>
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define endl '\n'
using namespace std;

template<class T> ostream &operator<<(ostream &os, const pair<T,T> &p){
	return os<<"("<<p.fi<<","<<p.se<<")";}
template<class T> ostream &operator<<(ostream &os, const pair<const T,T> &p){
	return os<<"("<<p.fi<<","<<p.se<<")";}
template<class T> ostream &operator<<(ostream &os, const array<T,3> &p){
	return os<<"("<<p[0]<<","<<p[1]<<","<<p[2]<<")";}
template<class T> ostream &operator<<(ostream &os, const vector<T> &p){
	for(auto x: p) os<<x<<' '; return os;}
#define dbug(x) cerr<<">>>> "<<#x<<" = "<<x<<endl
#define _ <<", "<<
#define FOR(X,L,R) for(int X=L;X<R;X++)
#define FI(I,X) for(auto I=(X).begin();I!=(X).end();I++)
#define print(X) {cerr<<"{ ";FI(I,X)cerr<<*I<<' ';cerr<<"}"<<endl;}
#define mset(V,X) memset(V,X,sizeof(V))
#define all(X) (X).begin(),(X).end()
#define upperb(V,X) (int)(upper_bound(all(V),(X))-V.begin())
#define lowerb(V,X) (int)(lower_bound(all(V),(X))-V.begin())

const double EPS = 1e-9, PI = acos(-1);
const ll LINF = 0x3f3f3f3f3f3f3f3f, mod = 1e9+7;
const int INF = 0x3f3f3f3f, SZ = 2e5+20;

int n,c;
vector<pii> v;
int res,aux;
double c2,aux2;
void bt(int i){
	if(i == n) return;

	aux2 = 0; c2 = c;
	for(int j=i; j<n && c2; j++){
		if(v[j].fi <= c2){
			c2 -= v[j].fi; aux2 += v[j].se;
		} else {
			aux2 += (v[j].se*c2)/v[j].fi;
			c2 = 0;
		}
	}
	if(aux2 + aux <= res) return;

	if(v[i].fi <= c){
		c -= v[i].fi;
		aux += v[i].se;
		if(aux > res) res = aux;
		bt(i+1);
		aux -= v[i].se;
		c += v[i].fi;
	}
	bt(i+1);
}

int32_t main(){
	ios::sync_with_stdio(false);cin.tie(0);

	cin>>n>>c;
	FOR(i,0,n){
		int x,y; cin>>x>>y;
		v.pb({x,y});
	}

	sort(all(v),[](pii a, pii b){
		return (a.se+0.0)/a.fi > (b.se+0.0)/b.fi;
	});

	bt(0);
	cout<<res<<endl;

	return 0;
}


#include <algorithm>
#include <iostream>
#include <vector>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
using namespace std;
typedef long long ll;

void iostream_init() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.setf(ios::fixed);
    cout.precision(12);
}

class Knapsack {
    struct item {
        ll v, w;
    };

    vector<item> items;
    ll W, lv;

    ll solve_rec(size_t k, ll v, ll w) {
        if (w + items[k].w > W)
            return solve_rec(k + 1, v, w);
        ll cv = v, cw = w;
        for (size_t i = k; i < items.size(); ++i) {
            if (cw + items[i].w <= W) {
                cw += items[i].w;
                cv += items[i].v;
            }
        }
        if (lv < cv)
            lv = cv;
        double fv = v, fw = w;
        for (size_t i = k; i < items.size(); ++i) {
            if (fw + items[i].w <= W) {
                fw += items[i].w;
                fv += items[i].v;
            } else {
                fv += items[i].v * (W - fw) / items[i].w;
                break;
            }
        }
        if (fv - lv < 1 || fv < lv)
            return lv;
        solve_rec(k + 1, v + items[k].v, w + items[k].w);
        return solve_rec(k + 1, v, w);
    }

  public:
    // 価値v, 重みwのアイテムを追加
    void add_item(ll v, ll w) { items.push_back({v, w}); }

    // 重みの合計がW以下になるようにアイテムを選んだときの価値の和の最大値を返す．
    ll solve(ll W_) {
        if (items.empty())
            return 0;
        W = W_;
        sort(items.begin(), items.end(), [](const item &a, const item &b) {
            return a.v * b.w > a.w * b.v;
        });
        lv = 0;
        return solve_rec(0, 0, 0);
    };
};

int main() {
    iostream_init();
    int N, W;
    cin >> N >> W;
    Knapsack dp;
    for (int i = 0; i < N; i++) {
        int w, v;
        cin >> w >> v;
        dp.add_item(v, w);
    }

    cout << dp.solve(W) << endl;
    return 0;
}


#include <bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define rrep(i,n) for(int i = 1; i <= (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int,int>;

ll dp[100005][100005];

const int mod = 1000000007;
int main() {
  int n, W;
  cin >> n >> W;
  vector<int> w(n), v(n);
  rep(i, n){
    cin >> w[i] >> v[i];
  }
  rep(i, n+1){
    rep(j, W+1){
      if(j < w[i]) dp[i+1][j] = dp[i][j];
      else dp[i+1][j] = max(dp[i][j], dp[i][j-w[i]] + v[i]);
    }
  }
  cout << dp[n][W] << endl;
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i=0; i<n; i++)

int main(){
    int n, w;
    cin >> n >> w;
    int W[110], V[110];
    rep(i,n) cin >> W[i] >> V[i];

    int dp[110][100010];
    rep(i,n){
        rep(j,100010){
            dp[i+1][j] = dp[i][j];
            if (j >= W[i]) dp[i+1][j] = max(dp[i][j-W[i]]+V[i], dp[i+1][j]);
        }
    }

    cout << dp[n][w] << endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i=0; i<n; i++)

int main(){
    int n, w;
    cin >> n >> w;
    vector<int> W[110], V[110];
    rep(i,n) cin >> W[i] >> V[i];

    int dp[110][100010];
    rep(i,n){
        rep(j,100010){
            dp[i+1][j] = dp[i][j];
            if (j >= W[i]) dp[i+1][j] = max(dp[i][j-W[i]]+V[i], dp[i+1][j]);
        }
    }

    cout << dp[n][w] << endl;
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<inttypes.h>

typedef int32_t i32;
typedef int64_t i64;

#define MAX(a,b) ((a)>(b)?(a):(b))
#define ALLOC(size,type) ((type*)calloc((size),sizeof(type)))

void run (void) {
  i32 n, w;
  scanf ("%" SCNi32 "%" SCNi32, &n, &w);
  i64 *dp = ALLOC (w + 1, i64);
  while (n--) {
    i32 a, b;
    scanf ("%" SCNi32 "%" SCNi32, &a, &b);
    for (i32 i = w; i >= a; --i) {
      i64 x = dp[i - a] + b;
      dp[i] = MAX (dp[i], x);
    }
  }
  printf ("%" PRIi64 "\n", dp[w]);
}

int main (void) {
  run();
  return 0;
}


#include <stdio.h>
#include <stdlib.h>
#define int long long

int max(int a, int b){
	return a >= b ? a : b;
}

signed main(){
	int N, W, w, v, i, j;
	scanf("%lld%lld", &N, &W);
	int *dp = (int *)malloc(sizeof(int) * (W + 1));
	for(j = 0; j <= W; j++){
		dp[j] = 0;
	}
	for(i = 0; i < N; i++){
		scanf("%lld%lld", &w, &v);
		for(j = W; j >= w; j--){
			dp[j] = max(dp[j], dp[j - w] + v);
		}
	}
	printf("%lld\n", dp[W]);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define NOT_ZERO 1
#define MAX(a,b) (a>b?a:b)
#define MAX3(a,b,c) MAX(a,MAX(b,c))
#define MIN(a,b) (a<b?a:b)
#define MIN3(a,b,c) MIN(a, MIN(b,c))
typedef long long ll;

int main()
{
    int N, W;
    int w[100], v[100];
    int i, j;

    scanf("%d %d",&N,&W);

    ll *dp = (ll*)calloc(W+1, sizeof(ll));  //容量が最大iの時の価値の最大値

    for(i=0; i<N; i++) {
        scanf("%d %d",w+i, v+i);
        for(j=W; j>=w[i]; j--) {
            dp[j] = MAX(dp[j], dp[j-w[i]]+v[i]);
        }
    }
    printf("%lld",dp[W]);

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
long long arr [110000];

int main ()
{
int n,w;
int wi,vi;
cin >>n>>w;
int i,j;
for (i = 1 ;i <= n;i++)
{
cin >>wi>>vi;
for (j = w - wi;j >= 0;j --)
{
arr [j + wi] = max (arr [j + wi] , arr [j] + vi);
}
}
long long t ;
t = 0;
for (i = 0 ; i <= w;i ++)
{
t = max (t , arr [i]);
}
cout <<t<<'\n';

}


#include <stdio.h>
#include <stdlib.h>

void    chmax(long long *left, long long right)
{
        if (*left < right)
        {
                *left = right;
        }
}

int             main(void)
{
        int                     n;
        int                     w_max;
        int                     weight[100];
        int                     value[100];
        long long       answer[100][10001] = {0};
        long long       max = 0;
        int                     i;
        int                     j;

        scanf("%d%d", &n, &w_max);
        for (i = 0; i < n; i++)
        {
                scanf("%d%d", &weight[i], &value[i]);
        }
        for (i = 0; i <= w_max; i++)
        {
                if (i < weight[0])
                        answer[0][i] = 0;
                else
                        answer[0][i] = value[0];
        }
        for (i = 1; i < n; i++)
        {
                for (j = 0; j <= w_max; j++)
                {
                        if (j + weight[i] <= w_max)
                        {
                                chmax(&answer[i][j + weight[i]], answer[i - 1][j] + value[i]);
                        }
                        chmax(&answer[i][j], answer[i - 1][j]);
                }
        }
        for (i = 0; i <= w_max; i++)
        {
                chmax(&max, answer[n - 1][i]);
        }
        printf("%lld\n", max);
        return (0);
}


#include <stdio.h>

int             N;
int             W_MAX;
int             WEIGHT[100];
int             VALUE[100];

void    culc_max(int weight, long long value, int i, long long *max)
{
        if (i == N)
        {
                if (weight <= W_MAX)
                {
                        if (*max < value)
                                *max = value;
                }
                return ;
        }
        culc_max(weight + WEIGHT[i], value + VALUE[i], i + 1, max);
        culc_max(weight, value, i + 1, max);
}

int             main(void)
{
        long long       max = 0;
        int                     i;

        scanf("%d%d", &N, &W_MAX);
        for (i = 0; i < N; i++)
        {
                scanf("%d%d", &WEIGHT[i], &VALUE[i]);
        }
        culc_max(0, 0, 0, &max);
        printf("%lld\n", max);
        return (0);
}


var readline = require('readline');

var knapSack = async function(){
  let n,capacity;

  let val = []
  let weight = [];

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    terminal: false
  });

  async function processLineByLine() {
    const rl1 = readline.createInterface({
      input: process.stdin,
      output: process.stdout,
      terminal: false
    });
    let index = 0;
    for await (const line of rl1) {
      let [one, two] = line.trim().split(" ").map(x => parseInt(x));
      if(!index){
        [n,capacity] = [one,two]
      } else {
        weight.push(one);
        val.push(two);
        // console.log(val);
      }
      index++;
      if(index === n+1){
        return;
      }
    }
  }

  await processLineByLine();

  let mem = [];

  for(let i = 0 ; i <= capacity ; i++){
    mem.push(0);
  }

  for(let i=1;i<= n ; i++){
    for(let j=capacity;j > 0;j--){
      let valWithoutItem = mem[j];
      let valWithItem = 0;
      if(weight[i-1] <= j){
        valWithItem = val[i-1] + mem[j - weight[i-1]];
      }
      mem[j] = Math.max(valWithItem, valWithoutItem);
    }
  }

  console.log(mem[capacity]);
};

knapSack();


"use strict";

function main(input){
  const args = input.trim().split('\n').map(_=>_.split(' ').map(_=>parseInt(_,10)));
  const n = args[0][0];
  const w = args[0][1];
  const items = args.slice(1);

  const dp = Array(w+1).fill(0); // 容量をi使うときの最大価値
  for(let i=0; i<n; i++){
    const weight = items[i][0];
    const value = items[i][1];
    for(let k=w; k>=weight; k--){
      dp[k] = Math.max(dp[k-weight] + value, dp[k]);
    }
  }

  console.log(dp.reduce((acc,cur)=>Math.max(acc,cur)));
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));


const W = [3, 4, 5];
const V = [30, 50, 60];

function knapsack(pos, curr_weight) {
  if (pos == W.length) {
    return 0;
  }

  if (curr_weight - W[pos] >= 0) {

    return Math.max(
      knapsack(pos + 1, curr_weight - W[pos]) + V[pos],
      knapsack(pos + 1, curr_weight)
    );
  } else {
    return knapsack(pos + 1, curr_weight);
  }
}

console.log(knapsack(0, 8));


'use strict'
const lines = require('fs').readFileSync(0, 'utf8').split('\n')
const firstLine = lines[0].split(' ').map(Number)
const N = firstLine[0]
const W = firstLine[1]
var dp = new Array(N + 1);
for(var i = 0; i < N + 1; i++){
  dp[i] = new Array(W + 1).fill(0);
}

for (let i=0;i < N;++i) {
  const vw = lines[i].split(' ')
  for (let w=0; w<=W; ++w) {
    if (w - vw[0] >= 0) {
      dp[i+1][w] = Math.max(dp[i+1][w], dp[i][w-vw[0]] + vw[1])
    }
    dp[i+1][w] = dp[i][w]
  }
}
console.log(dp[N][W])


'use strict'
const lines = require('fs').readFileSync(0, 'utf8').split('\n')
const firstLine = lines[0].split(' ').map(Number)
const N = firstLine[0]
const W = firstLine[1]
var dp = new Array(N + 1);
for(var i = 0; i < N + 1; i++){
  dp[i] = new Array(W + 1).fill(0);
}

for (let i=0;i < N;++i) {
  const vw = lines[i].split(' ')
  for (let w=0; w<=W; ++w) {
    if (w - vw[0] >= 0) {
      dp[i+1][w] = Math.max(dp[i+1][w], dp[i][w-vw[0]] + vw[1])
    }
    dp[i+1][w] = Math.max(dp[i+1][w], dp[i][w])
  }
}
console.log(dp[N][W])


package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

func main() {
	sc := NewScanner(os.Stdin)
	n, maxWeight := sc.Int(), sc.Int()

	weights, values := make([]int, n+1), make([]int, n+1)
	for i := 1; i <= n; i++ {
		weights[i] = sc.Int()
		values[i] = sc.Int()
	}

	m := make([]int, maxWeight+1)

	for i := range weights {
		w, v := weights[i], values[i]

		for j := maxWeight; j >= w; j-- {
			m[j] = Max(m[j], m[j-w]+v)
		}
	}

	fmt.Println(m[maxWeight])
}

// generated by https://github.com/murosan/gollect

func Max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

type Scanner struct{ *bufio.Scanner }

func NewScanner(r io.Reader) *Scanner {
	s := bufio.NewScanner(r)
	s.Split(bufio.ScanWords)
	return &Scanner{Scanner: s}
}

func (s *Scanner) Bytes() []byte { s.Scan(); return s.Scanner.Bytes() }

func (s *Scanner) Int() int { return BytesToInt(s.Bytes()) }

func BytesToInt(b []byte) (n int) {
	var i int
	negative := b[0] == 45
	if negative {
		i++
	}
	for ; i < len(b); i++ {
		n = n*10 + int(b[i]-'0')
	}
	if negative {
		return -n
	}
	return
}


package main

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
)

func main() {
	n, w := readInt(), readInt()
	dp := make([]int, w+1)

	for i := 0; i < n; i++ {
		ww, v := readInt(), readInt()
		for j := w - ww; j >= 0; j-- {
			dp[j+ww] = max(dp[j+ww], dp[j]+v)
		}
	}

	fmt.Println(dp[w])
}

// sort ------------------------------------------------------------

type xxx struct {
	x int
}

type sortArray []xxx

func (s sortArray) Len() int           { return len(s) }
func (s sortArray) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
func (s sortArray) Less(i, j int) bool { return s[i].x < s[j].x }

// -----------------------------------------------------------------

var (
	readString func() string
	readBytes  func() []byte
)

func init() {
	log.SetFlags(log.Lshortfile)
	readString, readBytes = newReadString(os.Stdin)
}

func newReadString(ior io.Reader) (func() string, func() []byte) {
	r := bufio.NewScanner(ior)
	r.Buffer(make([]byte, 1024), int(1e+11))
	r.Split(bufio.ScanWords)

	f1 := func() string {
		if !r.Scan() {
			panic("Scan failed")
		}
		return r.Text()
	}
	f2 := func() []byte {
		if !r.Scan() {
			panic("Scan failed")
		}
		return r.Bytes()
	}
	return f1, f2
}

func readInt() int {
	return int(readInt64())
}

func readInt64() int64 {
	i, err := strconv.ParseInt(readString(), 10, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

func readFloat64() float64 {
	f, err := strconv.ParseFloat(readString(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}

func sum(a []int) int {
	var ret int
	for i := range a {
		ret += a[i]
	}
	return ret
}

func sumFloat64(a []float64) float64 {
	var ret float64
	for i := range a {
		ret += a[i]
	}
	return ret
}

func gcd(m, n int) int {
	for m%n != 0 {
		m, n = n, m%n
	}
	return n
}

func lcm(m, n int) int {
	return m / gcd(m, n) * n
}


package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"math/big"
	"os"
)

var reader *bufio.Reader
var writer *bufio.Writer

var inputFile = flag.String("input", "", "")

func init() {
	flag.Parse()
	var i io.Reader
	if *inputFile != "" {
		i, _ = os.Open(*inputFile)
	} else {
		i = os.Stdin
	}
	reader = bufio.NewReaderSize(i, 1<<20)
	writer = bufio.NewWriterSize(os.Stdout, 1<<20)
}

func println(a ...interface{}) {
	_, _ = fmt.Fprintln(writer, a...)
}

func printf(format string, a ...interface{}) {
	_, _ = fmt.Fprintf(writer, format, a...)
}

func scanf(format string, a ...interface{}) {
	_, _ = fmt.Fscanf(reader, format, a...)
}

func scan(a interface{}) {
	_, _ = fmt.Fscan(reader, a)
}

func NextInt64() int64 {
	var res int64
	scan(&res)
	return res
}

func NextInt() int {
	var res int
	scan(&res)
	return res
}

func NextIntArray(n int) []int {
	res := make([]int, n)
	for i := range res {
		scan(&res[i])
	}
	return res
}

func NextInt64Array(n int) []int64 {
	res := make([]int64, n)
	for i := range res {
		scan(&res[i])
	}
	return res
}

func NextString() string {
	var res string
	scan(&res)
	return res
}

func NextBigInt() *big.Int {
	n := new(big.Int)
	n, _ = n.SetString(NextString(), 10)
	return n
}

func AbsInt64(x int64) int64 {
	if x < 0 {
		return -x
	}
	return x
}

func MinInt64(x, y int64) int64 {
	if x < y {
		return x
	}
	return y
}

func MaxInt64(x, y int64) int64 {
	if x > y {
		return x
	}
	return y
}

func main() {
	defer writer.Flush()

	n := NextInt()
	W := NextInt()

	dp := make([]int64, W + 1)

	for i := 0; i < n; i++ {
		w := NextInt()
		v := NextInt64()

		for j := W; j >= w; j-- {
			dp[j] = MaxInt64(dp[j], dp[j - w] + v)
		}
	}

	answer := int64(0)
	for i := 0; i <= W; i++ {
		answer = MaxInt64(answer, dp[i])
	}
	println(answer)
}


package maihn

import (
	"fmt"
	"math"
)

func main() {
	var n, w int64
	fmt.Scanf("%d%d", &n, &w)
	weight := make([]int64, n)
	values := make([]int64, n)
	for i := 0; i < int(n); i++ {
		fmt.Scanf("%d%d", &weight[i], &values[i])
	}
	ans := maximumPossibleSum(n, w, values, weight)
	fmt.Println(ans)
}

// https://atcoder.jp/contests/dp/tasks/dp_d
func maximumPossibleSum(n int64, w int64, values []int64, weight []int64) int64 {
	dp := make([][]int64, n+1)
	for i := 0; i <= int(n); i++ {
		dp[i] = make([]int64, w+1)
	}
	for i := 1; i <= int(n); i++ {
		for j := 1; j <= int(w); j++ {
			if weight[i-1] > int64(j) {
				dp[i][j] = dp[i-1][j]
			} else {
				dp[i][j] = int64(math.Max(float64(dp[i-1][j]), float64(values[i-1]+dp[i-1][int64(j)-weight[i-1]])))
			}
		}
	}
	return dp[n][w]
}


a


//go:generate echo "https://atcoder.jp/contests/dp/tasks/dp_d"
package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
)

type scanner struct{ *bufio.Scanner }

func newScanner(r io.Reader) *scanner {
	s := bufio.NewScanner(r)
	s.Split(bufio.ScanWords)
	s.Buffer(nil, 100000000)
	return &scanner{s}
}

func (s *scanner) Int() int {
	s.Scan()
	n, _ := strconv.Atoi(s.Text())
	return n
}

func (s *scanner) IntSlice(l int) []int {
	if l == 0 {
		return []int{}
	}
	sl := make([]int, l, l)
	for i := range sl {
		sl[i] = s.Int()
	}
	return sl
}

func chmax(x *int, v int) {
	if *x < v {
		*x = v
	}
}

func solve(N, W int, wvs [][]int) int {
	t := make([][]int, N+1, N+1) // t[item_index][weight]
	for i := range t {
		t[i] = make([]int, W+1, W+1)
	}
	for i, wv := range wvs {
		weight, value := wv[0], wv[1]
		for sumWeight := 0; sumWeight <= W; sumWeight++ {
			if sumWeight-weight >= 0 {
				chmax(&t[i+1][sumWeight], t[i][sumWeight-weight]+value)
			}
			chmax(&t[i+1][sumWeight], t[i][sumWeight])
		}
	}
	return t[N][W]
}

func main() {
	for {

	}
	scan := newScanner(os.Stdin)
	N, W := scan.Int(), scan.Int()
	wvs := make([][]int, N, N)
	for i := 0; i < N; i++ {
		wvs[i] = []int{scan.Int(), scan.Int()}
	}
	fmt.Println(solve(N, W, wvs))
}


WV = $<.read.split.map(&:to_i).each_slice(2).to_a
N,W = WV.shift
WV.sort_by! {|w,v| [w,-v]}
I = {}
WV.each.with_index { |(w,*),i| break if w > W; I[w] ||= i}
I[0] = N
K = I.keys
A = Array.new W+1
A[0] = [0,0]
l = [-1]
A.each_with_index {|(c,b),n|
  if (c||0) <= l[0] then next A[n]=l else l=A[n] end
  K.each_cons(2) {|w,x|
    i,j = I[w],I[x]
    break  if W < w+=n
    m = 1 << j
    next  if m <= (b&(m-1))+(1<<i)
	i += 1  while b[i] > 0
    m = (A[w]||l)[0]
    v = WV[i][1] + c
    A[w] = [v,b+(1<<i)]  if m < v
  }
}
p A[W][0]


WV = $<.read.split.map(&:to_i).each_slice(2).to_a
N,W = WV.shift
WV.sort_by! {|w,v| [w,-v]}
I = {}
WV.each.with_index { |(w,*),i| break if w > W; I[w] ||= i}
I[0] = N
K = I.keys
A = Array.new W+1
A[0] = [0,0]
l = [-1]
A.each_with_index {|(c,b),n|
  (c||0) > l[0] ? l=A[n] : next
  K.each_cons(2) {|w,x|
    i,j = I[w],I[x]
    break  if W < w+=n
    m = 1 << j
    next  if WV[i][1]+c <= l[0] || m <= (b&(m-1))+(1<<i)
	i += 1  while b[i] > 0
    m = (A[w]||l)[0]
    v = WV[i][1] + c
    A[w] = [v,b+(1<<i)]  if m < v
  }
}
p l[0]


N, W = gets.split.map(&:to_i)
d = [[0, 0]]

(0..(N-1)).each do
  w, v = gets.split.map(&:to_i)
  next if w > W

  (0..(d.size - 1)).each do |i|
    d << [d[i][0] + w, d[i][1] + v] if d[i][0] + w <= W
  end

  d.sort!

  idx = 1
  while idx < d.size do
    if d[idx-1][1] >= d[idx][1]
      d.delete_at(idx)
    else
      idx += 1
    end
  end
end

puts d[-1][1]


N, W = gets.split.map(&:to_i)

w = N.times.map { gets.split.map(&:to_i) }

dp = []
dp[0] = [0] * (W + 1)

1.upto(N) do |i|
  dp[i] = (W + 1).times.map { 0 }
  0.upto(W) do |j|
    if j >= w[i - 1][0]
      dp[i][j] = [dp[i - 1][j - w[i - 1][0]] + w[i - 1][1], dp[i - 1][j]].max
    else
      dp[i][j] = dp[i - 1][j]
    end
  end
end

puts dp[N][W]


F =-> {gets.split.map &:to_i}
N,W = F[]
D = Hash.new 0
D[0] = 0
N.times {
	w,v = F[]
	D.keys.each {|i| W >= j=i+w and D[j] < x=D[i]+v and D[j]=x}
}
p D.values.max


n, w = $stdin.readline.chomp.split.map(&:to_i)
dp = Array.new(n + 1) { Hash.new(0) }
dp[0][w] = 0

n.times do |i|
  wi, vi = $stdin.readline.chomp.split.map(&:to_i)
  dp[i].each do |k, v|
    dp[i + 1][k] = [dp[i + 1][k], v].max
    if k - wi >= 0
      dp[i + 1][k - wi] = [dp[i + 1][k - wi], v + vi].max
    end
  end
end
puts dp[n].values.max


// Try Educational DP Contest
// author: Leonardone @ NEETSDKASU

fn main() {
	let mut stdin = String::new();
	std::io::Read::read_to_string(
		&mut std::io::stdin(),
		&mut stdin).unwrap();
	let mut stdin = stdin.split_whitespace();
	let mut get = || stdin.next().unwrap();
	macro_rules! get {
		($t:ty) => (get().parse::<$t>().unwrap());
		() => (get!(i64));
	}

	let n = get!(usize);
	let w = get!(usize);
	let mut dp = vec![0; w + 1];
	for _ in 0..n {
		let wi = get!(usize);
		let vi = get!();
		for j in 0..w-wi+1 {
			let j = w-wi-j;
			dp[j+wi] = std::cmp::max(
				dp[j+wi], dp[j]+vi);
		}
	}
	let ans = dp.iter().max().unwrap();
	println!("{}", ans);
}


use std::io::*;
use std::str::*;
use std::collections::*;

fn main() {
    let N : i32 = read();
    let W : usize = read();
    let mut dp = vec![0 as usize; W + 1];
    for i in 0..N {
        let w : i32 = read();
        let v : usize = read();
        for j in (0..W+1).rev() {
            let pj = j as i32 - w;
            if pj < 0 { break; }
            let pj = pj as usize;
            dp[j] = std::cmp::max(dp[j], dp[pj] + v);
        }
    }
    println!("{}", dp[W]);
}

fn read<T: FromStr>() -> T {
    let cin = stdin();
    let cin = cin.lock();
    let s: String = cin
        .bytes() // Bytes
        .map(|c| c.expect("failed reading char") as char)
        .skip_while(|c| c.is_whitespace()) // c が whitespace である限り skip
        .take_while(|c| !c.is_whitespace()) // c が whitespace でない限り要素を返す
        .collect();
    s.parse().ok().expect("failed parsing")
}


macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut iter = $ s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { let s = { use std :: io :: Read ; let mut s = String :: new ( ) ; std :: io :: stdin ( ) . read_to_string ( & mut s ) . unwrap ( ) ; s } ; let mut iter = s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; }
macro_rules ! input_inner { ( $ iter : expr ) => { } ; ( $ iter : expr , ) => { } ; ( $ iter : expr , mut $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let mut $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , mut $ var : ident $ ( $ r : tt ) * ) => { let mut $ var = $ iter . next ( ) . unwrap ( ) . parse ::< usize > ( ) . unwrap ( ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident $ ( $ r : tt ) * ) => { let $ var = $ iter . next ( ) . unwrap ( ) . parse ::< usize > ( ) . unwrap ( ) ; input_inner ! { $ iter $ ( $ r ) * } } ; }
macro_rules ! read_value { ( $ iter : expr , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ iter , $ t ) ) ,* ) } ; ( $ iter : expr , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ iter , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ iter : expr , chars ) => { read_value ! ( $ iter , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ iter : expr , usize1 ) => { read_value ! ( $ iter , usize ) - 1 } ; ( $ iter : expr , $ t : ty ) => { $ iter . next ( ) . unwrap ( ) . parse ::<$ t > ( ) . unwrap ( ) } ; }
use std::cmp::max;
fn main() {
    input! { n, cap, wv: [(usize, usize); n] };
    let mut dp = vec![0; cap + 2];
    for &(w, v) in &wv {
        for c in (0..(cap + 1)).rev() {
            if c + w <= cap {
                dp[c + w] = max(dp[c + w], dp[c] + v);
            }
        }
    }
    println!("{}", dp.iter().max().unwrap());
}


macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        #[allow(unused_mut)]
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

use std::collections::HashMap;

#[derive(Debug)]
struct Load {
    pub weight: i64,
    pub value: i64,
}

fn main() {
    input! {
        n: i64,
        w: i64,
        _loads: [(i64, i64); n as usize]
    }
    let mut loads = vec![];
    for l in _loads {
        loads.push(Load {
            weight: l.0,
            value: l.1,
        })
    }
    let mut cache = HashMap::new();
    let v = max_value(&loads, &mut cache, n - 1, w);
    println!("{}", v)
}

fn max_value(loads: &Vec<Load>, cache: &mut HashMap<(i64, i64), i64>, k: i64, y: i64) -> i64 {
    if let Some(v) = cache.get(&(k, y)) {
        return *v;
    }

    if k < 0 {
        0
    } else {
        let using = if y - loads[k as usize].weight < 0 {
            0
        } else {
            max_value(loads, cache, k - 1, y - loads[k as usize].weight) + loads[k as usize].value
        };
        let not_using = max_value(loads, cache, k - 1, y);
        let value = i64::max(using, not_using);
        cache.insert((k, y), value);
        value
    }
}


macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        #[allow(unused_mut)]
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

use std::collections::HashMap;

#[derive(Debug)]
struct Load {
    pub weight: i64,
    pub value: i64,
}

fn main() {
    input! {
        n: i64,
        w: i64,
        _loads: [(i64, i64); n as usize]
    }
    let mut loads = vec![];
    for l in _loads {
        loads.push(Load {
            weight: l.0,
            value: l.1,
        })
    }
    let mut cache = HashMap::new();
    let v = max_value(&loads, &mut cache, n - 1, w);
    println!("{}", v)
}

fn max_value(loads: &Vec<Load>, cache: &mut HashMap<(i64, i64), i64>, k: i64, y: i64) -> i64 {
    if let Some(v) = cache.get(&(k, y)) {
        return *v;
    }

    if k < 0 {
        0
    } else if y - loads[k as usize].weight < 0 {
        max_value(loads, cache, k - 1, y)
    } else {
        let value = i64::max(
            max_value(loads, cache, k - 1, y - loads[k as usize].weight) + loads[k as usize].value,
            max_value(loads, cache, k - 1, y),
        );
        cache.insert((k, y), value);
        value
    }
}


macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        #[allow(unused_mut)]
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

use std::collections::HashMap;

#[derive(Debug)]
struct Load {
    pub weight: i64,
    pub value: i64,
}

fn main() {
    input! {
        n: i64,
        w: i64,
        _loads: [(i64, i64); n as usize]
    }
    let mut loads = vec![];
    for l in _loads {
        loads.push(Load {
            weight: l.0,
            value: l.1,
        })
    }
    let mut cache = HashMap::new();
    let v = max_value(&loads, &mut cache, n - 1, w);
    println!("{}", v)
}

fn max_value(loads: &Vec<Load>, cache: &mut HashMap<(i64, i64), i64>, k: i64, y: i64) -> i64 {
    if k < 0 {
        0
    } else if y - loads[k as usize].weight < 0 {
        max_value(loads, cache, k - 1, y)
    } else {
        if let Some(v) = cache.get(&(k, y)) {
            *v
        } else {
            let value = i64::max(
                max_value(loads, cache, k - 1, y - loads[k as usize].weight)
                    + loads[k as usize].value,
                max_value(loads, cache, k - 1, y),
            );
            cache.insert((k, y), value);
            value
        }
    }
}


let input = readLine()!.split(separator: " ").map { Int($0)! }

let N = input[0]
let W = input[1]

var weights: [Int] = .init(repeating: 0, count: N)
var values: [Int] = .init(repeating: 0, count: N)

for i in 0..<N {
  let inp = readLine()!.split(separator: " ").map { Int($0)! }
  weights[i] = inp[0]
  values[i] = inp[1]
}

var dp: [[Int]] = .init(repeating: .init(repeating: 0, count: W + 1), count: N + 1)

for i in 1...N {
  for j in 1...W {
   	let prev = j - weights[i - 1]
    if prev < 0 {
      dp[i][j] = dp[i-1][j]
      continue
    }
    dp[i][j] = max(dp[i-1][prev] + values[i - 1], dp[i-1][j])
  }
}
print(dp[N][W])


import Foundation

func readWords<T>(_ f: (Substring) -> T) -> [T] {
    return readLine()!.split(separator: " ").map(f)
}

func main() {
    let nw = readWords { Int($0)! }
    let n = nw[0]
    let w = nw[1]

    let items: [(w: Int, v: Int)] = (1...n).map { _ in
        let wv = readWords { Int($0)! }
        return (w: wv[0], v: wv[1])
    }
    var dp: [[Int]] = (0...n).map {_ in [Int](repeating: 0, count: w+1) }

    for i in 0..<n {
        for weight in 0...w {
            if items[i].w <= weight {
                dp[i+1][weight] = max(dp[i][weight-items[i].w] + items[i].v, dp[i][weight])
            } else {
                dp[i+1][weight] = dp[i][weight]
            }
        }
    }

    print(dp[n][w])
}

main()


/// Swift5 -> Swift2.2

extension String {
    // split(separator:maxSplits:omittingEmptySubsequences:)
    func split(separator separator: Character) -> [String] {
        return self.characters.split(separator).map(String.init)
    }
}
extension Array {
    // init(repeating:count:)
    init(repeating: Element, count: Int) {
        self.init(count: count, repeatedValue: repeating)
    }
}
extension Array where Element: Comparable {
    // sorted()
    func sorted() -> [Element] {
        return self.sort( { $0 < $1 } )
    }
}
// stride(from:through:by:)
func stride(from start: Int, through end: Int, by stride: Int) -> StrideThrough<Int> {
    return start.stride(through: end, by: stride)
}
// stride(from:to:by)
func stride(from start: Int, to end: Int, by stride: Int) -> StrideTo<Int> {
    return start.stride(to: end, by: stride)
}
extension Range {
    func reversed() -> [Element] {
        return self.reverse()
    }
}

/// end

let input = readLine()!.split(separator: " ").map { Int($0)! }
let N = input[0]
let W = input[1]

var dp = Array(repeating: 0, count: W + 1)

for _ in 0 ..< N {
    let knapsack = readLine()!.split(separator: " ").map { Int($0)! }
    let weight = knapsack[0]
    let value = knapsack[1]

  	var i = W
  	while i >= weight {
        dp[i] = max(dp[i], dp[i - weight] + value)
        i -= 1
    }
}

print(dp.last!)


/// Swift5 -> Swift2.2
extension String {
    // split(separator:maxSplits:omittingEmptySubsequences:)
    func split(separator separator: Character) -> [String] {
        return self.characters.split(separator).map(String.init)
    }
}
extension Array {
    // init(repeating:count:)
    init(repeating: Element, count: Int) {
        self.init(count: count, repeatedValue: repeating)
    }
}
extension Array where Element: Comparable {
    // sorted()
    func sorted() -> [Element] {
        return self.sort( { $0 < $1 } )
    }
}
// stride(from:through:by:)
func stride(from start: Int, through end: Int, by stride: Int) -> StrideThrough<Int> {
    return start.stride(through: end, by: stride)
}
// stride(from:to:by)
func stride(from start: Int, to end: Int, by stride: Int) -> StrideTo<Int> {
    return start.stride(to: end, by: stride)
}
/// end

let input = readLine()!.split(separator: " ").map { Int($0)! }
let N = input[0]
let W = input[1]

var dp = Array(repeating: 0, count: W + 1)

for _ in 0 ..< N {
    let knapsack = readLine()!.split(separator: " ").map { Int($0)! }
    let weight = knapsack[0]
    let value = knapsack[1]

    let tmp = Array((weight ... W).reverse())
    for i in stride(from: W, through: weight, by: -1) {
        dp[i] = max(dp[i], dp[i - weight] + value)
    }
}

print(dp.last!)


/// Swift5 -> Swift2.2

extension String {
    // split(separator:maxSplits:omittingEmptySubsequences:)
    func split(separator separator: Character) -> [String] {
        return self.characters.split(separator).map(String.init)
    }
}
extension Array {
    // init(repeating:count:)
    init(repeating: Element, count: Int) {
        self.init(count: count, repeatedValue: repeating)
    }
}
extension Array where Element: Comparable {
    // sorted()
    func sorted() -> [Element] {
        return self.sort( { $0 < $1 } )
    }
}
// stride(from:through:by:)
func stride(from start: Int, through end: Int, by stride: Int) -> StrideThrough<Int> {
    return start.stride(through: end, by: stride)
}
// stride(from:to:by)
func stride(from start: Int, to end: Int, by stride: Int) -> StrideTo<Int> {
    return start.stride(to: end, by: stride)
}

/// end

let input = readLine()!.split(separator: " ").map { Int($0)! }
let N = input[0]
let W = input[1]

var dp = Array(repeating: 0, count: W + 1)

for _ in 0 ..< N {
    let knapsack = readLine()!.split(separator: " ").map { Int($0)! }
    let weight = knapsack[0]
    let value = knapsack[1]

    for i in (weight ... W).reverse() {
        dp[i] = max(dp[i], dp[i - weight] + value)
    }
}

print(dp.last!)


/// Swift5 -> Swift2.2

extension String {
    // split(separator:maxSplits:omittingEmptySubsequences:)
    func split(separator separator: Character) -> [String] {
        return self.characters.split(separator).map(String.init)
    }
}
extension Array {
    // init(repeating:count:)
    init(repeating: Element, count: Int) {
        self.init(count: count, repeatedValue: repeating)
    }
}
extension Array where Element: Comparable {
    // sorted()
    func sorted() -> [Element] {
        return self.sort( { $0 < $1 } )
    }
}
// stride(from:through:by:)
func stride(from start: Int, through end: Int, by stride: Int) -> StrideThrough<Int> {
    return start.stride(through: end, by: stride)
}
// stride(from:to:by)
func stride(from start: Int, to end: Int, by stride: Int) -> StrideTo<Int> {
    return start.stride(to: end, by: stride)
}
extension Range {
    func reversed() -> [Element] {
        return self.reverse()
    }
}

/// end

let input = readLine()!.split(separator: " ").map { Int($0)! }
let N = input[0]
let W = input[1]

var dp = Array(repeating: 0, count: W + 1)

for _ in 0 ..< N {
    let knapsack = readLine()!.split(separator: " ").map { Int($0)! }
    let weight = knapsack[0]
    let value = knapsack[1]

  	let tmp: [Int] = (weight ... W).reversed()
    for i in stride(from: W, through: weight, by: -1) {
        dp[i] = max(dp[i], dp[i - weight] + value)
    }
}

print(dp.last!)


const lines: string[] = [];
const reader = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
});
reader.on("line", function (line: string) {
  lines.push(line);
});

reader.on("close", function () {
  const rule = lines.shift().split(" ").map(Number);
  const itemNum = rule[0];
  const weightMax = rule[1];

  const data: any = lines.map((line) => {
    return line.split(" ").map((int) => parseInt(int));
  });

  const dp = [];
  dp.push(new Array(weightMax + 1).fill(0));
  for (let i = 0; i < itemNum; i++) {
    dp.push(new Array(weightMax + 1).fill(-1));
  }

  for (let i = 0; i < itemNum; i++) {
    for (let w = 0; w <= weightMax; w++) {
      if (w - data[i][0] >= 0) {
        dp[i + 1][w] = Math.max(
          dp[i + 1][w],
          dp[i][w - data[i][0]] + data[i][1]
        );
      }
      dp[i + 1][w] = Math.max(dp[i + 1][w], dp[i][w]);
    }
  }

  console.log(Math.max.apply(null, dp[itemNum]));
});


import * as fs from "fs";

// inputで受け取り配列化する
const input = fs.readFileSync("/dev/stdin", "utf8").split("\n");
const [n, w] = input.shift().split(" ").map(Number);
const items = input.map((item) => item.split(" ").map(Number));

const dp = [];
for (let i = 0; i <= n; i++) {
  const arr = [];
  for (let j = 0; j <= w; j++) {
    arr.push(0);
  }
  dp.push(arr);
}

for (let index = 0; index < n; index++) {
  for (let sum_weight = 0; sum_weight <= w; sum_weight++) {
    const item = items[index];
    if (sum_weight - item[0] >= 0) {
      dp[index + 1][sum_weight] = Math.max(
        dp[index + 1][sum_weight],
        dp[index][sum_weight - item[0]] + item[1]
      );
    }
    dp[index + 1][sum_weight] = Math.max(
      dp[index + 1][sum_weight],
      dp[index][sum_weight]
    );
  }
}

console.log(dp[n][w]);


import * as fs from "fs";

// inputで受け取り配列化する
const input = fs.readFileSync("/dev/stdin", "utf8").split("\n");
const [n, w] = input.shift().split(" ").map(Number);
const items = input.map((item) => item.split(" ").map(Number));

const dp = new Map();

const dig = (index: number, weight: number, val: number): number => {
  if (weight > w) {
    return 0;
  } else if (index === n) {
    return val;
  }
  if (dp.has(`${index}${weight}`)) {
    return dp.get(`${index}${weight}`);
  }

  const item = items[index];
  const newVal = Math.max(
    dig(index + 1, weight, val),
    dig(index + 1, weight + item[0], val + item[1])
  );
  dp.set(`${index}${weight}`, newVal);
  return newVal;
};

console.log(dig(0, 0, 0));


import * as fs from "fs"

// 配列を作成して指定された値で初期化する
const createArray = (length: number, initialValue: any): any[] => {
  const isArray = <T>(value: any): value is Array<T> => Array.isArray(value)
  const ary: any[] = []
  for (let i = 0; i < length; i++) {
    if (isArray(initialValue)) {
      // TODO 多分ディープコピーしたほうがいいやつ
      ary.push([...initialValue])
    } else if (typeof initialValue === "object") {
      // TODO 多分ディープコピーしたほうがいいやつ
      ary.push({ ...initialValue })
    } else {
      ary.push(initialValue)
    }
  }
  return ary
}

const process = (n: number, w: number, wv: number[][]): string => {
  const table: number[][] = createArray(n + 1, createArray(w + 1, 0))

  for (let i = 1; i < n + 1; i++) {
    const wi = wv[i - 1][0]
    const vi = wv[i - 1][1]

    for (let j = 1; j < w + 1; j++) {
      // i 番目の品物を選ぶ
      if (j < wi) {
        table[i][j] = table[i - 1][j]
        continue
      }
      if (table[i - 1][j] < table[i - 1][j - wi] + vi) {
        // 更新
        table[i][j] = table[i - 1][j - wi] + vi
      } else {
        table[i][j] = table[i - 1][j]
      }
    }
  }
  console.log(table)

  return table[n][w] + ""
}

const Main = (input: string): string => {
  const aa: string[][] = input.split("\n").map((e) => e.split(" "))
  const na0: number[] = aa[0].map((e) => parseInt(e))
  aa.shift()
  const na: number[][] = aa.map((e) => e.map((e) => parseInt(e)))
  const [a, b] = na0

  const res = process(a, b, na) + ""
  console.log(res)
  return res
}
Main(fs.readFileSync("/dev/stdin", "utf8"))


import * as fs from "fs"

// 配列を作成して指定された値で初期化する
const createArray = (length: number, initialValue: any): any[] => {
  const isArray = <T>(value: any): value is Array<T> => Array.isArray(value)
  const ary: any[] = []
  for (let i = 0; i < length; i++) {
    if (isArray(initialValue)) {
      // TODO 多分ディープコピーしたほうがいいやつ
      ary.push([...initialValue])
    } else if (typeof initialValue === "object") {
      // TODO 多分ディープコピーしたほうがいいやつ
      ary.push({ ...initialValue })
    } else {
      ary.push(initialValue)
    }
  }
  return ary
}

const process = (n: number, w: number, wv: number[][]): string => {
  const table: number[][] = createArray(n, createArray(w, 0))

  for (let i = 0; i < n; i++) {
    // i：いくつめ？
    const wi = wv[i][0] - 1
    const vi = wv[i][1]

    for (let j = 0; j < w; j++) {
      if (i === 0) {
        if (j >= wi) {
          table[i][j] = vi
        }
        continue
      }

      // j：そのときの w
      if (j <= wi) {
        table[i][j] = table[i - 1][j]
        continue
      }

      if (table[i - 1][j] < table[i - 1][j - wi] + vi) {
        // 更新
        table[i][j] = table[i - 1][j - wi] + vi
      } else {
        table[i][j] = table[i - 1][j]
      }
    }
  }

  return table[n - 1][w - 1] + ""
}

const Main = (input: string): string => {
  const aa: string[][] = input.split("\n").map((e) => e.split(" "))
  const na0: number[] = aa[0].map((e) => parseInt(e))
  aa.shift()
  const na: number[][] = aa.map((e) => e.map((e) => parseInt(e)))
  const [a, b] = na0

  const res = process(a, b, na) + ""
  console.log(res)
  return res
}
Main(fs.readFileSync("/dev/stdin", "utf8"))


N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
C = list(map(int, input().split()))

s = 0
prev = -1

for i in range(N):
    t = A[i] - 1
    s += B[t]
    if prev != -1 and prev + 1 == t:
        s += C[prev]
    prev = t

print(s)


n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
c = list(map(int, input().split()))
prev = -float('inf')
res = 0
for e in a:
    e -= 1
    res += b[e]
    if prev == e - 1:
        res += c[prev]
    prev = e
print(res)


N = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
C = list(map(int, input().split()))

ans = 0
for i in range(N):
  a = A[i] - 1
  ans += B[a]
  if i > 0 and A[i] - A[i-1] == 1:
    ans += C[a-1]
print(ans)


kind = int(input())

table_1 = input().split(' ')
table_2 = input().split(' ')
table_3 = input().split(' ')
total = 0
for i in range(kind):
    total += int(table_2[i])

for j in range(kind-1):
    if int(table_1[j]) == int(table_1[j + 1]) - 1:
        total += int(table_3[j])
print(total)


n=int(input())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
c=list(map(int,input().split()))

addans=0

for i in range(n-1) :
  if a[i]+1 == a[i+1] :
    addans += c[a[i]-1]
    print(addans)
print(sum(b)+addans)


n=int(input())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
c=list(map(int,input().split()))

addans=0

for i in range(1,n) :
  if a[i-1]+1 == a[i] :
    addans += c[a[i-2]]
    print(addans)
print(sum(b)+addans)


import java.io.IOException;
import java.io.InputStream;
import java.util.NoSuchElementException;

public class Main {
	public static void main(String args[]) {

		FastScanner sc = new FastScanner();
		int n = sc.nextInt();

		int a[] = new int[n];
		int c[] = new int[n - 1];

		for (int j = 0; j < n; j++) {
			a[j] = sc.nextInt();
		}

		int result = 0;
		for (int j = 0; j < n; j++) {
			result += sc.nextInt();
		}

		for (int j = 0; j < n - 1; j++) {
			c[j] = sc.nextInt();
		}

		for (int i = 0; i < n - 1; i++) {
			result += (a[i] + 1 == a[i + 1] ? c[a[i] - 1] : 0);
		}

		System.out.println(result);
	}
}

class FastScanner {
	private final InputStream in = System.in;
	private final byte[] buffer = new byte[1024];
	private int ptr = 0;
	private int buflen = 0;

	private boolean hasNextByte() {
		if (ptr < buflen) {
			return true;
		} else {
			ptr = 0;
			try {
				buflen = in.read(buffer);
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (buflen <= 0) {
				return false;
			}
		}
            return true;
	}

	private int readByte() {
		if (hasNextByte())
			return buffer[ptr++];
		else
			return -1;
	}

	private static boolean isPrintableChar(int c) {
		return 33 <= c && c <= 126;
	}

	public boolean hasNext() {
		while (hasNextByte() && !isPrintableChar(buffer[ptr]))
			ptr++;
		return hasNextByte();
	}

	public String next() {
		if (!hasNext())
			throw new NoSuchElementException();
		StringBuilder sb = new StringBuilder();
		int b = readByte();
		while (isPrintableChar(b)) {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	public long nextLong() {
		if (!hasNext())
			throw new NoSuchElementException();
		long n = 0;
		boolean minus = false;
		int b = readByte();
		if (b == '-') {
			minus = true;
			b = readByte();
		}
		if (b < '0' || '9' < b) {
			throw new NumberFormatException();
            }
		while (true) {
			if ('0' <= b && b <= '9') {
				n *= 10;
				n += b - '0';
			} else if (b == -1 || !isPrintableChar(b)) {
				return minus ? -n : n;
			} else {
				throw new NumberFormatException();
			}
			b = readByte();
            }
        }

	public int nextInt() {
		long nl = nextLong();
		if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE)
			throw new NumberFormatException();
		return (int) nl;
        }

	public double nextDouble() {
		return Double.parseDouble(next());
	}
}


import java.io.*;
import java.util.*;
class Main{
	static final long MOD = 1_000_000_007; // 10^9+7
    static final int MAX = 2_147_483_646; // intMax
    static final int INF = 1_000_000_000; // 10^9
    public static void main(String[] args) throws Exception {
		hayami saori = new hayami();
		int n = saori.saori_hayami();
		int[] a = new int[n];
		int[] b = new int[n];
		int[] c = new int[n-1];
		for(int i = 0;i < n;i++){
			a[i] = saori.saori_hayami();
		}
		for(int i = 0;i < n;i++){
			b[i] = saori.saori_hayami();
		}
		for(int i = 0;i < n-1;i++){
			c[i] = saori.saori_hayami();
		}
		int ans = 0;
		ans = b[a[0]-1];
		for(int i = 1;i < a.length;i++){
			ans += b[a[i]-1];
			if(a[i] - a[i-1] == 1){
				ans += c[a[i-1]-1];
			}
		}
		System.out.println(ans);
		saori.close();
    }
}

class hayami implements Closeable {
	private final InputStream in = System.in;
	private final byte[] hayami = new byte[1024];
	private int Hayami = 0;
	private int saori = 0;
	private boolean HayamiSaori() {
		if (Hayami < saori) {
			return true;
		}else{
			Hayami = 0;
			try {
				saori = in.read(hayami);
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (saori <= 0) {
				return false;
			}
		}
		return true;
	}
	private int SaoriHayami() {
		if (HayamiSaori()) {
            return hayami[Hayami++];
         }else{
             return -1;
         }
	}
	private static boolean hayami_saori(int hayami) {
		return 33 <= hayami && hayami <= 126;
	}
	public boolean hayamisaori() {
		while(HayamiSaori() && !hayami_saori(hayami[Hayami])) Hayami++; return HayamiSaori();
	}
	public String nextHayami() {
		if (!hayamisaori()) throw new NoSuchElementException();
		StringBuilder hayamin = new StringBuilder();
		int saori = SaoriHayami();
		while(hayami_saori(saori)) {
			hayamin.appendCodePoint(saori);
			saori = SaoriHayami();
		}
		return hayamin.toString();
	}
	public long saorihayami() {//nextLong
		if (!hayamisaori()) throw new NoSuchElementException();
		long hayami = 0;
		boolean misao = false;
		int saori = SaoriHayami();
		if (saori == '-') {
			misao = true;
			saori = SaoriHayami();
		}
		if (saori < '0' || '9' < saori) {
			throw new NumberFormatException();
		}
		while(true){
			if ('0' <= saori && saori <= '9') {
				hayami *= 10;
				hayami += saori - '0';
			}else if(saori == -1 || !hayami_saori(saori)){
				return misao ? -hayami : hayami;
			}else{
				throw new NumberFormatException();
			}
			saori = SaoriHayami();
		}
	}
	public int saori_hayami() {//nextInt
		long hayami = saorihayami();
		if (hayami < Integer.MIN_VALUE || hayami > Integer.MAX_VALUE) throw new NumberFormatException();
		return (int) hayami;
	}
	public double Hayamin() { //nextDouble
		return Double.parseDouble(nextHayami());
	}
	public void close() {
		try {
			in.close();
		} catch (IOException e) {
		}
    }

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) throws IOException {

        InputStreamReader is = new InputStreamReader(System.in);
        BufferedReader reader = new BufferedReader(is);

        List<String> mylist = new ArrayList<>();

        // 標準入力からの値を変数strinputに代入
        String strinput = reader.readLine();

        while (strinput != null) {

            mylist.add(strinput);
            strinput = reader.readLine();

        }
        String arr01[] = mylist.get(0).split(" ");
        String arr02[] = mylist.get(1).split(" ");
        String arr03[] = mylist.get(2).split(" ");
        String arr04[] = mylist.get(3).split(" ");

        String s = arr01[0];
        Integer n = Integer.valueOf(s);

        int mysum = 0;
        for (String v : arr03) {
            mysum += Integer.valueOf(v);

        }

        for (int i = 0; i < n - 1; i++) {

            int temp = Integer.valueOf(arr02[i]);

            if (temp + 1 == Integer.valueOf(arr02[i + 1])) {
                mysum += Integer.valueOf(arr04[temp - 1]);
            }

        }

        System.out.println(mysum);
    }

}


import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int[] A = new int[N + 1];
		int[] B = new int[N + 1];
		int[] C = new int[N];
		int sum = 0;
		int target = -1;
		int add = 0;

		for (int i = 1; i < N + 1; i++) {
			A[i] = sc.nextInt();
		}
		for (int i = 1; i < N + 1; i++) {
			B[i] = sc.nextInt();
		}
		for (int i = 1; i < N; i++) {
			C[i] = sc.nextInt();
		}

		for (int i = 1; i < N + 1; i++) {
			sum+=B[A[i]];
			//addできるか
			if (A[i] == target) {
				sum+=add;
				target = -1;
			}

			//C確認
			if (A[i] < C.length) {
				target = A[i] + 1;
				add = C[A[i]];
			}

		}

		System.out.println(sum);
	}

}


import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO 140_B
		Scanner sc = new Scanner(System.in);

		int N = sc.nextInt();

		int[] A = new int[N];
		int[] B = new int[N];
		int[] C = new int[N];

		int i = 0;
		int ret = 0;

		for(i=0; i<N; i++) {
			A[i] = sc.nextInt();
		}
		for(i=0; i<N; i++) {
			B[i] = sc.nextInt();
		}
		for(i=0; i<N-1; i++) {
			C[i] = sc.nextInt();
		}
	    // Scannerクラスのインスタンスをクローズ
		sc.close();

		for(i=0; i<N; i++) {
			ret += B[i];
			ret += C[i];
		}

		// 最後に食べた料理だけ、追加の満足度はゼロ（差し引き）
		ret -= C[A[N-1]-1];

		System.out.println(ret);

	}

}


import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ

		try(Scanner sc = new Scanner(System.in)){
			int n = sc.nextInt();
			int[] a = new int[n];
			int[] b = new int[n];
			int[] c = new int[n-1];

			//Input

			for(int i = 0; i < n; i++) {
				a[i] = sc.nextInt();
			}
			for(int i = 0; i < n; i++) {
				b[i] = sc.nextInt();
			}
			for(int i = 0; i < n - 1; i++) {
				c[i] = sc.nextInt();
			}

			//けーさん
			int ans = 0;
			for(int i = 0; i < n; i++) {
				ans +=b[a[i] - 1];
				if(i != n - 1 && a[i] + 1 == a[i + 1]) {
					ans += c[i - 1];
				}

			}
			System.out.println(ans);
		}
	}

}


#include <cstdio>
#include <unordered_map>
typedef long long ll;
#define re register

#define gc getchar
#define pc putchar
#define sp pc(' ')
#define ln pc('\n')

template <class t>
inline void read(t&num) {
    register char c = gc();
    register bool flag = 0;
    while (c != '-' && (c < '0' || c > '9')) c = gc();
    if (c == '-') flag = 1, c = gc();
    num = 0;
    while (c >= '0' && c <= '9') num = (num << 1) + (num << 3) + (c ^ 48), c = gc();
    flag && (num = ~(num - 1));
}

template <class t>
inline void print(t num) {
    if (num < 0) pc('-'), num = ~(num - 1);
    if (num >= 10) print(num / 10);
    pc(num % 10 ^ 48);
}

int n;
int a[21], b[21], c[21];

int main() {
    read(n);
    for (int i = 1; i <= n; i++) read(a[i]);
    for (int i = 1; i <= n; i++) read(b[i]);
    for (int i = 1; i < n; i++) read(c[i]);
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        ans += b[a[i]];
        if (a[i + 1] == a[i] + 1) ans += c[a[i]];
    }
    print(ans), ln;
}


#include<bits/stdc++.h>
#include<string>
#include<map>
#define ll          long long
#define pb          push_back
#define mp          make_pair
#define pii         pair<int,int>
#define pll         pair<ll,ll>
#define vii         vector<pair<ll,ll> >
#define vi          vector<int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (int)x.size()
#define hell        1000000007
#define endl        '\n'
#define rep(i,a,b)  for(ll i=a;i<b;i++)
#define rep1(i,a,b) for(ll i=a;i<= b;i++)
#define PI          3.14159
#define MAX         100000001
#define fast_io      ios_base::sync_with_stdio(false);  cin.tie(0); cout.tie(0);
#define scan(var)    scanf("%lld",&var)
#define print(var)   printf("%lld\n", var);
#define BLOCK 317
#define double       long double
#define mod          998244353
using namespace std;
ll arr[21];
ll arr1[21];
ll arr2[21];
int main()
{
  fast_io
  ll n;
  cin >> n;
  rep(i,1,n + 1)
  {
    cin >> arr[i];
  }
  rep(i,1,n + 1)
  {
    cin >> arr1[i];
  }
  rep(i,1,n)
  {
    cin >> arr2[i];
  }
  ll prev = -1;
  ll ans = 0;
  rep(i,1,n + 1)
  {
    ans += arr1[arr[i]];
    if(prev != -1)
    {
      if(prev == arr[i] - 1)
      {
        ans += arr2[prev];
      }
    }
    prev = arr[i];
  }
  cout << ans;
  return 0;
}


#pragma GCC optimize("-O3")

#include <bits/stdc++.h>

using namespace std;

#define ll long long

signed main() {
	int n; cin >> n;
	vector<int> a(n);
	for (int i = 0; i < n; ++i)
		cin >> a[i];
	ll ans = 0;
	for (int i = 0; i < n; ++i) {
		int b; cin >> b;
		ans += b;
	}
	vector<int> c(n - 1);
	for (int i = 0; i < n - 1; ++i)
		cin >> c[i];
	for (int i = 0; i < n - 1; ++i) {
		if (a[i] + 1 == a[i + 1])
			ans += c[a[i] - 1];
	}

	cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (ll i = 0; i < (ll)n; i++)
#define Rep(i, s, n) for (ll i = (ll)s; i < (ll)n; i++)
typedef long long ll;

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

    int n;
    cin >> n;
    int a[n], b[n], c[n-1];
    rep (i, n) cin >> a[i];
    rep (i, n) cin >> b[i];
    rep (i, n-1) cin >> c[i];
    int res = 0;
    rep (i, n) {
        res += b[a[i]-1];
        if (i > 0) {
            if (a[i]-a[i-1] == 1) res += c[a[i]-2];
        }
    }
    cout << &c[0] << endl;
}


#pragma region header
#define _GLIBCXX_DEBUG
#include <bitset>
#include <tuple>
#include <cstdint>
#include <cstdio>
#include <cctype>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <limits>
#include <map>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <math.h>
using namespace std;
#define int long long
using ll = long long;
/* ----------------よく使う数字や配列----------------- */
int dx[] = { 1,0,-1,0 };
int dy[] = { 0,1,0,-1 };
constexpr ll mod = 1e9 + 7;
constexpr ll inf = INT32_MAX / 2;
constexpr ll INF = LLONG_MAX / 2;
constexpr long double eps = DBL_EPSILON;
constexpr long double pi = 3.141592653589793238462643383279;
/* ----------------------end----------------------- */
/* --------------------テンプレート------------------ */
template<class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
/* ----------------------end----------------------- */

/* --------------------ライブラリ-------------------- */
ll fact(int i) {       //階乗
    if (i == 0) return 1;
    return (fact(i - 1)) * i % mod;
}
ll gcd(ll a, ll b) {        //最大公約数
    if (b == 0) return a;
    return gcd(b, a % b);
}
ll lcm(ll a, ll b) {      //最小公倍数
    return a * b / gcd(a, b);
}
bool isprime(ll a)//素数判定、primeならtrue,違うならfalse
{
    if (a < 2) return false;
    else if (a == 2) return true;
    else if (a % 2 == 0) return false;
    double m = sqrt(a);
    for (int i = 3; i <= m; i += 2)
    {
        if (a % i == 0)
        {
            return false;
        }
    }
    // 素数である
    return true;
}
ll keta(ll n) {        //桁数を求める
    if (n == 0) return 1;
    int count = 0;
    while (n != 0) {
        n /= 10;
        count++;
    }
    return count;
}
ll ketasum(ll n) {    //各桁の和
    ll sum = 0;
    while (n != 0) {
        sum += n % 10;
        n /= 10;
    }
    return sum;
}
/* ----------------------end----------------------- */
#pragma endregion
signed main() {
    int N;
    cin>>N;
    int ans=0;

    vector<int>A(N);
    vector<int>B(N);
    vector<int>C(N-1);
    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-1;i++){
        cin>>C[i];
    }
    for(int i=0;i<N;i++){
        if(A[i+1]-1==A[i]){
            ans+=(B[i]+C[i]);
        }
        else{
            ans+=B[i];
        }
    }
    cout<<ans<<endl;
}


#include <iostream>
#include <vector>

int main() {
  int n;
  std::cin >> n;
  std::vector<int> a(n), b(n), c(n);
  for (int i = 0; i < n; ++i) {
    std::cin >> a[i];
    a[i]--;
  }
  for (int i = 0; i < n; ++i)
    std::cin >> b[i];
  for (int i = 0; i < n - 1; ++i)
    std::cin >> c[i];

  int sum = 0;
  for (int i = 0; i < n; ++i)
    sum += b[a[i]];

  for (int i = 0; i < n - 1; ++i)
    if (a[i] + 1 == a[i + 1])
      sum += c[i];

  std::cout << sum << std::endl;
}


int main(void){
  int n,a[20],b[20],c[20];

  scanf("%d",&n);

  int i,sum=0;

  for(i=0; i<n; i++){
    scanf("%d",&a[i]);
  }
  for(i=0; i<n; i++){
    scanf("%d",&b[i]);
  }
  for(i=0; i<n-1; i++){
    scanf("%d",&c[i]);
  }

  for(i=0; i<n-1; i++){
    sum += b[a[i]-1];
    if(a[i+1]-a[i] == 1)
      sum += c[a[i]-1];
  }

  sum += b[a[n-1]-1];

  printf("%d",sum);
}


#include<stdio.h>
int main(){
  int n,i,count=0,score;
  scanf("%d",&n);
  int a[n+1],c[n+1];
  for(i=0;i<n;i++)
    scanf("%d",&a[i]);
  for(i=0;i<n;i++){
    scanf("%d",&score);
    count+=score;
  }
  for(i=0;i<n-1;i++)
    scanf("%d",&c[i]);
  for(i=0;i<n-1;i++){
    if(a[i]==a[i+1]-1)
      count+=c[a[i]-1];
  }
  printf("%d\n",count);
  return 0;
}


#include "stdio.h"

int main(void) {

	int number;
	int array[20], barray[20], carray[19];
	int sum = 0;
	scanf("%d", &number);

	for (int i = 1; i<=number; i++) {
		scanf("%d", &array[i]);
	}
	for (int i = 1; i<=number; i++) {
		scanf("%d", &barray[i]);
	}
	for (int i = 1; i<=number - 1; i++) {
		scanf("%d", &carray[i]);
	}

	for (int i = 1; i<=number; i++) {
		sum += barray[array[i]];
			if ((array[i] == array[i-1] + 1) && (i != 1)) {
				sum += carray[array[i-1]];
			}
	}
	printf("%d\n", sum);

	return 0;
}


#include <stdio.h>
#include <stdlib.h>

int main()
{
  int n;
  int i;
  int ans = 0;

  scanf("%d", &n);

  int a[n];
  int b[n];
  int c[n-1];

  for(i = 0; i < n; i++) {
    scanf("%d", &a[i]);
    a[i] = a[i] - 1;
  }

  for(i = 0; i < n; i++) {
    scanf("%d", &b[i]);
  }

  for(i = 0; i < n-1; i++) {
    scanf("%d", &c[i]);
  }

  for(i = 0; i < n; i++) {
    ans += b[a[i]];
    if((a[i] - a[i-1] == 1)) {
      ans += c[a[i]];
    }
  }

  printf("%d\n", ans);

  return(0);
}


#include <stdio.h>
#include <stdlib.h>

int main()
{
  int n;
  int i;
  int ans = 0;

  scanf("%d", &n);

  int a[n];
  int b[n];
  int c[n-1];

  for(i = 0; i < n; i++) {
    scanf("%d", &a[i]);
    a[i] = a[i] - 1;
  }

  for(i = 0; i < n; i++) {
    scanf("%d", &b[i]);
  }

  for(i = 0; i < n-1; i++) {
    scanf("%d", &c[i]);
  }

  for(i = 0; i < n; i++) {
    ans += b[a[i]];
    if((a[i] - a[i-1] == 1)) {
      ans += c[a[i-1]];
    }
  }

  printf("%d\n", ans);

  return(0);
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
  int n,i,ans=0;
  scanf("%d", &n);

  int a[n],b[n],c[n-1];

  for(i=0; i<n; i++)
    scanf("%d", &a[i]);
  for(i=0; i<n; i++)
    scanf("%d", &b[i]);
  for(i=0; i<n-1; i++)a
    scanf("%d", &c[i]);

  ans += b[a[0]-1];

  for(i=1; i<n; i++){
    ans += b[a[i]-1];
    if(a[i]-a[i-1]==1)
      ans += c[a[i-1]-1];
  }

  printf("%d", ans);

  return 0;
}


// inputに入力データ全体が入る
function Main(input) {
	// 1行目がinput[0], 2行目がinput[1], …に入る
	input = input.split("\n");
	var N = Number(input[0])
	//文字列から10進数に変換するときはparseIntを使います
    var a = input[1].split(" ")
	var b = input[2].split(" ")
    var c = input[3].split(" ")

    var answer = 0

    for(var i =0; i<N ;i++){

      var aa = Number(a[i])
      var zz = Number(b[aa - 1])

      answer = answer + zz

      if(i != 0 && aa == Number(a[i - 1]) + 1){
        var cc = Number(c[aa - 2])
        answer = answer + cc
      }
     }

	//出力
	console.log(answer);
}
//*この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(input) {
	input = input.trim();
	input = input.split("\n");

	var shurui = input[0];
	var ryori = input[1].split(" ");
	var manzoku = input[2].split(" ");
	var manzoku_plus = input[3].split(" ");

	var manzoku_sum = 0;
	var ryori_order = 0;
	var ryori_order_back = 0;
	for (var i = 0; i < ryori.length; i++) {

		ryori_order = Number(ryori[i]);
		manzoku_sum += Number(manzoku[ryori_order - 1]);

		if (i > 0 && ryori_order_back + 1 == ryori_order) {
			manzoku_sum += Number(manzoku_plus[ryori_order_back - 1]);
		}
		ryori_order_back = ryori_order;

	}

	console.log(manzoku_sum);

}

//*この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


"use strict"
const Main = (input)=>{
	let xs = input.trim().split("\n");
    let N = xs[0].split(" ").map(Number);
    let A = xs[1].split(" ").map(Number);
    let B = xs[2].split(" ").map(Number);
    let C = xs[3].split(" ").map(Number);
    let ans = 0;
      for(let i = 0; i < N; i++){
        ans += B[A[i]-1];
          if(i >= 1){
          let a = A[i];
          let b = A[i-1];
            if(a-b == 1){
            ans += C[A[i]-2];
            }
          }
        }
  console.log(ans);
}
Main(require("fs").readFileSync("/dev/stdin","utf8"));


"use strict"
const create = () => {
    const input = require("fs").readFileSync("/dev/stdin", "utf8").trim().split("\n");
    const res = {
        "list": input, "index": 0, "max": input.length,
        "hasNext": function() {return this.index < this.max},
        "next": function() { if (!this.hasNext()) {throw "ArrayIndexOutOfBoundsException";}else{return this.list[this.index++];}}
    };
    return res;
}
const o = create();
const next = () => o.next()
const nextInt = () => parseInt(o.next())
const nextStrArray = () => o.next().split(" ")
const nextIntArray = () => o.next().split(" ").map(el => parseInt(el))
const nextCharArray = () => o.next().split("")
const hasNext = () => o.hasNext()
const myout = (...x) => console.log(...x)
const Main = () => {
    let n = nextInt()
    let a = nextIntArray()
    let b = nextIntArray()
    let c = nextIntArray()
    let ans =
    for(let i = 0;i<a.length; i++){
        ans += b[a[i]-1]
        if(a[i]+1 == a[i+1]) ans += c[a[i]-1]
    }
    console.log(ans)
}
Main()


"use strict"
const create = () => {
    const input = require("fs").readFileSync("/dev/stdin", "utf8").trim().split("\n");
    const res = {
        "list": input, "index": 0, "max": input.length,
        "hasNext": function() {return this.index < this.max},
        "next": function() { if (!this.hasNext()) {throw "ArrayIndexOutOfBoundsException";}else{return this.list[this.index++];}}
    };
    return res;
}
const o = create();
const next = () => o.next()
const nextInt = () => parseInt(o.next())
const nextStrArray = () => o.next().split(" ")
const nextIntArray = () => o.next().split(" ").map(el => parseInt(el))
const nextCharArray = () => o.next().split("")
const hasNext = () => o.hasNext()
const myout = (...x) => console.log(...x)
const Main = () => {
    let n = nextInt()
    let a = nextIntArray()
    let b = nextIntArray()
    let c = nextIntArray()
    let ans = b[a[0]]
    for(let i = 1;i<a.length; i++){
        ans += b[a[i]-1]
        if(a[i]+1 == a[i+1]) ans += c[a[i]-1]
    }
    console.log(ans)
}
Main()


"use strict"
const create = () => {
    const input = require("fs").readFileSync("/dev/stdin", "utf8").trim().split("\n");
    const res = {
        "list": input, "index": 0, "max": input.length,
        "hasNext": function() {return this.index < this.max},
        "next": function() { if (!this.hasNext()) {throw "ArrayIndexOutOfBoundsException";}else{return this.list[this.index++];}}
    };
    return res;
}
const o = create();
const next = () => o.next()
const nextInt = () => parseInt(o.next())
const nextStrArray = () => o.next().split(" ")
const nextIntArray = () => o.next().split(" ").map(el => parseInt(el))
const nextCharArray = () => o.next().split("")
const hasNext = () => o.hasNext()
const myout = (...x) => console.log(...x)
const Main = () => {
    let n = nextInt()
    let a = nextIntArray()
    let b = nextIntArray()
    let c = nextIntArray()
    let ans = b[a[0]]
    for(let i = 1;i<a.length; i++){
        ans += b[a[i]]
        if(a[i]-1 == i-1) ans += c[a[i]]
    }
    console.log(ans)
}
Main()


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

const (
	defaultBufferSize = 1024
	maxBufferSize     = 1e6
	Mod               = 1e9 + 7
)

var sc = bufio.NewScanner(os.Stdin)

// sc.Buffer(make([]byte, defaultBufferSize), maxBufferSize)

func readInt() int {
	sc.Scan()
	i, err := strconv.Atoi(sc.Text())
	if err != nil {
		panic(err)
	}
	return i
}

func readString() string {
	sc.Scan()
	return sc.Text()
}

func readInt64() int64 {
	sc.Scan()
	i, err := strconv.ParseInt(sc.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return int64(i)
}

func readfloat64() float64 {
	sc.Scan()
	f, err := strconv.ParseFloat(sc.Text(), 64)
	if err != nil {
		panic(err)
	}
	return f
}

func abs(a int) int {
	if a < 0 {
		return a * -1
	}
	return a
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func gcd(x, y int) int {
	if y == 0 {
		return x
	}
	return gcd(y, x%y)
}

func ModComb(n, k int) int {
	if k == 0 {
		return 1
	}
	x, y := n, k
	for i := 1; i < k; i++ {
		x = x * (n - i) % Mod
		y = y * (k - i) % Mod
	}
	inv := ModInv(y)
	return x * inv % Mod
}

func ModFact(x int) int {
	fact := 1
	for i := 1; i <= x; i++ {
		fact = fact * i % Mod
	}
	return fact
}

func ModInv(x int) int {
	return ModPow(x, Mod-2)
}

func ModPow(a, n int) int {
	res := 1
	for n > 0 {
		if n%2 != 0 {
			res = res * a % Mod
		}
		a = a * a % Mod
		n /= 2
	}
	return res
}

func pow(a, n int) int {
	if n == 0 {
		return 1
	}

	ans := 0
	if n%2 == 0 {
		ans = pow(a*a, n/2)
	} else {
		ans = a * pow(a*a, (n-1)/2)
	}
	return ans
}

func intSliceReverse(slice []int) []int {
	for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 {
		slice[i], slice[j] = slice[j], slice[i]
	}
	return slice
}

func stringReverse(str string) string {
	runes := []rune(str)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func primeFactorization(x int) map[int]int {
	result := make(map[int]int, 0)
	for i := 2; i*i <= x; i++ {
		for x%i == 0 {
			result[i]++
			x /= i
		}
	}
	if x != 1 {
		result[x]++
	}
	return result
}

func isPrime(x int) bool {
	if x == 1 {
		return false
	}
	for i := 2; i*i <= x; i++ {
		if i == x {
			continue
		}
		if x%i == 0 {
			return false
		}
	}
	return true
}

func main() {
	sc.Split(bufio.ScanWords)
	n := readInt()
	A := make([]int, n)
	B := make([]int, n)
	C := make([]int, n-1)

	for i := 0; i < n; i++ {
		A[i] = readInt()
	}
	for i := 0; i < n; i++ {
		B[i] = readInt()
	}
	for i := 0; i < n-1; i++ {
		C[i] = readInt()
	}

	ans := 0
	prev := 0
	for i := 0; i < n; i++ {
		ans += B[A[i]-1]
		if i > 0 && A[i]-1-prev == 1 {
			ans += C[prev]
		}
		prev = A[i] - 1
	}
	fmt.Println(ans)
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

var mod = 1000000007

func main() {
	r := bufio.NewReader(os.Stdin)
	var n int
	fmt.Fscan(r, &n)

	as := make([]int,n)
	bs := make([]int,n)
	cs := make([]int,n-1)
	for i := 0; i < n; i++ {
		fmt.Fscan(r, &as[i])
		as[i]--
	}
	for i := 0; i < n; i++ {
		fmt.Fscan(r, &bs[i])
	}
	for i := 0; i < n-1; i++ {
		fmt.Fscan(r, &cs[i])
	}

	before := 10000000
	ans := 0
	for i := 0; i <n; i++ {
		ans += bs[as[i]]
		if before == as[i]-1 {
			ans += cs[before]
		}
		before = as[i]
	}

	fmt.Println(ans)
}

// Union-Find
type unionFind struct {
	d []int
}

func newUnionFind(n int) *unionFind {
	uf := new(unionFind)
	uf.d = make([]int, n)
	for i := 0; i < n; i++ {
		uf.d[i] = -1
	}
	return uf
}

func (uf *unionFind) find(x int) int {
	if uf.d[x] < 0 {
		return x
	}
	uf.d[x] = uf.find(uf.d[x])
	return uf.d[x]
}

func (uf *unionFind) unite(x, y int) bool {
	rootX := uf.find(x)
	rootY := uf.find(y)
	if rootX == rootY {
		return false
	}

	if uf.d[rootX] < uf.d[rootY] {
		uf.d[rootX] += uf.d[rootY]
		uf.d[rootY] = rootX
	} else {
		uf.d[rootY] += uf.d[rootX]
		uf.d[rootX] = rootY
	}

	return true
}

func (uf *unionFind) same(x, y int) bool {
	return uf.find(x) == uf.find(y)
}

func (uf *unionFind) size(x int) int {
	return -uf.d[uf.find(x)]
}

// mod
func modpow(a, n, mod int) int {
	res := 1
	for n > 0 {
		if n%2 != 0 {
			res = res * a % mod
		}
		a = a * a % mod
		n = n / 2
	}
	return res
}

func modinv(n, mod int) int {
	return modpow(n, mod-2, mod)
}

func modcomb(n, a, mod int) int {
	x := 1
	y := 1
	for i := 0; i < a; i++ {
		x = x * (n - i)
		x %= mod
		y = y * (i + 1)
		y %= mod
	}
	return x * modpow(y, mod-2, mod) % mod
}

func modfactorial(n, mod int) int {
	result := 1
	for i := 1; i <= n; i++ {
		result = (result * i) % mod
	}
	return result
}

// Combination ...
type Combination struct {
	facts, invs []int
	mod         int
}

// NewCombination ...
func NewCombination(n, mod int) Combination {
	return Combination{
		facts: make([]int, n+1),
		invs:  make([]int, n+1),
		mod:   mod,
	}
}

func (cmb *Combination) calc(n, k int) int {
	ret := cmb.facts[n] * cmb.invs[k]
	ret %= cmb.mod
	ret = ret * cmb.invs[n-k]
	ret %= cmb.mod
	return ret
}

func (cmb *Combination) init(n int) {
	cmb.facts[0] = 1
	// 階乗を算出
	for i := 1; i <= n; i++ {
		cmb.facts[i] = cmb.facts[i-1] * i % cmb.mod
	}
	// 逆元を算出
	cmb.invs[n] = modinv(cmb.facts[n], cmb.mod)
	for i := n - 1; i >= 0; i-- {
		cmb.invs[i] = cmb.invs[i+1] * (i + 1) % cmb.mod
	}
}

// Utility
func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

func max(x, y int) int {
	if x > y {
		return x
	}
	return y
}

func abs(x int) int {
	if x < 0 {
		return -x
	}
	return x
}

func primeFactor(x int) map[int]int {
	res := make(map[int]int)
	for i := 2; i*i <= x; i++ {
		for x%i == 0 {
			res[i]++
			x = x / i
		}
	}
	if x != 1 {
		res[x] = 1
	}
	return res
}

func divisor(x int) []int {
	res := make([]int, 0)
	for i := 1; i*i <= x; i++ {
		if x%i == 0 {
			res = append(res, i)
			if i != x/i {
				res = append(res, x/i)
			}
		}
	}
	return res
}

func gcd(x, y int) int {
	if y == 0 {
		return x
	}
	return gcd(y, x%y)
}

func lcm(x, y int) int {
	return x / gcd(x, y) * y
}

func reverseString(s string) string {
	r := []rune(s)
	for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
		r[i], r[j] = r[j], r[i]
	}
	return string(r)
}

func pow(a, n int) int {
	ret := 1
	for i := 1; i <= n; i++ {
		ret *= a
	}
	return ret
}

// Queue ...
type Queue []int

// pop ...
func (q *Queue) empty() bool {
	return len(*q) == 0
}

// push ...
func (q *Queue) push(i int) {
	*q = append(*q, i)
}

// pop ...
func (q *Queue) pop() (int, bool) {
	if q.empty() {
		return 0, false
	} else {
		res := (*q)[0]
		*q = (*q)[1:]
		return res, true
	}
}

// Stack ...
type Stack []int

// pop ...
func (s *Stack) empty() bool {
	return len(*s) == 0
}

// push ...
func (s *Stack) push(i int) {
	*s = append(*s, i)
}

// pop ...
func (s *Stack) pop() (int, bool) {
	if s.empty() {
		return 0, false
	} else {
		index := len(*s) - 1
		res := (*s)[index]
		*s = (*s)[:index]
		return res, true
	}
}

// priority_queue
type intHeap []int

func (h intHeap) Len() int           { return len(h) }
func (h intHeap) Less(i, j int) bool { return h[i] > h[j] }
func (h intHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
func (h *intHeap) Push(x interface{}) {
	*h = append(*h, x.(int))
}
func (h *intHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

// sortable points
type point struct {
	x int
	y int
}

type points []point

func (p points) Len() int {
	return len(p)
}

func (p points) Less(i, j int) bool {
	return p[i].x < p[j].x
}

func (p points) Swap(i, j int) {
	p[i], p[j] = p[j], p[i]
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

func out(x ...interface{}) {
	fmt.Println(x...)
}

var sc = bufio.NewScanner(os.Stdin)

func getInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func getString() string {
	sc.Scan()
	return sc.Text()
}

// min, max, asub, absなど基本関数
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func asub(a, b int) int {
	if a > b {
		return a - b
	}
	return b - a
}

func abs(a int) int {
	if a >= 0 {
		return a
	}
	return -a
}

func lowerBound(a []int, x int) int {
	idx := sort.Search(len(a), func(i int) bool {
		return a[i] >= x
	})
	return idx
}

func upperBound(a []int, x int) int {
	idx := sort.Search(len(a), func(i int) bool {
		return a[i] > x
	})
	return idx
}

func main() {
	sc.Split(bufio.ScanWords)
	N := getInt()
	a := make([]int, N)
	b := make([]int, N)
	c := make([]int, N-1)
	for i := 0; i < N; i++ {
		a[i] = getInt() - 1
	}
	for i := 0; i < N; i++ {
		b[i] = getInt()
	}
	for i := 0; i < N-1; i++ {
		c[i] = getInt()
	}

	prev := -1
	ans := 0
	for i := 0; i < N; i++ {
		x := a[i]
		ans += b[x]
		if x == prev+1 && x != 0 {
			ans += c[x-1]
		}
		prev = x
	}
	out(ans)
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

func main() {
	sc.Split(bufio.ScanWords)

	n := nextInt()
	alist := make([]int, n)
	blist := make([]int, n)
	clist := make([]int, n)
	bsum := 0
	for i := 0; i < n; i++ {
		alist[i] = nextInt()
	}
	for i := 0; i < n; i++ {
		blist[i] = nextInt()
		bsum += blist[i]
	}
	for i := 0; i < n-1; i++ {
		clist[i] = nextInt()
	}
	for i := 1; i < n; i++ {
		if alist[i]-alist[i-1] == 1 {
			bsum += clist[alist[i-1]-1]
		}
	}

	fmt.Println(bsum, clist)
}

// ---- readfunc
func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}
func nextStr() string {
	sc.Scan()
	return sc.Text()
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

var (
	read  = bufio.NewReader(os.Stdin)
	write = bufio.NewWriter(os.Stdout)
)

func min(a, b int) int {
	if a <= b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a >= b {
		return a
	}
	return b
}

func yesno(result bool) {
	if result {
		fmt.Fprintln(write, "Yes")
	} else {
		fmt.Fprintln(write, "No")
	}
}

func printansStr(result bool, a, b string) {
	if result {
		fmt.Fprintln(write, a)
	} else {
		fmt.Fprintln(write, b)
	}
}

func printansInt(result bool, a, b int) {
	if result {
		fmt.Fprintln(write, a)
	} else {
		fmt.Fprintln(write, b)
	}
}

func main() {
	defer write.Flush()

	var n int
	fmt.Fscan(read, &n)

	A := make([]int, n)
	B := make([]int, n)
	C := make([]int, n)

	for i := 0; i < n; i++ {
		fmt.Fscan(read, &A[i])
	}
	for i := 0; i < n; i++ {
		fmt.Fscan(read, &B[i])
	}
	for i := 0; i < n-1; i++ {
		fmt.Fscan(read, &C[i])
	}

	pre := -1
	sum := 0
	for i := 0; i < n; i++ {
		sum += B[A[i]-1]
		if pre+1 == A[i]-1 {
			sum += C[pre]
		}
		pre = A[i] - 1
	}
	fmt.Println(sum)

}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

func main() {
	var n int
	fmt.Scan(&n)

	ali := make([]int, n, n)

	sc.Split(bufio.ScanWords)

	for i := 0; i < n; i++ {
		ali[i] = nextInt()
	}

	bli := make([]int, n, n)

	for i := 0; i < n; i++ {
		bli[i] = nextInt()
	}

	cli := make([]int, n-1, n-1)

	for i := 0; i < n-1; i++ {
		cli[i] = nextInt()
	}

	count := sum(bli)

	tmpA := ali[0]
	for i := 0; i < n; i++ {
		if ali[i] == tmpA+1 {
			if i == 1 {
				count += cli[len(cli)-1]
			} else if i == n-1 {
				count += cli[0]
			} else {
				count += cli[i-1]
			}
		}
		tmpA = ali[i]
	}

	fmt.Println(count)
}

func sum(a []int) int {
	s := 0
	for i := 0; i < len(a); i++ {
		s += a[i]
	}
	return s
}

func nextLine() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}


lines = []
while line = gets
    lines << line.chomp.split(' ').map(&:to_i)
end

N = lines[0][0]

ans = 0
last_dish = -10
for i in 1..N do
  dish = lines[1][i-1]
  ans += lines[2][dish-1]
  if dish == last_dish + 1 then
    ans += lines[3][last_dish-1]
  end
  last_dish = dish
end
print ans


N = gets.to_i
A = gets.split.map(&:to_i)
B = gets.split.map(&:to_i)
C = gets.split.map(&:to_i)
before = -1
res = 0
A.each do |a|
    res += B[a-1]
    if before == a-1 then
        res += C[before-1]
    end
    before = a
end
puts res


n = gets.to_i
a = gets.split(" ").map(&:to_i)
b = gets.split(" ").map(&:to_i)
c = gets.split(" ").map(&:to_i)

ans = 0
a.each.with_index do |n, i|
  ans += b[n-1]
  if i > 0 && a[i] - a[i-1] == 1
    ans += c[a[i]-2]
  end
end
p ans


n,a,b,c=$<.map{_1.split.map &:to_i}
p b.sum+(0..n-2).sum{|i|a[i]+1==a[i+1] ? c[a[i]-1] : 0}


n = gets.chomp.to_i
a = gets.chomp.split.map(&:to_i)
b = gets.chomp.split.map(&:to_i)
c = gets.chomp.split.map(&:to_i)
sum = 0
n.times do |i|
  sum += b[a[i] - 1]
  if a[i-1] + 1 == a[i]
    sum += c[a[i-1]-1]
  end
end

puts sum


num = gets
desh = gets.chomp.split(' ')
manzoku1 = gets.chomp.split(' ')
manzoku2 = gets.chomp.split(' ')

for i in 0..num do
  if i > 0
  	result += manzoku2[i-1] if desh[i-1] == (desh[i]+1)
  result += manzoku1[i]
end
puts result


use std::io;

fn main() {
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let n = match buf.trim().parse::<i32>() {
		Ok(m) => m,
		_ => panic!(""),
	};

	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let iter = buf.split_whitespace();
	let mut a = Vec::new();
	for j in iter {
		let i = match j.parse::<i32>() {
			Ok(m) => m,
			_ => panic!(""),
		};
		a.push(i);
	}

	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let iter = buf.split_whitespace();
	let mut b = Vec::new();
	for j in iter {
		let i = match j.parse::<i32>() {
			Ok(m) => m,
			_ => panic!(""),
		};
		b.push(i);
	}

	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let iter = buf.split_whitespace();
	let mut c = Vec::new();
	for j in iter {
		let i = match j.parse::<i32>() {
			Ok(m) => m,
			_ => panic!(""),
		};
		c.push(i);
	}
	let mut ret = 0;
	for i in 0..n {
		let num = a[i as usize];
		ret = ret + b[(num - 1) as usize];
		if i+1 < n && a[(i+1) as usize] == num + 1 {
			ret = ret + c[(num - 1) as usize];
		}
	}
	println!("{}", ret);
}


/* {{{ */
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};
    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };
    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };
    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}
/* }}} */

fn main() {
    input! {
        n: usize,
        a: [usize1;n],
        b: [u32;n],
        c: [u32;n-1]
    }
    let mut res = b[a[0]];
    for i in 1..n {
        res += b[a[i]];
        if a[i-1] + 1 == a[i] {
            res += c[a[i]-1];
        }
    }
    println!("{}", res);
}
/* vim:set foldmethod=marker: */


fn input1<T: std::str::FromStr> () -> Result<T, T::Err> {
    let mut n = String::new();
    std::io::stdin().read_line(&mut n).unwrap();
    n.trim().parse()
}

fn input_arr<T: std::str::FromStr> () -> Vec<T> {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim().split_whitespace().flat_map(str::parse).collect()
}

fn main() {
    let n: usize = input1().unwrap();
    let a: Vec<usize> = input_arr();
    let b: Vec<usize> = input_arr();
    let c: Vec<usize> = input_arr();

    let mut prev = n;
    let mut result = 0;
    for av in a.into_iter() {
        let i = av - 1;
        result += b[i];
        if i == 1 + prev {
            result += c[prev];
        }
        prev = i;
    }
    println!("{}", result);
}


#![allow(unused_imports)]

//input
use proconio::input;
use proconio::marker::{Bytes, Chars};
//use std::io::Read;

//collections
//use std::collections::BTreeMap;
//use std::collections::BTreeSet;
//use std::collections::HashMap;
//use std::collections::HashSet;
//use std::collections::VecDeque;
//use std::collections::BinaryHeap;

//use std::cmp::*;

fn main() {
    input! {
        n: usize,
        a: [usize;n],
        b: [u64;n],
        c: [u64;n-1],
    }

    let mut ans = b[a[0] - 1];
    let mut bf = a[0];

    for i in 1..n {
        ans += b[a[i] - 1];
        if a[i] != 1 {
            if bf + 1 == a[i] {
                ans += c[bf - 1];
            }
        }
        bf = a[i];
    }

    println!("{}", ans);
}


use std::io::*;
use std::str::FromStr;

fn read<T: FromStr>() -> T {
	let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn main() {
	let n: u32 = read();
	let mut a: Vec<u32> = Vec::new();
	let mut b: Vec<u32> = Vec::new();
	let mut c: Vec<u32> = Vec::new();
	for i in 0..n{
		a.push(read());
	}
	for i in 0..n{
		b.push(read());
	}
	for i in 0..n-1{
		c.push(read());
	}

	let mut result = 0;
	let mut past_ai = 0;

	for ai in a {
		result += b[(ai-1) as usize];
		if (ai > past_ai && ai-past_ai == 1) || (ai <= past_ai && past_ai-ai == 1) {
			result += c[(past_ai-1) as usize];
		}
		past_ai = ai;
	}
	println!("{}", result);

}


macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};
    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };
    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };
    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };
    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

fn main() {
    input! {
        n: i32,
        a: [i32; n],
        b: [i32; n],
        c: [i32; n-1]
    }
    let mut ans: i32 = 0;
    let mut bef: i32 = 1000;
    for i in 0..n {
        ans += b.get(a.get(a).unwrap()).unwrap();
        if bef + 1 == a.get(a).unwrap() {
            ans += c.get(bef).unwrap();
        }
        bef = a.get(a).unwrap();
    }
    println!("{}", ans);
}


var i:[Int]{return readLine()!.characters.split(" ").map{Int(String($0))!}}
let N=i[0],A=i.map{$0-1},B=i,C=i
print((0..<N).reduce(0){$0+B[A[$1]]+(0<$1&&A[$1-1]+1==A[$1] ?C[A[$1-1]]:0)})


import Foundation
import CoreFoundation

#if swift(>=4.0)
prefix operator *
infix operator **: PowerPrecedence
precedencegroup PowerPrecedence {
    higherThan: MultiplicationPrecedence
    lowerThan: BitwiseShiftPrecedence
    associativity: right
}
#else
extension String {
    func split(separator separator: Character) -> [String] {
        return self.characters.split(separator).map{String($0)}
    }
    var count: Int {
        return self.characters.count
    }
    var first: Character? {
        return self.characters.first
    }
    var last: Character? {
        return self.characters.last
    }
    func uppercased() -> String {
        return self.uppercaseString
    }
    func lowercased() -> String {
        return self.lowercaseString
    }
    func reversed() -> ReverseCollection<String.CharacterView> {
        return self.characters.reverse()
    }
    func forEach(body: (Character) -> Void) {
        return self.characters.forEach{body($0)}
    }
    func map<T>(transform: (Character) -> T) -> [T] {
        return self.characters.map{transform($0)}
    }
    func reduce<Result>(initialResult: Result, _ nextPartialResult: (Result, Character) -> Result) -> Result {
        return self.characters.reduce(initialResult){nextPartialResult($0, $1)}
    }
    func filter(isIncluded: (Character) -> Bool) -> String {
        return String(self.characters.filter{isIncluded($0)})
    }
    func enumerated() -> EnumerateSequence<String.CharacterView> {
        return self.characters.enumerate()
    }
}
extension Array where Element: Comparable {
    func max() -> Element? {
        return self.maxElement()
    }
    func min() -> Element? {
        return self.minElement()
    }
    func sorted(by areInIncreasingOrder: (Element, Element) -> Bool = {$0 < $1}) -> [Element] {
        return self.sort(areInIncreasingOrder)
    }
    mutating func sort(by areInIncreasingOrder: (Element, Element) -> Bool = {$0 < $1}) {
        self.sortInPlace(areInIncreasingOrder)
    }
}
extension Array {
    mutating func swapAt(i: Int, _ j: Int) {
        swap(&self[i], &self[j])
    }
    func reversed() -> Array {
        return self.reverse()
    }
    mutating func reverse() {
        self = self.reversed()
    }
    func enumerated() -> EnumerateSequence<[Element]> {
        return self.enumerate()
    }
    init(repeating: Element, count: Int) {
        self.init(count: count, repeatedValue: repeating)
    }
}
extension _ArrayType where Generator.Element == String {
    func joined(separator separator: String = "") -> String {
        return self.joinWithSeparator(separator)
    }
}
extension Range {
    func reversed() -> [Element] {
        return self.reverse()
    }
}
func stride<T: Strideable>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T> {
    return start.stride(to: end, by: stride)
}
prefix operator * { }
infix operator ** {
    precedence 155      // 乗除算より強く，ビットシフトより弱い
    associativity right // 右結合
}
#endif
prefix func * <T> (a: [T]) -> (T, T)             { return (a[0], a[1]) }
prefix func * <T> (a: [T]) -> (T, T, T)          { return (a[0], a[1], a[2]) }
prefix func * <T> (a: [T]) -> (T, T, T, T)       { return (a[0], a[1], a[2], a[3]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T)    { return (a[0], a[1], a[2], a[3], a[4]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T, T) { return (a[0], a[1], a[2], a[3], a[4], a[5]) }
func **(lhs: Int, rhs: Int) -> Int {
    return Int(pow(Double(lhs), Double(rhs)))
}
func **(lhs: Int, rhs: Double) -> Double {
    return pow(Double(lhs), rhs)
}
func * <Element> (lhs: [Element], rhs: Int) -> [Element] {
    return (0..<rhs).reduce([]){a,_ in a+lhs}
}
func *(lhs: String, rhs: Int) -> String {
    return (0..<rhs).reduce(""){s,_ in s+lhs}
}
let MOD = 10 ** 9 + 7
let alphabets = "abcdefghijklmnopqrstuvwxyz"
let ALPHABETS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
protocol Container {
    associatedtype Item
    mutating func append(item: Item)
    var count: Int { get }
    subscript(i: Int) -> Item { get }
}
struct Stack<Element>: Container {
    var items = [Element]()
    mutating func push(item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
    mutating func append(item: Element) {
        self.push(item)
    }
    var count: Int {
        return items.count
    }
    subscript(i: Int) -> Element {
        return items[i]
    }
}
struct Queue<Element>: Container {
    var items = [Element]()
    mutating func push(item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeFirst()
    }
    mutating func append(item: Element) {
        self.push(item)
    }
    var count: Int {
        return items.count
    }
    subscript(i: Int) -> Element {
        return items[i]
    }
}
struct Heap<Element: Comparable>: Container {
    var items = [Element]()
    mutating func push(item: Element) {
        var i = items.count
        while i > 0 {
            let p = (i - 1) / 2
            if items[p] <= item {
                break
            }
            if i == items.count {
                items.append(items[p])
            } else {
                items[i] = items[p]
            }
            i = p
        }
        if i == items.count {
            items.append(item)
        } else {
            items[i] = item
        }
    }
    mutating func pop() -> Element {
        let ret = items[0]
        let x = items[items.count - 1]
        var i: Int = 0
        while i * 2 + 1 < items.count - 1 {
            var a = i * 2 + 1
            let b = i * 2 + 2
            if b < items.count - 1 && items[b] < items[a] {
                a = b
            }
            if items[a] >= x {
                break
            }
            items[i] = items[a]
            i = a
        }
        items[i] = x
        _ = items.removeLast()
        return ret
    }
    mutating func append(item: Element) {
        self.push(item)
    }
    var count: Int {
        return items.count
    }
    subscript(i: Int) -> Element {
        return items[i]
    }
}
extension Array where Element: Equatable {
    func count(of value: Element) -> Int {
        return self.reduce(0){$0+($1==value ? 1 : 0)}
    }
}
extension String {
    func count(of value: Character) -> Int {
        return self.reduce(0){$0+($1==value ? 1 : 0)}
    }
    subscript(i: Int) -> Character {
        return self.map{$0}[i]
    }
}
func readInt() -> Int? {
    return Int(readLine()!)
}
func readStringsSplit(by separator: Character = " ") -> [String] {
    return readLine()!.split(separator: separator).map{String($0)}
}
func readIntsSplit(by separator: Character = " ") -> [Int] {
    return readLine()!.split(separator: separator).map{Int($0)!}
}
func gcd(x: Int, _ y: Int) -> Int {
    return y>0 ? gcd(y, x%y) : x
}
func lcm(x: Int, _ y: Int) -> Int {
    return x * y / gcd(x, y)
}
func manhattanDistance(x1: Int, _ y1: Int, _ x2: Int, _ y2: Int) -> Int {
    return abs(x1 - x2) + abs(y1 - y2)
}
func euclideanDistance(x1: Int, _ y1: Int, _ x2: Int, _ y2: Int) -> Double {
    return sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
}

/*************** メインプログラム ***************/

let N = readInt()!
let A = readIntsSplit()
let B = readIntsSplit()
let C = readIntsSplit()
var ans = 0
for i in 0..<N {
    ans += B[A[i]-1]
    if 0 < i && A[i-1] == A[i]-1 {
        ans += C[A[i]-2]
    }
}
print(ans)


let n = Int(readLine()!)!

let a = readLine()!.characters.split{$0 == " "}.map{ Int(String($0))! }
let b = readLine()!.characters.split{$0 == " "}.map{ Int(String($0))! }
let c = readLine()!.characters.split{$0 == " "}.map{ Int(String($0))! }

var ret = 0

for i in 0..<a.count {
  ret += b[a[i] - 1]
  if (i != 0) && (a[i] == a[i - 1] + 1) {
    ret += c[a[i - 1] - 1]
  }
}

print(ret)


import Foundation
func readInts() -> [Int] {
    return readLine()!.split(separator: " ").map { Int($0)! }
}
let n=Int(readLine()!)!
var aa=readInts()
var bb=readInts()
var cc=readInts()
var before=0
var ans=0
for a in aa{
  ans+=bb[a-1]
  if before==a-1{
    ans+=cc[a-2]
  }
  before=a
}
print(ans)


const stdin = require('fs').readFileSync('/dev/stdin', 'utf8').trim()

const input = stdin.split('\n')

const n = Number(input[0])
const a = input[1].split(' ').map(Number)
const b = input[2].split(' ').map(Number)
const c = input[3].split(' ').map(Number)

const ans = () => {
  let prevFood = -100
  let count = 0
  for (let i = 0; i < n; i++) {
    const food = a[i] - 1

    const m = b[food]

    const additionalM = food === prevFood + 1 ? c[food - 1] : 0

    count += m + additionalM

    prevFood = food
  }

  console.log(count)
}

ans()


function solve() {
    const input = (require('fs').readFileSync("/dev/stdin", "utf8") as string).split("\n");
    const N = +input[0];
    const A = input[1].split(" ").map((x: string): number => +x);
    const B = input[2].split(" ").map((x: string): number => +x);
    const C = input[3].split(" ").map((x: string): number => +x);

    let ans = 0;
    let prev = -1;
    for (let i = 0; i < N; i++) {
        ans += B[A[i] - 1];
        if (prev + 1 == A[i]) {
            ans += C[A[i] - 1 - 1];
        }
        prev = A[i];
    }
    console.log(ans);
}

solve();


import * as fs from "fs"
const NUMBER_MIN = Math.ceil(Number.MIN_SAFE_INTEGER / 2)

const process = (n: number, a: number[], b: number[], c: number[]): string => {
  let lastEat = NUMBER_MIN
  let res = 0

  for (let i = 0; i < n; i++) {
    const ryouri = a[i]
    const manzoku = b[ryouri - 1]
    res += manzoku
    if (lastEat + 1 === ryouri - 1) {
      res += c[ryouri - 2]
    }
    lastEat = ryouri - 1
  }

  return "" + res
}

const Main = (input: string): string => {
  const aa: string[][] = input.split("\n").map((e) => e.split(" "))
  const na0: number[] = aa[0].map((e) => parseInt(e))
  const [n] = na0

  const res =
    process(
      n,
      aa[1].map((e) => parseInt(e)),
      aa[2].map((e) => parseInt(e)),
      aa[3].map((e) => parseInt(e))
    ) + ""
  console.log(res)
  return res
}
Main(fs.readFileSync("/dev/stdin", "utf8"))


function main(input) {
    const lines = input.split('\n');
    const names = lines[1].split(' ').map(item => +item)
    const manzoku = lines[2].split(' ').map(item => +item)
    const manzoku_a = lines[3].split(' ').map(item => +item)

    let res = 0
    for (let i = 0; i < names.length; i++) {
        if (i > 0) {
            if (names[i] - 1 === names[i - 1]) {
                res += manzoku_a[i]
            }
        }

        res += manzoku[i]
    }
    console.log(res)
}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));