#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());

struct node{
   int l, r;
   ll val=1e18;
   ll lazy=0;
   node *lef, *righ;
};
void build(int l, int r, node* nod){
   nod->l = l;
   nod->r = r;
   if(l==r){
        nod->val=0;
       return;
   }
   nod->lef = new node;
   nod->righ = new node;
   int mid = (l+r)/2;
   build(l, mid, nod->lef);
   build(mid+1, r, nod->righ);
}
void push(node* nod){
   nod->val+=nod->lazy;
   if(nod->l!=nod->r){
       nod->lef->lazy+=nod->lazy;
       nod->righ->lazy+=nod->lazy;
   }
   nod->lazy=0;
}
void upd(int l, int r, node* nod, ll val){
   push(nod);
   if(l>nod->r||r<nod->l){
       return;
   }
   if(l<=nod->l&&r>=nod->r){
       nod->lazy += val;
       push(nod);
       return;
   }
   upd(l, r, nod->lef, val);
   upd(l, r, nod->righ, val);
   nod->val = min(nod->lef->val, nod->righ->val);
}
node* st = new node;

ll a[200001];
ll p[200001];

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

    int n; cin>>n;
    for(int i=1; i<=n; i++){
        cin>>p[i];
    }
    for(int i=1; i<=n; i++){
        cin>>a[i];
    }
    build(1, n, st);
    for(int i=1; i<=n; i++){
        upd(p[i], n, st, a[i]);
    }
    ll ans = 1e18;
    for(int i=1; i<n; i++){
        upd(p[i], n, st, -a[i]);
        upd(1, p[i]-1, st, a[i]);
        ans = min(ans,st->val);
    }
    cout<<ans;
}


#include <iostream>

using namespace std;

long long MAX_VAL = 9223372036854775807;

void printArray(long long *arr, int length){
	for(int i=0;i<length;++i){
		cout << arr[i] << " ";
	}
	cout << endl;
}

void buildHelper(int ind, int l, int r, long long *segTree, long long *data){
	if (l == r){
		segTree[ind] = data[l];
	} else {
		int m = (l+r)/2;
		buildHelper(2*ind+1,l,m,segTree,data);
		buildHelper(2*ind+2,m+1,r,segTree,data);
		segTree[ind] = min(segTree[2*ind+1],segTree[2*ind+2]);
	}
}

void build(int n, long long *segTree, long long *data){
	buildHelper(0,0,n-1,segTree,data);
}

// l and r are the ranges that have to be update.
// L and R are just the ranges of the segTree for reference
void updateHelper(int ind, int l, int r, int L, int R, long long *segTree, long long delta, long long *lazy){
	if(l > r){
		return;
	}
	if(l == L && r == R){
		segTree[ind] += delta;
		lazy[ind] += delta;
	} else {
		int m = (L+R)/2;
		updateHelper(2*ind+1,l,min(m,r),L,m,segTree,delta, lazy);
		updateHelper(2*ind+2,max(l,m+1),r,m+1,R,segTree,delta, lazy);
		segTree[ind] = min(segTree[2*ind+1],segTree[2*ind+2]);
	}
}

void update(int l, int r, int n, long long *segTree, long long delta, long long *lazy){
	updateHelper(0,l,r,0,n-1,segTree,delta, lazy);
}

void push(int ind, long long *segTree, long long *lazy){
	if (lazy[ind] != 0){
		segTree[2*ind+1] += lazy[ind];
		lazy[2*ind+1] = lazy[ind];
		segTree[2*ind+2] += lazy[ind];
		lazy[2*ind+2] = lazy[ind];
		lazy[ind] = 0;
	}
}

long long getHelper(int ind, int l, int r, int L, int R, long long *segTree, long long *lazy){
	if(l > r){
		return MAX_VAL;
	}
	push(ind, segTree, lazy);
	if (l == L and r == R){
		return segTree[ind];
	}
	int m = (L+R)/2;
	return min(getHelper(2*ind+1, l, min(r,m), L, m, segTree, lazy),
			   getHelper(2*ind+2, max(l,m+1), r, m+1, R, segTree, lazy));
}

long long get(int l, int r, int n, long long *segTree, long long *lazy) {
	return getHelper(0, l, r, 0 , n-1, segTree, lazy);
}

int main() {
	int n;
	cin >> n;
	int p[n];
	long long a[n];
	for(int i=0;i<n;++i){
		cin >> p[i];
		--p[i];
	}
	int reverse_p[n]; // quick way of knowing index of values of permutation
	for(int i=0;i<n;++i){
		cin >> a[i];
		// gonna hijack this for loop for more work
		reverse_p[p[i]] = i;
	}
	// assume that val is -1, so we want all elements in the left set to be less or equal
	//  to -1. Which is gonna be none of them since they range from 0 to n-1. So this is equivalent
	//  to moving all elements to the right side.
	long long cost[n];
	cost[0] = a[0];
	for(int i=1;i<n;++i){
		cost[i] = a[i] + cost[i-1];
	}
	// now place this cost into our segment tree so we can do O(logn) updates and queries for
	//  min costs.
	long long lazy[4*n] = {0};
	long long segTree[4*n] = {0};
	build(n, segTree, cost);
	// now we have our base segtree
	// now we iterate from val=0 to n-1, where at each iteration we will want all elements smaller
	//  or equal to val to be in the left set and those greater in the right set.
	// The segTree allows us to consider all possible initially separations of the permutation p
	// That is the root, representing [0,n-1], is the minimum cost if we consider splitting at
	//  0,1,...,n-1. Note that splitting at n is not possible since this would leave the right set
	//  empty and the two sets are non empty.
	// we initially assumed a val of -1 when constructing the tree which implies moving everything
	//  to the right set. This will be our initial result
	long long res = get(0,n-2,n,segTree, lazy);
	for(int i=0;i<n;++i){
		int spot = reverse_p[i];
		// for split at index greater or equal to spot, we no longer need to move the val=i
		// to the right set, so we decrease that cost
		update(spot, n-1, n, segTree, -a[spot], lazy);
		// if(i==1){
		// 	printArray(segTree,4*n);
		// }
		// for split at index smaller than spot, we now need to move the val=i to the left set,
		//  so we add it to the cost
		update(0, spot-1, n, segTree, a[spot], lazy);
		// if(i==1){
		// 	printArray(segTree,4*n);
		// }
		res = min(get(0,n-2,n,segTree, lazy),res);
	}
	cout << res << endl;
}


#include <iostream>

using namespace std;

long long MAX_VAL = 9223372036854775807;

void printArray(long long *arr, int length){
	for(int i=0;i<length;++i){
		cout << arr[i] << " ";
	}
	cout << endl;
}

void buildHelper(int ind, int l, int r, long long *segTree, long long *data){
	if (l == r){
		segTree[ind] = data[l];
	} else {
		int m = (l+r)/2;
		buildHelper(2*ind+1,l,m,segTree,data);
		buildHelper(2*ind+2,m+1,r,segTree,data);
		segTree[ind] = min(segTree[2*ind+1],segTree[2*ind+2]);
	}
}

void build(int n, long long *segTree, long long *data){
	buildHelper(0,0,n-1,segTree,data);
}

void push(int ind, long long *segTree, long long *lazy, int L, int R){
	if (lazy[ind] != 0){
		if (R - L > 0) {
			segTree[2*ind+1] += lazy[ind];
			lazy[2*ind+1] += lazy[ind];
			segTree[2*ind+2] += lazy[ind];
			lazy[2*ind+2] += lazy[ind];
		}
		lazy[ind] = 0;
	}
}

// l and r are the ranges that have to be update.
// L and R are just the ranges of the segTree for reference
void updateHelper(int ind, int l, int r, int L, int R, long long *segTree, long long delta, long long *lazy){
	if(l > r){
		return;
	}
	if(l == L && r == R){
		segTree[ind] += delta;
		lazy[ind] += delta;
		push(ind, segTree, lazy, L, R);
		return;
	}
	push(ind, segTree, lazy, L, R);
	int m = (L+R)/2;
	updateHelper(2*ind+1,l,min(m,r),L,m,segTree,delta, lazy);
	updateHelper(2*ind+2,max(l,m+1),r,m+1,R,segTree,delta, lazy);
	segTree[ind] = min(segTree[2*ind+1],segTree[2*ind+2]);
}

void update(int l, int r, int n, long long *segTree, long long delta, long long *lazy){
	updateHelper(0,l,r,0,n-1,segTree,delta, lazy);
}

long long getHelper(int ind, int l, int r, int L, int R, long long *segTree, long long *lazy){
	if(l > r){
		return MAX_VAL;
	}
	push(ind, segTree, lazy, L, R);
	if (l == L and r == R){
		return segTree[ind];
	}
	int m = (L+R)/2;
	return min(getHelper(2*ind+1, l, min(r,m), L, m, segTree, lazy),
			   getHelper(2*ind+2, max(l,m+1), r, m+1, R, segTree, lazy));
}

long long get(int l, int r, int n, long long *segTree, long long *lazy) {
	return getHelper(0, l, r, 0 , n-1, segTree, lazy);
}

int main() {
	int n;
	cin >> n;
	int p[n];
	long long a[n];
	for(int i=0;i<n;++i){
		cin >> p[i];
		--p[i];
	}
	int reverse_p[n]; // quick way of knowing index of values of permutation
	for(int i=0;i<n;++i){
		cin >> a[i];
		// gonna hijack this for loop for more work
		reverse_p[p[i]] = i;
	}
	// assume that val is -1, so we want all elements in the left set to be less or equal
	//  to -1. Which is gonna be none of them since they range from 0 to n-1. So this is equivalent
	//  to moving all elements to the right side.
	long long cost[n];
	cost[0] = a[0];
	for(int i=1;i<n;++i){
		cost[i] = a[i] + cost[i-1];
	}
	// now place this cost into our segment tree so we can do O(logn) updates and queries for
	//  min costs.
	long long lazy[4*n] = {0};
	long long segTree[4*n] = {0};
	build(n, segTree, cost);
	// now we have our base segtree
	// now we iterate from val=0 to n-1, where at each iteration we will want all elements smaller
	//  or equal to val to be in the left set and those greater in the right set.
	// The segTree allows us to consider all possible initially separations of the permutation p
	// That is the root, representing [0,n-1], is the minimum cost if we consider splitting at
	//  0,1,...,n-1. Note that splitting at n is not possible since this would leave the right set
	//  empty and the two sets are non empty.
	// we initially assumed a val of -1 when constructing the tree which implies moving everything
	//  to the right set. This will be our initial result
	long long res = get(0,n-2,n,segTree, lazy);
	for(int i=0;i<n;++i){
		int spot = reverse_p[i];
		// for split at index greater or equal to spot, we no longer need to move the val=i
		// to the right set, so we decrease that cost
		update(spot, n-1, n, segTree, -a[spot], lazy);
		// for split at index smaller than spot, we now need to move the val=i to the left set,
		//  so we add it to the cost
		update(0, spot-1, n, segTree, a[spot], lazy);
		res = min(get(0,n-2,n,segTree, lazy),res);
	}
	cout << res << endl;
}


#include <iostream>

using namespace std;

long long MAX_VAL = 9223372036854775807;

void printArray(long long *arr, int length){
	for(int i=0;i<length;++i){
		cout << arr[i] << " ";
	}
	cout << endl;
}

void buildHelper(int ind, int l, int r, long long *segTree, long long *data){
	if (l == r){
		segTree[ind] = data[l];
	} else {
		int m = (l+r)/2;
		buildHelper(2*ind+1,l,m,segTree,data);
		buildHelper(2*ind+2,m+1,r,segTree,data);
		segTree[ind] = min(segTree[2*ind+1],segTree[2*ind+2]);
	}
}

void build(int n, long long *segTree, long long *data){
	buildHelper(0,0,n-1,segTree,data);
}

// l and r are the ranges that have to be update.
// L and R are just the ranges of the segTree for reference
void updateHelper(int ind, int l, int r, int L, int R, long long *segTree, long long delta){
	if(l > r){
		return;
	}
	if(L == R){
		segTree[ind] += delta;
	} else {
		int m = (L+R)/2;
		updateHelper(2*ind+1,l,min(m,r),L,m,segTree,delta);
		updateHelper(2*ind+2,max(l,m+1),r,m+1,R,segTree,delta);
		segTree[ind] = min(segTree[2*ind+1],segTree[2*ind+2]);
	}
}

void update(int l, int r, int n, long long *segTree, long long delta){
	updateHelper(0,l,r,0,n-1,segTree,delta);
}

long long getHelper(int ind, int l, int r, int L, int R, long long *segTree){
	if(l > r){
		return MAX_VAL;
	}
	if (l == L and r == R){
		return segTree[ind];
	}
	int m = (L+R)/2;
	return min(getHelper(2*ind+1, l, min(r,m), L, m, segTree),
			   getHelper(2*ind+2, max(l,m+1), r, m+1, R, segTree));
}

long long get(int l, int r, int n, long long *segTree) {
	return getHelper(0, l, r, 0 , n-1, segTree);
}

int main() {
	int n;
	cin >> n;
	int p[n];
	long long a[n];
	for(int i=0;i<n;++i){
		cin >> p[i];
		--p[i];
	}
	int reverse_p[n]; // quick way of knowing index of values of permutation
	for(int i=0;i<n;++i){
		cin >> a[i];
		// gonna hijack this for loop for more work
		reverse_p[p[i]] = i;
	}
	// assume that val is -1, so we want all elements in the left set to be less or equal
	//  to -1. Which is gonna be none of them since they range from 0 to n-1. So this is equivalent
	//  to moving all elements to the right side.
	long long cost[n];
	cost[0] = a[0];
	for(int i=1;i<n;++i){
		cost[i] = a[i] + cost[i-1];
	}
	// now place this cost into our segment tree so we can do O(logn) updates and queries for
	//  min costs.
	long long segTree[4*n] = {0};
	build(n, segTree, cost);
	// now we have our base segtree
	// now we iterate from val=0 to n-1, where at each iteration we will want all elements smaller
	//  or equal to val to be in the left set and those greater in the right set.
	// The segTree allows us to consider all possible initially separations of the permutation p
	// That is the root, representing [0,n-1], is the minimum cost if we consider splitting at
	//  0,1,...,n-1. Note that splitting at n is not possible since this would leave the right set
	//  empty and the two sets are non empty.
	// we initially assumed a val of -1 when constructing the tree which implies moving everything
	//  to the right set. This will be our initial result
	long long res = get(0,n-2,n,segTree);
	for(int i=0;i<n;++i){
		int spot = reverse_p[i];
		// for split at index greater or equal to spot, we no longer need to move the val=i
		// to the right set, so we decrease that cost
		update(spot, n-1, n, segTree, -a[spot]);
		// if(i==1){
		// 	printArray(segTree,4*n);
		// }
		// for split at index smaller than spot, we now need to move the val=i to the left set,
		//  so we add it to the cost
		update(0, spot-1, n, segTree, a[spot]);
		// if(i==1){
		// 	printArray(segTree,4*n);
		// }
		res = min(get(0,n-2,n,segTree),res);
	}
	cout << res << endl;
}


#include <iostream>

using namespace std;

long long MAX_VAL = 9223372036854775807;

void printArray(long long *arr, int length){
	for(int i=0;i<length;++i){
		cout << arr[i] << " ";
	}
	cout << endl;
}

void buildHelper(int ind, int l, int r, long long *segTree, long long *data){
	if (l == r){
		segTree[ind] = data[l];
	} else {
		int m = (l+r)/2;
		buildHelper(2*ind+1,l,m,segTree,data);
		buildHelper(2*ind+2,m+1,r,segTree,data);
		segTree[ind] = min(segTree[2*ind+1],segTree[2*ind+2]);
	}
}

void build(int n, long long *segTree, long long *data){
	buildHelper(0,0,n-1,segTree,data);
}

// l and r are the ranges that have to be update.
// L and R are just the ranges of the segTree for reference
void updateHelper(int ind, int l, int r, int L, int R, long long *segTree, long long delta, long long *lazy){
	if(l > r){
		return;
	}
	if(l == L && r == R){
		segTree[ind] += delta;
		lazy[ind] += delta;
	} else {
		int m = (L+R)/2;
		updateHelper(2*ind+1,l,min(m,r),L,m,segTree,delta, lazy);
		updateHelper(2*ind+2,max(l,m+1),r,m+1,R,segTree,delta, lazy);
		segTree[ind] = min(segTree[2*ind+1],segTree[2*ind+2]);
	}
}

void update(int l, int r, int n, long long *segTree, long long delta, long long *lazy){
	updateHelper(0,l,r,0,n-1,segTree,delta, lazy);
}

void push(int ind, long long *segTree, long long *lazy){
	if (lazy[ind] != 0){
		segTree[2*ind+1] += lazy[ind];
		lazy[2*ind+1] = lazy[ind];
		segTree[2*ind+2] += lazy[ind];
		lazy[2*ind+2] = lazy[ind];
		lazy[ind] = 0;
	}
}

long long getHelper(int ind, int l, int r, int L, int R, long long *segTree, long long *lazy){
	if(l > r){
		return MAX_VAL;
	}
	if (l == L and r == R){
		return segTree[ind];
	}
	push(ind, segTree, lazy);
	int m = (L+R)/2;
	return min(getHelper(2*ind+1, l, min(r,m), L, m, segTree, lazy),
			   getHelper(2*ind+2, max(l,m+1), r, m+1, R, segTree, lazy));
}

long long get(int l, int r, int n, long long *segTree, long long *lazy) {
	return getHelper(0, l, r, 0 , n-1, segTree, lazy);
}

int main() {
	int n;
	cin >> n;
	int p[n];
	long long a[n];
	for(int i=0;i<n;++i){
		cin >> p[i];
		--p[i];
	}
	int reverse_p[n]; // quick way of knowing index of values of permutation
	for(int i=0;i<n;++i){
		cin >> a[i];
		// gonna hijack this for loop for more work
		reverse_p[p[i]] = i;
	}
	// assume that val is -1, so we want all elements in the left set to be less or equal
	//  to -1. Which is gonna be none of them since they range from 0 to n-1. So this is equivalent
	//  to moving all elements to the right side.
	long long cost[n];
	cost[0] = a[0];
	for(int i=1;i<n;++i){
		cost[i] = a[i] + cost[i-1];
	}
	// now place this cost into our segment tree so we can do O(logn) updates and queries for
	//  min costs.
	long long lazy[4*n] = {0};
	long long segTree[4*n] = {0};
	build(n, segTree, cost);
	// now we have our base segtree
	// now we iterate from val=0 to n-1, where at each iteration we will want all elements smaller
	//  or equal to val to be in the left set and those greater in the right set.
	// The segTree allows us to consider all possible initially separations of the permutation p
	// That is the root, representing [0,n-1], is the minimum cost if we consider splitting at
	//  0,1,...,n-1. Note that splitting at n is not possible since this would leave the right set
	//  empty and the two sets are non empty.
	// we initially assumed a val of -1 when constructing the tree which implies moving everything
	//  to the right set. This will be our initial result
	long long res = get(0,n-2,n,segTree, lazy);
	for(int i=0;i<n;++i){
		int spot = reverse_p[i];
		// for split at index greater or equal to spot, we no longer need to move the val=i
		// to the right set, so we decrease that cost
		update(spot, n-1, n, segTree, -a[spot], lazy);
		// if(i==1){
		// 	printArray(segTree,4*n);
		// }
		// for split at index smaller than spot, we now need to move the val=i to the left set,
		//  so we add it to the cost
		update(0, spot-1, n, segTree, a[spot], lazy);
		// if(i==1){
		// 	printArray(segTree,4*n);
		// }
		res = min(get(0,n-2,n,segTree, lazy),res);
	}
	cout << res << endl;
}


 #include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<stack>
#include<algorithm>
#include<map>
#include<queue>
#define ll long long
#define sd(n) scanf("%d",&n)
#define sf(n) scanf("%lf",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define ss(str) scanf("%s",str)
#define pd(n) printf("%d",n)
#define plf(n) printf("%lf",n)
#define mm(a,n) memset(a,n,sizeof(a))
#define tmp(x) std::cout<<"& "<<(x)<<" &\n"
#define rep(i,a,b) for(int i=(a);i<(b);++i)
using namespace std;
const int maxn=2e5+100;
const int mo=998244353;
int n,p[maxn];
ll a[maxn],v[maxn],ans;
struct Node{
    int l,r,rs,ls;ll val,lz;
}node[maxn<<2];
int cnt=1;
inline void build(int l,int r,int x){
    node[x].l=l,node[x].r=r;//
	if(l==r){
		node[x].val=v[cnt++];
		return;
	}
    int mid=(l+r)>>1;
        build(l,mid,node[x].ls=2*x),
        build(mid+1,r,node[x].rs=2*x+1);

}
void add(int l,int r,ll val,int x){
    if(l<=node[x].l&&r>=node[x].r){
	node[x].lz+=val;return ;
	}
    else{
        if(node[x].ls)add(l,r,val,node[x].ls);
        if(node[x].rs)add(l,r,val,node[x].rs);
    }
}
void update(int x){
    if(node[x].l==node[x].r){
        node[x].val+=node[x].lz;
		node[x].lz=0;
		return;
    }
    if(node[x].lz){
//    	tmp(x);
        int ls=node[x].ls,rs=node[x].rs;
        node[ls].lz+=node[x].lz,node[rs].lz+=node[x].lz;
        node[x].lz=0;
    }
    if(node[x].ls)update(node[x].ls);
	if(node[x].rs)update(node[x].rs);
}
void dfs(int x){
	if(node[x].val!=0)ans=min(node[x].val,ans);
	if(node[x].ls)dfs(node[x].ls);
	if(node[x].rs)dfs(node[x].rs);

}
int pos[maxn];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i)scanf("%d",&p[i]),pos[p[i]]=i;
    for(int i=1;i<=n;++i)scanf("%I64d",&a[i]);
    ans=min(a[1],a[n]);
    if(a[1]==1||a[n]==n)ans=0;
    v[1]=(p[1]==1)?0:a[1];
    for(int i=2;i<=n;++i){
        if(p[i]>i)v[i]=v[i-1]+a[pos[p[i]]]+a[i];
        else v[i]=v[i-1];
    }build(1,n,1);
    for(int i=2;i<n;++i){
        if(p[i]<i){
        	add(i,n,-a[pos[p[i]]],1);
		}
    }
    update(1);
	dfs(1);
    printf("%I64d",ans);
    return 0;
}


 #include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<stack>
#include<algorithm>
#include<map>
#include<queue>
#define ll long long
#define sd(n) scanf("%d",&n)
#define sf(n) scanf("%lf",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define ss(str) scanf("%s",str)
#define pd(n) printf("%d",n)
#define plf(n) printf("%lf",n)
#define mm(a,n) memset(a,n,sizeof(a))
#define tmp(x) std::cout<<"& "<<(x)<<" &\n"
#define rep(i,a,b) for(int i=(a);i<(b);++i)
using namespace std;
const int maxn=2e5+100;
const int mo=998244353;
int n,p[maxn];
ll a[maxn],v[maxn],ans;
struct Node{
    int l,r,rs,ls;ll val,lz;
}node[maxn<<2];
int cnt=1;
inline void build(int l,int r,int x){
    node[x].l=l,node[x].r=r;//
	if(l==r){
		node[x].val=v[cnt++];
		return;
	}
    int mid=(l+r)>>1;
        build(l,mid,node[x].ls=2*x),
        build(mid+1,r,node[x].rs=2*x+1);

}
void add(int l,int r,ll val,int x){
    if(l<=node[x].l&&r>=node[x].r){
	node[x].lz+=val;return ;
	}
    else{
        if(node[x].ls)add(l,r,val,node[x].ls);
        if(node[x].rs)add(l,r,val,node[x].rs);
    }
}
void update(int x){
    if(node[x].l==node[x].r){
        node[x].val+=node[x].lz;
		node[x].lz=0;
		return;
    }
    if(node[x].lz){
//    	tmp(x);
        int ls=node[x].ls,rs=node[x].rs;
        node[ls].lz+=node[x].lz,node[rs].lz+=node[x].lz;
        node[x].lz=0;
    }
    if(node[x].ls)update(node[x].ls);
	if(node[x].rs)update(node[x].rs);
}
void dfs(int x){
	if(node[x].val!=0)ans=min(node[x].val,ans);
	if(node[x].ls)dfs(node[x].ls);
	if(node[x].rs)dfs(node[x].rs);

}
int pos[maxn];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i)scanf("%d",&p[i]),pos[p[i]]=i;
    for(int i=1;i<=n;++i)scanf("%lld",&a[i]);
    ans=min(a[1],a[n]);
    if(a[1]==1||a[n]==n)ans=0;
    v[1]=(p[1]==1)?0:a[1];
    for(int i=2;i<=n;++i){
        if(p[i]>i)v[i]=v[i-1]+a[pos[p[i]]]+a[i];
        else v[i]=v[i-1];
    }build(1,n,1);
    for(int i=1;i<=n;++i)cout<<v[i]<<" ";cout<<endl;
    for(int i=2;i<n;++i){
        if(p[i]<i){
        	add(i,n,-a[pos[p[i]]],1);
		}
    }
    update(1);
	dfs(1);
    printf("%lld",ans);
    return 0;
}


#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<stack>
#include<algorithm>
#include<map>
#include<queue>
#define ll long long
#define sd(n) scanf("%d",&n)
#define sf(n) scanf("%lf",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define ss(str) scanf("%s",str)
#define pd(n) printf("%d",n)
#define plf(n) printf("%lf",n)
#define mm(a,n) memset(a,n,sizeof(a))
#define tmp(x) std::cout<<"& "<<(x)<<" &\n"
#define rep(i,a,b) for(int i=(a);i<(b);++i)
using namespace std;
const int maxn=2e5+100;
const int mo=998244353;
int n,p[maxn],cnt2;
ll a[maxn],v[maxn],ans,an[maxn];
struct Node{
    int l,r,rs,ls;ll val,lz;
}node[maxn<<2];
int cnt=1;
inline void build(int l,int r,int x){
    node[x].l=l,node[x].r=r;//
    if(l==r){
        node[x].val=v[cnt++],an[cnt2++]=x;
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,node[x].ls=2*x),
    build(mid+1,r,node[x].rs=2*x+1);

}
void add(int l,int r,ll val,int x){
    if(l<=node[x].l&&r>=node[x].r){
        node[x].lz+=val;return ;
    }
    else{
        if(node[x].ls)add(l,r,val,node[x].ls);
        if(node[x].rs)add(l,r,val,node[x].rs);
    }
}
void update(int x){
    if(node[x].l==node[x].r){
        node[x].val+=node[x].lz;
        node[x].lz=0;
        return;
    }
    if(node[x].lz){
        node[node[x].ls].lz+=node[x].lz,node[node[x].rs].lz+=node[x].lz;
        node[x].lz=0;
    }
    if(node[x].ls)update(node[x].ls);
    if(node[x].rs)update(node[x].rs);
}
/*void dfs(int x){
    if(node[x].val!=0)ans=min(node[x].val,ans);
    if(node[x].ls)dfs(node[x].ls);
    if(node[x].rs)dfs(node[x].rs);

}*/
int pos[maxn];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i)scanf("%d",&p[i]),pos[p[i]]=i;
    for(int i=1;i<=n;++i)scanf("%I64d",&a[i]);
    ans=min(a[1],a[n]);
    if(a[1]==1||a[n]==n)ans=0;
    v[1]=(p[1]==1)?0:a[1];
    for(int i=2;i<=n;++i){
        if(p[i]>i)v[i]=v[i-1]+a[pos[p[i]]]+a[i];
        else v[i]=v[i-1];
    }
    build(1,n,1);
    for(int i=2;i<n;++i){
        if(p[i]<i){
            add(i,n,-a[pos[p[i]]],1);
        }
    }
    update(1);
    for(int i=0;i<cnt2;++i)if(an[i])ans=min(node[an[i]].val,ans);
//    dfs(1);
    printf("%I64d",ans);
    return 0;
}


#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<stack>
#include<algorithm>
#include<map>
#include<queue>
#define ll long long
#define sd(n) scanf("%d",&n)
#define sf(n) scanf("%lf",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define ss(str) scanf("%s",str)
#define pd(n) printf("%d",n)
#define plf(n) printf("%lf",n)
#define mm(a,n) memset(a,n,sizeof(a))
#define tmp(x) std::cout<<"& "<<(x)<<" &\n"
#define rep(i,a,b) for(int i=(a);i<(b);++i)
using namespace std;
const int maxn=2e5+100;
const int mo=998244353;
int n,p[maxn];
int a[maxn];
ll ans,v[maxn];
struct Node{
    int l,r;ll val,lz;
}node[maxn<<2];
int cnt=1;
inline int read() {
    int x=0,f=1;
    char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
inline void build(int l,int r,int x){
    node[x].l=l,node[x].r=r;
    if(l==r){
        node[x].val=v[l];//
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,x<<1),            build(mid+1,r,(x<<1)+1);
    node[x].val=min(node[x<<1].val,node[1+(x<<1)].val);//
}
inline void add(int l,int r,int val,int x){
//    cout<<x<<" "<<l<<" "<<r<<" "<<node[x].l<<" "<<node[x].r<<endl;
//    if(!node[x].r)return;
    if(l<=node[x].l&&r>=node[x].r){
        node[x].val+=val,node[x].lz+=val;return ;
    }
    if(node[x].lz&&l!=r){
        node[x<<1].val+=node[x].lz,node[1+(x<<1)].val+=node[x].lz;
        node[x<<1].lz+=node[x].lz,node[1+(x<<1)].lz+=node[x].lz;
        node[x].lz=0;
    }
    int mid=node[x].l+node[x].r>>1;
    if(l<=mid)add(l,r,val,x<<1);
    if(r>mid)add(l,r,val,(x<<1)+1);
    node[x].val=min(node[x<<1].val,node[(x<<1)+1].val);
}
int pos[maxn];
int main(){
    n=read();register int i;
    for(i=1;i<=n;++i){p[i]=read();pos[p[i]]=i;
    }
    for(i=1;i<=n;++i)a[i]=read();
    ans=min(a[1],a[n]);
    if(p[1]==1||p[n]==n)ans=0;    //cout<<ans<<endl;
    for(i=1;i<=n;++i)
        v[i]=v[i-1]+a[i];
    build(1,n-1,1);
    for(i=1;i<=n;++i){
        if(pos[i]!=n)add(pos[i],n-1,-a[pos[i]],1);
        if(pos[i]!=1)add(1,pos[i]-1,a[pos[i]],1);
        ans=min(ans,node[1].val);
    }
    printf("%I64d",ans);
    return 0;
}


#include<bits/stdc++.h>
#define lson(p) p<<1
#define rson(p) p<<1|1
using namespace std;
typedef long long ll;
const int maxn=2e5;
int a[maxn+5],p[maxn+5],pos[maxn+5];
ll c[maxn+5];
int n;
struct SegmentTree
{
    ll mn,lazy;
}b[4*maxn+5];
void pushup(int p)
{
    b[p].mn=min(b[lson(p)].mn,b[rson(p)].mn);
}
void build(int p,int l,int r)
{
    b[p].lazy=0;
    if (l==r) {
        b[p].mn=c[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lson(p),l,mid);
    build(rson(p),mid+1,r);
    pushup(p);
}
void pushdown(int p)
{
    if (b[p].lazy) {
        b[lson(p)].mn+=b[p].lazy; b[lson(p)].lazy+=b[p].lazy;
        b[rson(p)].mn+=b[p].lazy; b[rson(p)].lazy+=b[p].lazy;
        b[p].lazy=0;
    }
}
void modify(int p,int l,int r,int L,int R,int val)
{
    if (L<=l&&r<=R) {
        b[p].mn+=val; b[p].lazy+=val;
        return ;
    }
    int mid=(l+r)>>1;
    pushdown(p);
    if (L<=mid) modify(lson(p),l,mid,L,R,val);
    if (R>mid) modify(rson(p),mid+1,r,L,R,val);
    pushup(p);
}
ll getMn(int p,int l,int r,int L,int R)
{
    if (L<=l&&r<=R) return b[p].mn;
    int mid=(l+r)>>1;
    pushdown(p);
    if (R<=mid) return getMn(lson(p),l,mid,L,R);
    else if (L>mid) return getMn(rson(p),mid+1,r,L,R);
    else return min(getMn(lson(p),l,mid,L,R),getMn(rson(p),mid+1,r,L,R));
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++) {
        scanf("%d",&p[i]);
        pos[p[i]]=i;
    }
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    ll sum=0;
    bool bo=false;
    for (int i=1;i<=n;i++) {
        if (p[i]!=1) sum+=a[i];
        else bo=true;
        if (!bo) c[i]=sum+a[pos[1]];
        else c[i]=sum;
    }
    build(1,1,n);
    ll ans=min(ans,getMn(1,1,n,1,n-1));
    for (int i=2;i<=n;i++) {
        int p=pos[i];
        if (p>1) modify(1,1,n,1,p-1,a[p]);
        modify(1,1,n,p,n,-a[p]);
        ans=min(ans,getMn(1,1,n,1,n-1));
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
#define lson(p) p<<1
#define rson(p) p<<1|1
using namespace std;
typedef long long ll;
const int maxn=2e5;
int a[maxn+5],p[maxn+5],pos[maxn+5];
ll c[maxn+5];
int n;
struct SegmentTree
{
    ll mn,lazy;
}b[4*maxn+5];
void pushup(int p)
{
    b[p].mn=min(b[lson(p)].mn,b[rson(p)].mn);
}
void build(int p,int l,int r)
{
    b[p].lazy=0;
    if (l==r) {
        b[p].mn=c[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lson(p),l,mid);
    build(rson(p),mid+1,r);
    pushup(p);
}
void pushdown(int p)
{
    if (b[p].lazy) {
        b[lson(p)].mn+=b[p].lazy; b[lson(p)].lazy+=b[p].lazy;
        b[rson(p)].mn+=b[p].lazy; b[rson(p)].lazy+=b[p].lazy;
        b[p].lazy=0;
    }
}
void modify(int p,int l,int r,int L,int R,int val)
{
    if (L<=l&&r<=R) {
        b[p].mn+=val; b[p].lazy+=val;
        return ;
    }
    int mid=(l+r)>>1;
    pushdown(p);
    if (L<=mid) modify(lson(p),l,mid,L,R,val);
    if (R>mid) modify(rson(p),mid+1,r,L,R,val);
    pushup(p);
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++) {
        scanf("%d",&p[i]);
        pos[p[i]]=i;
    }
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    ll sum=0;
    bool bo=false;
    for (int i=1;i<=n;i++) {
        if (p[i]!=1) sum+=a[i];
        else bo=true;
        if (!bo) c[i]=sum+a[pos[1]];
        else c[i]=sum;
    }
    build(1,1,n);
    ll ans=a[1];
    ans=min(ans,1LL*a[n]);
    for (int i=2;i<n;i++) {
        int p=pos[i];
        if (p>1) modify(1,1,n,1,p-1,a[p]);
        modify(1,1,n,p,n,-a[p]);
        ans=min(ans,b[1].mn);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
#define lson(p) p<<1
#define rson(p) p<<1|1
using namespace std;
typedef long long ll;
const int maxn=3e5;
int a[maxn+5],p[maxn+5],pos[maxn+5];
ll c[maxn+5];
int n;
struct SegmentTree
{
    ll mn,lazy;
}b[4*maxn+5];
void pushup(int p)
{
    b[p].mn=min(b[lson(p)].mn,b[rson(p)].mn);
}
void build(int p,int l,int r)
{
    b[p].lazy=0;
    if (l==r) {
        b[p].mn=c[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lson(p),l,mid);
    build(rson(p),mid+1,r);
    pushup(p);
}
void pushdown(int p)
{
    if (b[p].lazy) {
        b[lson(p)].mn+=b[p].lazy; b[lson(p)].lazy+=b[p].lazy;
        b[rson(p)].mn+=b[p].lazy; b[rson(p)].lazy+=b[p].lazy;
        b[p].lazy=0;
    }
}
void modify(int p,int l,int r,int L,int R,int val)
{
    if (L<=l&&r<=R) {
        b[p].mn+=val; b[p].lazy+=val;
        return ;
    }
    int mid=(l+r)>>1;
    pushdown(p);
    if (L<=mid) modify(lson(p),l,mid,L,R,val);
    if (R>mid) modify(rson(p),mid+1,r,L,R,val);
    pushup(p);
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++) {
        scanf("%d",&p[i]);
        pos[p[i]]=i;
    }
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    ll sum=0;
    bool bo=false;
    for (int i=1;i<=n;i++) {
        if (p[i]!=1) sum+=a[i];
        else bo=true;
        if (!bo) c[i]=sum+a[pos[1]];
        else c[i]=sum;
    }
    build(1,1,n);
    ll ans=a[1];
    ans=min(ans,1LL*a[n]);
    for (int i=2;i<n;i++) {
        int p=pos[i];
        if (p>1) modify(1,1,n,1,p-1,a[p]);
        modify(1,1,n,p,n,-a[p]);
        ans=min(ans,b[1].mn);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
#define lson(p) p<<1
#define rson(p) p<<1|1
using namespace std;
typedef long long ll;
const int maxn=2e5;
int a[maxn+5],p[maxn+5],pos[maxn+5];
ll c[maxn+5];
int n;
struct SegmentTree
{
    ll mn,lazy;
}b[4*maxn+5];
void pushup(int p)
{
    b[p].mn=min(b[lson(p)].mn,b[rson(p)].mn);
}
void build(int p,int l,int r)
{
    b[p].lazy=0;
    if (l==r) {
        b[p].mn=c[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lson(p),l,mid);
    build(rson(p),mid+1,r);
    pushup(p);
}
void pushdown(int p)
{
    if (b[p].lazy) {
        b[lson(p)].mn+=b[p].lazy; b[lson(p)].lazy+=b[p].lazy;
        b[rson(p)].mn+=b[p].lazy; b[rson(p)].lazy+=b[p].lazy;
        b[p].lazy=0;
    }
}
void modify(int p,int l,int r,int L,int R,int val)
{
    if (L<=l&&r<=R) {
        b[p].mn+=val; b[p].lazy+=val;
        return ;
    }
    int mid=(l+r)>>1;
    pushdown(p);
    if (L<=mid) modify(lson(p),l,mid,L,R,val);
    if (R>mid) modify(rson(p),mid+1,r,L,R,val);
    pushup(p);
}
ll getMn(int p,int l,int r,int L,int R)
{
    if (L<=l&&r<=R) return b[p].mn;
    int mid=(l+r)>>1;
    pushdown(p);
    if (R<=mid) return getMn(lson(p),l,mid,L,R);
    else if (L>mid) return getMn(rson(p),mid+1,r,L,R);
    else return min(getMn(lson(p),l,mid,L,R),getMn(rson(p),mid+1,r,L,R));
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++) {
        scanf("%d",&p[i]);
        pos[p[i]]=i;
    }
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    ll sum=0;
    bool bo=false;
    for (int i=1;i<=n;i++) {
        if (p[i]!=1) sum+=a[i];
        else bo=true;
        if (!bo) c[i]=sum+a[pos[1]];
        else c[i]=sum;
    }
    build(1,1,n);
    ll ans=getMn(1,1,n,1,n-1);
    for (int i=2;i<=n;i++) {
        int p=pos[i];
        if (p>1) modify(1,1,n,1,p-1,a[p]);
        modify(1,1,n,p,n,-a[p]);
        ans=min(ans,getMn(1,1,n,1,n-1));
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
#define lson(p) p<<1
#define rson(p) p<<1|1
using namespace std;
typedef long long ll;
const int maxn=2e5;
int a[maxn+5],p[maxn+5],pos[maxn+5];
ll c[maxn+5];
int n;
struct SegmentTree
{
    ll mn,lazy;
}b[4*maxn+5];
void pushup(int p)
{
    b[p].mn=min(b[lson(p)].mn,b[rson(p)].mn);
}
void build(int p,int l,int r)
{
    b[p].lazy=0;
    if (l==r) {
        b[p].mn=c[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lson(p),l,mid);
    build(rson(p),mid+1,r);
    pushup(p);
}
void pushdown(int p)
{
    if (b[p].lazy) {
        b[lson(p)].mn+=b[p].lazy; b[lson(p)].lazy+=b[p].lazy;
        b[rson(p)].mn+=b[p].lazy; b[rson(p)].lazy+=b[p].lazy;
        b[p].lazy=0;
    }
}
void modify(int p,int l,int r,int L,int R,int val)
{
    if (L<=l&&r<=R) {
        b[p].mn+=val; b[p].lazy+=val;
        return ;
    }
    int mid=(l+r)>>1;
    pushdown(p);
    if (L<=mid) modify(lson(p),l,mid,L,R,val);
    if (R>mid) modify(rson(p),mid+1,r,L,R,val);
    pushup(p);
}
ll getMn(int p,int l,int r,int L,int R)
{
    if (L<=l&&r<=R) return b[p].mn;
    int mid=(l+r)>>1;
    pushdown(p);
    if (R<=mid) return getMn(lson(p),l,mid,L,R);
    else if (L>mid) return getMn(rson(p),mid+1,r,L,R);
    else return min(getMn(lson(p),l,mid,L,R),getMn(rson(p),mid+1,r,L,R));
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++) {
        scanf("%d",&p[i]);
        pos[p[i]]=i;
    }
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    ll sum=0;
    bool bo=false;
    for (int i=1;i<=n;i++) {
        if (p[i]!=1) sum+=a[i];
        else bo=true;
        if (!bo) c[i]=sum+a[pos[1]];
        else c[i]=sum;
    }
    build(1,1,n);
    ll ans=a[1];
    ans=min(ans,1LL*a[n]);
    ans=min(ans,getMn(1,1,n,1,n-1));
    for (int i=2;i<=n;i++) {
        int p=pos[i];
        if (p>1) modify(1,1,n,1,p-1,a[p]);
        modify(1,1,n,p,n,-a[p]);
        ans=min(ans,getMn(1,1,n,1,n-1));
    }
    printf("%I64d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
#define lson(p) p<<1
#define rson(p) p<<1|1
using namespace std;
typedef long long ll;
const int maxn=2e5;
int a[maxn+5],p[maxn+5],pos[maxn+5];
ll c[maxn+5];
int n;
struct SegmentTree
{
    ll mn,lazy;
}b[4*maxn+5];
void pushup(int p)
{
    b[p].mn=min(b[lson(p)].mn,b[rson(p)].mn);
}
void build(int p,int l,int r)
{
    b[p].lazy=0;
    if (l==r) {
        b[p].mn=c[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lson(p),l,mid);
    build(rson(p),mid+1,r);
    pushup(p);
}
void pushdown(int p)
{
    if (b[p].lazy) {
        b[lson(p)].mn+=b[p].lazy; b[lson(p)].lazy+=b[p].lazy;
        b[rson(p)].mn+=b[p].lazy; b[rson(p)].lazy+=b[p].lazy;
        b[p].lazy=0;
    }
}
void modify(int p,int l,int r,int L,int R,int val)
{
    if (L<=l&&r<=R) {
        b[p].mn+=val; b[p].lazy+=val;
        return ;
    }
    int mid=(l+r)>>1;
    pushdown(p);
    if (L<=mid) modify(lson(p),l,mid,L,R,val);
    if (R>mid) modify(rson(p),mid+1,r,L,R,val);
    pushup(p);
}
ll getMn(int p,int l,int r,int L,int R)
{
    if (L<=l&&r<=R) return b[p].mn;
    int mid=(l+r)>>1;
    pushdown(p);
    if (R<=mid) return getMn(lson(p),l,mid,L,R);
    else if (L>mid) return getMn(rson(p),mid+1,r,L,R);
    else return min(getMn(lson(p),l,mid,L,R),getMn(rson(p),mid+1,r,L,R));
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++) {
        scanf("%d",&p[i]);
        pos[p[i]]=i;
    }
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    ll sum=0;
    bool bo=false;
    for (int i=1;i<=n;i++) {
        if (p[i]!=1) sum+=a[i];
        else bo=true;
        if (!bo) c[i]=sum+a[pos[1]];
        else c[i]=sum;
    }
    build(1,1,n);
    ll ans=a[1];
    ans=min(ans,1LL*a[n]);
    for (int i=2;i<=n;i++) {
        int p=pos[i];
        if (p>1) modify(1,1,n,1,p-1,a[p]);
        modify(1,1,n,p,n,-a[p]);
        ans=min(ans,getMn(1,1,n,1,n-1));
    }
    printf("%I64d\n",ans);
    return 0;
}


#include <bits/stdc++.h>
/*#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define ull unsigned long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

template<typename T>
struct SegmTree {
    T n;
    vector<T> tree;

    SegmTree(T n, T dig = 0) {
        this->n = n;
        tree.assign(4 * n, dig);
    }

    void upd(int v, int l, int r, int ind, T val) {
        if (l > ind || r < ind) {
            return;
        }
        if (l == r) {
            tree[v] = val;
            return;
        }
        int md = (r + l) / 2;
        upd(v * 2, l, md, ind, val);
        upd(v * 2 + 1, md + 1, r, ind, val);
        tree[v] = tree[v * 2] + tree[v * 2 + 1];
    }

    ll get(int v, int l, int r, int tl, int tr) {
        if (l > tr || r < tl) {
            return 0;
        }
        if (l >= tl && r <= tr) {
            return tree[v];
        }
        int md = (l + r) / 2;
        return get(v * 2, l, md, tl, tr) +
            get(v * 2 + 1, md + 1, r, tl, tr);
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<int> p(n);
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        p[i] = nxt() - 1;
    }
    for (int i = 0; i < n; i++) {
        a[i] = nxt();
    }
    SegmTree<ll> t1(n, 0);
    SegmTree<ll> t2(n);
    for (int i = 0; i < n; i++) {
        t2.upd(1, 0, n - 1, p[i], a[i]);
    }

    ll ans = inf;
    for (int i = 0; i < n - 1; i++) {
        t2.upd(1, 0, n - 1, p[i], 0);
        t1.upd(1, 0, n - 1, p[i], a[p[i]]);
        ll sum1 = t2.get(1, 0, n - 1, 0, i) +
                t1.get(1, 0, n - 1, i + 1, n - 1);
        ll sum2 = min({t1.tree[1], t2.tree[1], sum1});
        ans = min(ans, sum2);
    }
    cout << ans;
    return 0;
}


#include <bits/stdc++.h>
/*#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define ull unsigned long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

template<typename T>
struct SegmTree {
    T n;
    vector<T> tree;

    SegmTree(T n, T dig = 0) {
        this->n = n;
        tree.assign(4 * n, dig);
    }

    void upd(int v, int l, int r, int ind, T val) {
        if (l > ind || r < ind) {
            return;
        }
        if (l == r) {
            tree[v] = val;
            return;
        }
        int md = (r + l) / 2;
        upd(v * 2, l, md, ind, val);
        upd(v * 2 + 1, md + 1, r, ind, val);
        tree[v] = tree[v * 2] + tree[v * 2 + 1];
    }

    ll get(int v, int l, int r, int tl, int tr) {
        if (l > tr || r < tl) {
            return 0;
        }
        if (l >= tl && r <= tr) {
            return tree[v];
        }
        int md = (l + r) / 2;
        return get(v * 2, l, md, tl, tr) +
            get(v * 2 + 1, md + 1, r, tl, tr);
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<int> p(n);
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        p[i] = nxt() - 1;
    }
    for (int i = 0; i < n; i++) {
        a[i] = nxt();
    }
    SegmTree<ll> t1(n, 0);
    SegmTree<ll> t2(n);
    for (int i = 0; i < n; i++) {
        t2.upd(1, 0, n - 1, p[i], a[i]);
    }

    ll ans = min(a[0], a[n - 1]);
    for (int i = 0; i < n - 1; i++) {
        t2.upd(1, 0, n - 1, p[i], 0);
        t1.upd(1, 0, n - 1, p[i], a[p[i]]);
        ll sum1 = t2.get(1, 0, n - 1, 0, i) +
                t1.get(1, 0, n - 1, i + 1, n - 1);
        ans = min(ans, sum1);
    }
    cout << ans;
    return 0;
}


#include <bits/stdc++.h>
/*#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define ull unsigned long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

struct SegmTree {
    int n;
    vector<ll> tree;
    vector<ll> to_add;
    SegmTree(int n) {
        this->n = n;
        tree.resize(n * 4 + 10);
        to_add.resize(n * 4 + 10);
    }

    void push(int v) {
        tree[v * 2] += to_add[v];
        tree[v * 2 + 1] += to_add[v];
        to_add[v * 2] += to_add[v];
        to_add[v * 2 + 1] += to_add[v];
        to_add[v] = 0;
    }

    void add(int v, int l, int r, int tl, int tr, ll x) {
        if (tl > r || l > tr || l > r || tl > tr) return;
        if (l >= tl && r <= tr) {
            tree[v] += x;
            to_add[v] += x;
            return;
        }
        int md = (l + r) / 2;
        push(v);
        add(v * 2, l, md, tl, tr, x);
        add(v * 2 + 1, md + 1, r, tl, tr, x);
        tree[v] = min(tree[v * 2], tree[v * 2 + 1]);
    }

    void add(int l, int r, ll x) {
        if (r >= l)
            add(1, 0, n - 1, l, r, x);
    }

    ll get(int v, int l, int r, int tl, int tr) {
        if (l > tr || tl > r) {
            return inf;
        }
        if (tl <= l && r <= tr) {
            return tree[v];
        }
        push(v);
        int md = (l + r) / 2;
        return min(get(v * 2, l, md, tl, tr),
            get(v * 2 + 1, md + 1, r, tl, tr));
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<int> p(n);
    vector<ll> a(n);
    SegmTree tree(n);
    for (int i = 0; i < n; i++) {
        p[i] = nxt() - 1;
    }
    for (int i = 0; i < n; i++) {
        a[i] = nxt();
        tree.add(p[i], n - 1, a[i]);
    }
    ll ans = min(a[0], a[n - 1]);
    for (int i = 0; i < n - 1; i++) {
        tree.add(0, p[i] - 1, a[i]);
        tree.add(p[i], n - 1, -a[i]);
        ans = min(ans, tree.tree[1]);
    }
    cout << ans;
    return 0;
}


#include <bits/stdc++.h>
/*#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;*/
#define itn int
#define all(c) c.begin(),c.end()
#define make_unique(x) sort(all((x))); (x).resize(unique(all((x))) - (x).begin())
#define ll long long
#define ull unsigned long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
using namespace std;

const ll N = 1e6 + 5, inf = 1e18, mod = 1e9 + 7;
const double PI = 3.1415926536;
int days[13] = {0, 31, 28, 31, 30, 31,30, 31, 31, 30, 31, 30, 31};

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& mas) {
    for (const auto& x : mas) {
        out << x << ' ';
    }
    out << '\n';
    return out;
}

bool is_prime(ll n) {
    for (ll i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

inline ll getPow(ll a, ll b) {
    ll res = 1ll, tp = a;
    while (b){
        if (b&1ll) {
            res *= tp;
        }
        tp *= tp;
     //   tp %= mod; res %= mod;
        b >>= 1ll;
    }
    return res;
}

ll vec_mult(const pll & t1, const pll & t2, const pll & t3) {
    const ll & x1 = t1.first, y1 = t1.second;
    const ll & x2 = t2.first, y2 = t2.second;
    const ll & x3 = t3.first, y3 = t3.second;
    return abs((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1));
}

void ok() {
    cout << "YES" << '\n';
}

void no() {
    cout << "NO" << '\n';
}

inline ll nxt() {
    ll x;
    cin >> x;
    return x;
}

template<typename T>
struct SegmTree {
    T n;
    vector<T> tree;

    SegmTree(T n, T dig = 0) {
        this->n = n;
        tree.assign(4 * n, dig);
    }

    void upd(int v, int l, int r, int ind, T val) {
        if (l > ind || r < ind) {
            return;
        }
        if (l == r) {
            tree[v] = val;
            return;
        }
        int md = (r + l) / 2;
        upd(v * 2, l, md, ind, val);
        upd(v * 2 + 1, md + 1, r, ind, val);
        tree[v] = tree[v * 2] + tree[v * 2 + 1];
    }

    ll get(int v, int l, int r, int tl, int tr) {
        if (l > tr || r < tl) {
            return 0;
        }
        if (l >= tl && r <= tr) {
            return tree[v];
        }
        int md = (l + r) / 2;
        return get(v * 2, l, md, tl, tr) +
            get(v * 2 + 1, md + 1, r, tl, tr);
    }
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n = nxt();
    vector<int> p(n);
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        p[i] = nxt() - 1;
    }
    for (int i = 0; i < n; i++) {
        a[i] = nxt();
    }
    SegmTree<ll> t1(n, 0);
    SegmTree<ll> t2(n);
    for (int i = 0; i < n; i++) {
        t2.upd(1, 0, n - 1, p[i], a[i]);
    }

    ll ans = min(a[0], a[n - 1]);
    for (int i = 0; i < n - 1; i++) {
        t2.upd(1, 0, n - 1, p[i], 0);
        t1.upd(1, 0, n - 1, p[i], a[i]);
        ll sum1 = t2.get(1, 0, n - 1, 0, i) +
                t1.get(1, 0, n - 1, i + 1, n - 1);
        ans = min(ans, sum1);
    }
    cout << ans;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef long double ld;

const int MSZ = (1<<18)*22;

ll val[MSZ];
int le[MSZ], ri[MSZ];

struct PersistentSegtree {
    //vector<ll> val;
    //vector<int> le, ri;
    int n, h, cur, latest;
    PersistentSegtree() {}
    PersistentSegtree(int sz) {
        h = 32 - __builtin_clz(sz);
        n = 1<<h;
        //val = vector<ll>((n+1)*(h+4), 0);
        //le = ri = vector<int>((n+1)*(h+4), 0);
        for (int i=1; i<n; ++i) {
            le[i] = i*2;
            ri[i] = i*2+1;
        }
        cur = 2*n-1;
        latest = 1;
    }
    int last() const {
        return latest;
    }
    int modify(int pos, ll amt, int root, int lv, int rv) {
        if (pos<lv || pos>=rv) return root;
        int now = ++cur;
        //////cerr << " NOW " << now << " VS ROOT " << root << " VS SIZE " << val.size() << endl;
        assert (now < MSZ);
        val[now] = val[root]+amt;
        //////cerr << " OLD " << val[root] << " (" << root << ") "<< " NEW " << val[now] << endl;
        if (rv-lv == 1) return now;

        int mv = (lv+rv)/2;
        le[now] = modify(pos, amt, le[root], lv, mv);
        ri[now] = modify(pos, amt, ri[root], mv, rv);
        return now;
    }
    int modify(int root, int pos, ll amt) {
        return latest = modify(pos, amt, root, 0, n);
    }
    ll query(int root, int l, int r, int lv, int rv) {
        if (r<=lv || rv<=l) return 0;
        if (l<=lv && rv<=r) {
            return val[root];
        }
        int mv = (lv+rv)/2;
        ll ans = 0;
        ans += query(le[root], l, r, lv, mv);
        ans += query(ri[root], l, r, mv, rv);
        return ans;
    }
    ll query(int root, int l, int r) {
        ////cerr << "QUERY ON " << root << " FROM " << l << " TO " << r << endl;
        ll res = query(root, l, r, 0, n);
        ////cerr << "  RES " << res << endl;
        return res;
    }
};

const int N = 200200;
int marker[N];
ll p[N], a[N], ord[N];
ll ans[N];
PersistentSegtree segtree;
int n;

void solve(int lo, int hi, int plo, int phi) {
    if (lo > hi) return;

    int mi = (lo+hi)/2;

    ll base = segtree.query(marker[n], 1, plo+1)-segtree.query(marker[mi], 1, plo+1)+segtree.query(marker[mi], plo+1, n+1);
    ////cerr << "   ";
    ////cerr << segtree.query(marker[n], 1, plo+1) << " - " << segtree.query(marker[mi], 1, plo+1) << " + " << segtree.query(marker[mi], plo+1, n+1) << endl;

    ////cerr << " BASE " << base << endl;

    pii best(1e18, -1);

    for (int i=plo; i<=phi; ++i) {
        best = min(best, pii(base, i));
        if (i != phi) {
            if (p[i+1] > mi) {
                base += a[i+1];
            } else {
                base -= a[i+1];
            }
        }
    }

    //cerr << "SOLVE " << mi << " GET " << best.first << " (at " << best.second << ")" << endl;

    ans[mi] = best.first;
    solve(lo, mi-1, plo, best.second);
    solve(mi+1, hi, best.second, phi);
}

int main() {
    ios_base::sync_with_stdio(0), cin.tie(0);
    cin >> n;
    for (int i=1; i<=n; ++i) {
        cin >> p[i];
        ord[p[i]] = i;
    }
    for (int i=1; i<=n; ++i) {
        cin >> a[i];
        ////cerr << " :: " << a[i] << endl;
    }
    segtree = PersistentSegtree(n+10);

    int latest = 1;
    for (int i=1; i<=n; ++i) {
        int j = ord[i];
        latest = marker[i] = segtree.modify(latest, j, a[j]);
        ////cerr << " MARKER " << i << " = " << marker[i] << " :: j " << j << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 2) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 3, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 4) << endl;
    }

    solve(0, n, 1, n-1);
    ll overall = 1e18;
    for (int i=0; i<=n; ++i) {
        overall = min(overall, ans[i]);
    }
    cout << overall << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef long double ld;

struct PersistentSegtree {
    vector<ll> val;
    vector<int> le, ri;
    int n, h, cur, latest;
    PersistentSegtree() {}
    PersistentSegtree(int sz) {
        h = 32 - __builtin_clz(sz);
        n = 1<<h;
        val = vector<ll>((n+1)*(h+1), 0);
        le = ri = vector<int>((n+1)*(h+1), 0);
        for (int i=1; i<n; ++i) {
            le[i] = i*2;
            ri[i] = i*2+1;
        }
        cur = 2*n-1;
        latest = 1;
    }
    int last() const {
        return latest;
    }
    int modify(int pos, ll amt, int root, int lv, int rv) {
        if (pos<lv || pos>=rv) return root;
        int now = ++cur;
        //////cerr << " NOW " << now << " VS ROOT " << root << " VS SIZE " << val.size() << endl;
        assert (now < val.size());
        val[now] = val[root]+amt;
        //////cerr << " OLD " << val[root] << " (" << root << ") "<< " NEW " << val[now] << endl;
        if (rv-lv == 1) return now;

        int mv = (lv+rv)/2;
        le[now] = modify(pos, amt, le[root], lv, mv);
        ri[now] = modify(pos, amt, ri[root], mv, rv);
        return now;
    }
    int modify(int root, int pos, ll amt) {
        return latest = modify(pos, amt, root, 0, n);
    }
    ll query(int root, int l, int r, int lv, int rv) {
        if (r<=lv || rv<=l) return 0;
        if (l<=lv && rv<=r) {
            return val[root];
        }
        int mv = (lv+rv)/2;
        ll ans = 0;
        ans += query(le[root], l, r, lv, mv);
        ans += query(ri[root], l, r, mv, rv);
        return ans;
    }
    ll query(int root, int l, int r) {
        ////cerr << "QUERY ON " << root << " FROM " << l << " TO " << r << endl;
        ll res = query(root, l, r, 0, n);
        ////cerr << "  RES " << res << endl;
        return res;
    }
};

const int N = 200200;
int marker[N];
ll p[N], a[N], ord[N];
ll ans[N];
PersistentSegtree segtree;
int n;

void solve(int lo, int hi, int plo, int phi) {
    if (lo > hi) return;

    int mi = (lo+hi)/2;

    ll base = segtree.query(marker[n], 1, plo+1)-segtree.query(marker[mi], 1, plo+1)+segtree.query(marker[mi], plo+1, n+1);
    ////cerr << "   ";
    ////cerr << segtree.query(marker[n], 1, plo+1) << " - " << segtree.query(marker[mi], 1, plo+1) << " + " << segtree.query(marker[mi], plo+1, n+1) << endl;

    ////cerr << " BASE " << base << endl;

    pii best(1e18, -1);

    for (int i=plo; i<=phi; ++i) {
        best = min(best, pii(base, i));
        if (i != phi) {
            if (p[i+1] > mi) {
                base += a[i+1];
            } else {
                base -= a[i+1];
            }
        }
    }

    //cerr << "SOLVE " << mi << " GET " << best.first << " (at " << best.second << ")" << endl;

    ans[mi] = best.first;
    solve(lo, mi-1, plo, best.second);
    solve(mi+1, hi, best.second, phi);
}

int main() {
    ios_base::sync_with_stdio(0), cin.tie(0);
    cin >> n;
    for (int i=1; i<=n; ++i) {
        cin >> p[i];
        ord[p[i]] = i;
    }
    for (int i=1; i<=n; ++i) {
        cin >> a[i];
        ////cerr << " :: " << a[i] << endl;
    }
    segtree = PersistentSegtree(n+10);

    int latest = 1;
    for (int i=1; i<=n; ++i) {
        int j = ord[i];
        latest = marker[i] = segtree.modify(latest, j, a[j]);
        ////cerr << " MARKER " << i << " = " << marker[i] << " :: j " << j << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 2) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 3, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 4) << endl;
    }

    solve(0, n, 1, n-1);
    ll overall = 1e18;
    for (int i=0; i<=n; ++i) {
        overall = min(overall, ans[i]);
    }
    cout << overall << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef long double ld;

const int MSZ = (1<<19)*22;

ll val[(1<<19)*(22)];
int le[(1<<19)*22], ri[(1<<19)*22];

struct PersistentSegtree {
    //vector<ll> val;
    //vector<int> le, ri;
    int n, h, cur, latest;
    PersistentSegtree() {}
    PersistentSegtree(int sz) {
        h = 32 - __builtin_clz(sz);
        n = 1<<h;
        //val = vector<ll>((n+1)*(h+4), 0);
        //le = ri = vector<int>((n+1)*(h+4), 0);
        for (int i=1; i<n; ++i) {
            le[i] = i*2;
            ri[i] = i*2+1;
        }
        cur = 2*n-1;
        latest = 1;
    }
    int last() const {
        return latest;
    }
    int modify(int pos, ll amt, int root, int lv, int rv) {
        if (pos<lv || pos>=rv) return root;
        int now = ++cur;
        //////cerr << " NOW " << now << " VS ROOT " << root << " VS SIZE " << val.size() << endl;
        assert (now < MSZ);
        val[now] = val[root]+amt;
        //////cerr << " OLD " << val[root] << " (" << root << ") "<< " NEW " << val[now] << endl;
        if (rv-lv == 1) return now;

        int mv = (lv+rv)/2;
        le[now] = modify(pos, amt, le[root], lv, mv);
        ri[now] = modify(pos, amt, ri[root], mv, rv);
        return now;
    }
    int modify(int root, int pos, ll amt) {
        return latest = modify(pos, amt, root, 0, n);
    }
    ll query(int root, int l, int r, int lv, int rv) {
        if (r<=lv || rv<=l) return 0;
        if (l<=lv && rv<=r) {
            return val[root];
        }
        int mv = (lv+rv)/2;
        ll ans = 0;
        ans += query(le[root], l, r, lv, mv);
        ans += query(ri[root], l, r, mv, rv);
        return ans;
    }
    ll query(int root, int l, int r) {
        ////cerr << "QUERY ON " << root << " FROM " << l << " TO " << r << endl;
        ll res = query(root, l, r, 0, n);
        ////cerr << "  RES " << res << endl;
        return res;
    }
};

const int N = 200200;
int marker[N];
ll p[N], a[N], ord[N];
ll ans[N];
PersistentSegtree segtree;
int n;

void solve(int lo, int hi, int plo, int phi) {
    if (lo > hi) return;

    int mi = (lo+hi)/2;

    ll base = segtree.query(marker[n], 1, plo+1)-segtree.query(marker[mi], 1, plo+1)+segtree.query(marker[mi], plo+1, n+1);
    ////cerr << "   ";
    ////cerr << segtree.query(marker[n], 1, plo+1) << " - " << segtree.query(marker[mi], 1, plo+1) << " + " << segtree.query(marker[mi], plo+1, n+1) << endl;

    ////cerr << " BASE " << base << endl;

    pii best(1e18, -1);

    for (int i=plo; i<=phi; ++i) {
        best = min(best, pii(base, i));
        if (i != phi) {
            if (p[i+1] > mi) {
                base += a[i+1];
            } else {
                base -= a[i+1];
            }
        }
    }

    //cerr << "SOLVE " << mi << " GET " << best.first << " (at " << best.second << ")" << endl;

    ans[mi] = best.first;
    solve(lo, mi-1, plo, best.second);
    solve(mi+1, hi, best.second, phi);
}

int main() {
    ios_base::sync_with_stdio(0), cin.tie(0);
    cin >> n;
    for (int i=1; i<=n; ++i) {
        cin >> p[i];
        ord[p[i]] = i;
    }
    for (int i=1; i<=n; ++i) {
        cin >> a[i];
        ////cerr << " :: " << a[i] << endl;
    }
    segtree = PersistentSegtree(n+10);

    int latest = 1;
    for (int i=1; i<=n; ++i) {
        int j = ord[i];
        latest = marker[i] = segtree.modify(latest, j, a[j]);
        ////cerr << " MARKER " << i << " = " << marker[i] << " :: j " << j << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 2) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 3, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 4) << endl;
    }

    solve(0, n, 1, n-1);
    ll overall = 1e18;
    for (int i=0; i<=n; ++i) {
        overall = min(overall, ans[i]);
    }
    cout << overall << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef long double ld;

ll val[(1<<19)*(22)];
int le[(1<<19)*22], ri[(1<<19)*22];

struct PersistentSegtree {
    //vector<ll> val;
    //vector<int> le, ri;
    int n, h, cur, latest;
    PersistentSegtree() {}
    PersistentSegtree(int sz) {
        h = 32 - __builtin_clz(sz);
        n = 1<<h;
        //val = vector<ll>((n+1)*(h+4), 0);
        //le = ri = vector<int>((n+1)*(h+4), 0);
        for (int i=1; i<n; ++i) {
            le[i] = i*2;
            ri[i] = i*2+1;
        }
        cur = 2*n-1;
        latest = 1;
    }
    int last() const {
        return latest;
    }
    int modify(int pos, ll amt, int root, int lv, int rv) {
        if (pos<lv || pos>=rv) return root;
        int now = ++cur;
        //////cerr << " NOW " << now << " VS ROOT " << root << " VS SIZE " << val.size() << endl;
        assert (now < val.size());
        val[now] = val[root]+amt;
        //////cerr << " OLD " << val[root] << " (" << root << ") "<< " NEW " << val[now] << endl;
        if (rv-lv == 1) return now;

        int mv = (lv+rv)/2;
        le[now] = modify(pos, amt, le[root], lv, mv);
        ri[now] = modify(pos, amt, ri[root], mv, rv);
        return now;
    }
    int modify(int root, int pos, ll amt) {
        return latest = modify(pos, amt, root, 0, n);
    }
    ll query(int root, int l, int r, int lv, int rv) {
        if (r<=lv || rv<=l) return 0;
        if (l<=lv && rv<=r) {
            return val[root];
        }
        int mv = (lv+rv)/2;
        ll ans = 0;
        ans += query(le[root], l, r, lv, mv);
        ans += query(ri[root], l, r, mv, rv);
        return ans;
    }
    ll query(int root, int l, int r) {
        ////cerr << "QUERY ON " << root << " FROM " << l << " TO " << r << endl;
        ll res = query(root, l, r, 0, n);
        ////cerr << "  RES " << res << endl;
        return res;
    }
};

const int N = 200200;
int marker[N];
ll p[N], a[N], ord[N];
ll ans[N];
PersistentSegtree segtree;
int n;

void solve(int lo, int hi, int plo, int phi) {
    if (lo > hi) return;

    int mi = (lo+hi)/2;

    ll base = segtree.query(marker[n], 1, plo+1)-segtree.query(marker[mi], 1, plo+1)+segtree.query(marker[mi], plo+1, n+1);
    ////cerr << "   ";
    ////cerr << segtree.query(marker[n], 1, plo+1) << " - " << segtree.query(marker[mi], 1, plo+1) << " + " << segtree.query(marker[mi], plo+1, n+1) << endl;

    ////cerr << " BASE " << base << endl;

    pii best(1e18, -1);

    for (int i=plo; i<=phi; ++i) {
        best = min(best, pii(base, i));
        if (i != phi) {
            if (p[i+1] > mi) {
                base += a[i+1];
            } else {
                base -= a[i+1];
            }
        }
    }

    //cerr << "SOLVE " << mi << " GET " << best.first << " (at " << best.second << ")" << endl;

    ans[mi] = best.first;
    solve(lo, mi-1, plo, best.second);
    solve(mi+1, hi, best.second, phi);
}

int main() {
    ios_base::sync_with_stdio(0), cin.tie(0);
    cin >> n;
    for (int i=1; i<=n; ++i) {
        cin >> p[i];
        ord[p[i]] = i;
    }
    for (int i=1; i<=n; ++i) {
        cin >> a[i];
        ////cerr << " :: " << a[i] << endl;
    }
    segtree = PersistentSegtree(n+10);

    int latest = 1;
    for (int i=1; i<=n; ++i) {
        int j = ord[i];
        latest = marker[i] = segtree.modify(latest, j, a[j]);
        ////cerr << " MARKER " << i << " = " << marker[i] << " :: j " << j << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 2) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 3, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 4) << endl;
    }

    solve(0, n, 1, n-1);
    ll overall = 1e18;
    for (int i=0; i<=n; ++i) {
        overall = min(overall, ans[i]);
    }
    cout << overall << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef long double ld;

struct PersistentSegtree {
    vector<ll> val;
    vector<int> le, ri;
    int n, h, cur, latest;
    PersistentSegtree() {}
    PersistentSegtree(int sz) {
        h = 32 - __builtin_clz(sz);
        n = 1<<h;
        val = vector<ll>((n+1)*(h+2), 0);
        le = ri = vector<int>((n+1)*(h+2), 0);
        for (int i=1; i<n; ++i) {
            le[i] = i*2;
            ri[i] = i*2+1;
        }
        cur = 2*n-1;
        latest = 1;
    }
    int last() const {
        return latest;
    }
    int modify(int pos, ll amt, int root, int lv, int rv) {
        if (pos<lv || pos>=rv) return root;
        int now = ++cur;
        //////cerr << " NOW " << now << " VS ROOT " << root << " VS SIZE " << val.size() << endl;
        assert (now < val.size());
        val[now] = val[root]+amt;
        //////cerr << " OLD " << val[root] << " (" << root << ") "<< " NEW " << val[now] << endl;
        if (rv-lv == 1) return now;

        int mv = (lv+rv)/2;
        le[now] = modify(pos, amt, le[root], lv, mv);
        ri[now] = modify(pos, amt, ri[root], mv, rv);
        return now;
    }
    int modify(int root, int pos, ll amt) {
        return latest = modify(pos, amt, root, 0, n);
    }
    ll query(int root, int l, int r, int lv, int rv) {
        if (r<=lv || rv<=l) return 0;
        if (l<=lv && rv<=r) {
            return val[root];
        }
        int mv = (lv+rv)/2;
        ll ans = 0;
        ans += query(le[root], l, r, lv, mv);
        ans += query(ri[root], l, r, mv, rv);
        return ans;
    }
    ll query(int root, int l, int r) {
        ////cerr << "QUERY ON " << root << " FROM " << l << " TO " << r << endl;
        ll res = query(root, l, r, 0, n);
        ////cerr << "  RES " << res << endl;
        return res;
    }
};

const int N = 200200;
int marker[N];
ll p[N], a[N], ord[N];
ll ans[N];
PersistentSegtree segtree;
int n;

void solve(int lo, int hi, int plo, int phi) {
    if (lo > hi) return;

    int mi = (lo+hi)/2;

    ll base = segtree.query(marker[n], 1, plo+1)-segtree.query(marker[mi], 1, plo+1)+segtree.query(marker[mi], plo+1, n+1);
    ////cerr << "   ";
    ////cerr << segtree.query(marker[n], 1, plo+1) << " - " << segtree.query(marker[mi], 1, plo+1) << " + " << segtree.query(marker[mi], plo+1, n+1) << endl;

    ////cerr << " BASE " << base << endl;

    pii best(1e18, -1);

    for (int i=plo; i<=phi; ++i) {
        best = min(best, pii(base, i));
        if (i != phi) {
            if (p[i+1] > mi) {
                base += a[i+1];
            } else {
                base -= a[i+1];
            }
        }
    }

    //cerr << "SOLVE " << mi << " GET " << best.first << " (at " << best.second << ")" << endl;

    ans[mi] = best.first;
    solve(lo, mi-1, plo, best.second);
    solve(mi+1, hi, best.second, phi);
}

int main() {
    ios_base::sync_with_stdio(0), cin.tie(0);
    cin >> n;
    for (int i=1; i<=n; ++i) {
        cin >> p[i];
        ord[p[i]] = i;
    }
    for (int i=1; i<=n; ++i) {
        cin >> a[i];
        ////cerr << " :: " << a[i] << endl;
    }
    segtree = PersistentSegtree(n+10);

    int latest = 1;
    for (int i=1; i<=n; ++i) {
        int j = ord[i];
        latest = marker[i] = segtree.modify(latest, j, a[j]);
        ////cerr << " MARKER " << i << " = " << marker[i] << " :: j " << j << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 2) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 3, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 4) << endl;
    }

    solve(0, n, 1, n-1);
    ll overall = 1e18;
    for (int i=0; i<=n; ++i) {
        overall = min(overall, ans[i]);
    }
    cout << overall << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef long double ld;

struct PersistentSegtree {
    vector<ll> val;
    vector<int> le, ri;
    int n, h, cur, latest;
    PersistentSegtree() {}
    PersistentSegtree(int sz) {
        h = 32 - __builtin_clz(sz);
        n = 1<<h;
        val = vector<ll>((n+1)*(h+4), 0);
        le = ri = vector<int>((n+1)*(h+4), 0);
        for (int i=1; i<n; ++i) {
            le[i] = i*2;
            ri[i] = i*2+1;
        }
        cur = 2*n-1;
        latest = 1;
    }
    int last() const {
        return latest;
    }
    int modify(int pos, ll amt, int root, int lv, int rv) {
        if (pos<lv || pos>=rv) return root;
        int now = ++cur;
        //////cerr << " NOW " << now << " VS ROOT " << root << " VS SIZE " << val.size() << endl;
        assert (now < val.size());
        val[now] = val[root]+amt;
        //////cerr << " OLD " << val[root] << " (" << root << ") "<< " NEW " << val[now] << endl;
        if (rv-lv == 1) return now;

        int mv = (lv+rv)/2;
        le[now] = modify(pos, amt, le[root], lv, mv);
        ri[now] = modify(pos, amt, ri[root], mv, rv);
        return now;
    }
    int modify(int root, int pos, ll amt) {
        return latest = modify(pos, amt, root, 0, n);
    }
    ll query(int root, int l, int r, int lv, int rv) {
        if (r<=lv || rv<=l) return 0;
        if (l<=lv && rv<=r) {
            return val[root];
        }
        int mv = (lv+rv)/2;
        ll ans = 0;
        ans += query(le[root], l, r, lv, mv);
        ans += query(ri[root], l, r, mv, rv);
        return ans;
    }
    ll query(int root, int l, int r) {
        ////cerr << "QUERY ON " << root << " FROM " << l << " TO " << r << endl;
        ll res = query(root, l, r, 0, n);
        ////cerr << "  RES " << res << endl;
        return res;
    }
};

const int N = 200200;
int marker[N];
ll p[N], a[N], ord[N];
ll ans[N];
PersistentSegtree segtree;
int n;

void solve(int lo, int hi, int plo, int phi) {
    if (lo > hi) return;

    int mi = (lo+hi)/2;

    ll base = segtree.query(marker[n], 1, plo+1)-segtree.query(marker[mi], 1, plo+1)+segtree.query(marker[mi], plo+1, n+1);
    ////cerr << "   ";
    ////cerr << segtree.query(marker[n], 1, plo+1) << " - " << segtree.query(marker[mi], 1, plo+1) << " + " << segtree.query(marker[mi], plo+1, n+1) << endl;

    ////cerr << " BASE " << base << endl;

    pii best(1e18, -1);

    for (int i=plo; i<=phi; ++i) {
        best = min(best, pii(base, i));
        if (i != phi) {
            if (p[i+1] > mi) {
                base += a[i+1];
            } else {
                base -= a[i+1];
            }
        }
    }

    //cerr << "SOLVE " << mi << " GET " << best.first << " (at " << best.second << ")" << endl;

    ans[mi] = best.first;
    solve(lo, mi-1, plo, best.second);
    solve(mi+1, hi, best.second, phi);
}

int main() {
    ios_base::sync_with_stdio(0), cin.tie(0);
    cin >> n;
    for (int i=1; i<=n; ++i) {
        cin >> p[i];
        ord[p[i]] = i;
    }
    for (int i=1; i<=n; ++i) {
        cin >> a[i];
        ////cerr << " :: " << a[i] << endl;
    }
    segtree = PersistentSegtree(n+10);

    int latest = 1;
    for (int i=1; i<=n; ++i) {
        int j = ord[i];
        latest = marker[i] = segtree.modify(latest, j, a[j]);
        ////cerr << " MARKER " << i << " = " << marker[i] << " :: j " << j << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 2) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 3, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 4) << endl;
    }

    solve(0, n, 1, n-1);
    ll overall = 1e18;
    for (int i=0; i<=n; ++i) {
        overall = min(overall, ans[i]);
    }
    cout << overall << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
typedef long double ld;

struct PersistentSegtree {
    vector<ll> val;
    vector<int> le, ri;
    int n, h, cur, latest;
    PersistentSegtree() {}
    PersistentSegtree(int sz) {
        h = 32 - __builtin_clz(sz);
        n = 1<<h;
        val = vector<ll>(n*h*2, 0);
        le = ri = vector<int>(n*h*2, 0);
        for (int i=1; i<n; ++i) {
            le[i] = i*2;
            ri[i] = i*2+1;
        }
        cur = 2*n-1;
        latest = 1;
    }
    int last() const {
        return latest;
    }
    int modify(int pos, ll amt, int root, int lv, int rv) {
        if (pos<lv || pos>=rv) return root;
        int now = ++cur;
        //////cerr << " NOW " << now << " VS ROOT " << root << " VS SIZE " << val.size() << endl;
        assert (now < val.size());
        val[now] = val[root]+amt;
        //////cerr << " OLD " << val[root] << " (" << root << ") "<< " NEW " << val[now] << endl;
        if (rv-lv == 1) return now;

        int mv = (lv+rv)/2;
        le[now] = modify(pos, amt, le[root], lv, mv);
        ri[now] = modify(pos, amt, ri[root], mv, rv);
        return now;
    }
    int modify(int root, int pos, ll amt) {
        return latest = modify(pos, amt, root, 0, n);
    }
    ll query(int root, int l, int r, int lv, int rv) {
        if (r<=lv || rv<=l) return 0;
        if (l<=lv && rv<=r) {
            return val[root];
        }
        int mv = (lv+rv)/2;
        ll ans = 0;
        ans += query(le[root], l, r, lv, mv);
        ans += query(ri[root], l, r, mv, rv);
        return ans;
    }
    ll query(int root, int l, int r) {
        ////cerr << "QUERY ON " << root << " FROM " << l << " TO " << r << endl;
        ll res = query(root, l, r, 0, n);
        ////cerr << "  RES " << res << endl;
        return res;
    }
};

const int N = 200200;
int marker[N];
ll p[N], a[N], ord[N];
ll ans[N];
PersistentSegtree segtree;
int n;

void solve(int lo, int hi, int plo, int phi) {
    if (lo > hi) return;

    int mi = (lo+hi)/2;

    ll base = segtree.query(marker[n], 1, plo+1)-segtree.query(marker[mi], 1, plo+1)+segtree.query(marker[mi], plo+1, n+1);
    ////cerr << "   ";
    ////cerr << segtree.query(marker[n], 1, plo+1) << " - " << segtree.query(marker[mi], 1, plo+1) << " + " << segtree.query(marker[mi], plo+1, n+1) << endl;

    ////cerr << " BASE " << base << endl;

    pii best(1e18, -1);

    for (int i=plo; i<=phi; ++i) {
        best = min(best, pii(base, i));
        if (i != phi) {
            if (p[i+1] > mi) {
                base += a[i+1];
            } else {
                base -= a[i+1];
            }
        }
    }

    //cerr << "SOLVE " << mi << " GET " << best.first << " (at " << best.second << ")" << endl;

    ans[mi] = best.first;
    solve(lo, mi-1, plo, best.second);
    solve(mi+1, hi, best.second, phi);
}

int main() {
    ios_base::sync_with_stdio(0), cin.tie(0);
    cin >> n;
    for (int i=1; i<=n; ++i) {
        cin >> p[i];
        ord[p[i]] = i;
    }
    for (int i=1; i<=n; ++i) {
        cin >> a[i];
        ////cerr << " :: " << a[i] << endl;
    }
    segtree = PersistentSegtree(n+10);

    int latest = 1;
    for (int i=1; i<=n; ++i) {
        int j = ord[i];
        latest = marker[i] = segtree.modify(latest, j, a[j]);
        ////cerr << " MARKER " << i << " = " << marker[i] << " :: j " << j << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 2) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 3, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 3) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 2, 4) << endl;
        ////cerr << " :: " << segtree.query(marker[i], 1, 4) << endl;
    }

    solve(0, n, 1, n-1);
    ll overall = 1e18;
    for (int i=0; i<=n; ++i) {
        overall = min(overall, ans[i]);
    }
    cout << overall << "\n";
    return 0;
}


// Author: wlzhouzhuan
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define ull unsigned long long
#define rint register int
#define rep(i, l, r) for (rint i = l; i <= r; i++)
#define per(i, l, r) for (rint i = l; i >= r; i--)
#define mset(s, _) memset(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define mp(a, b) make_pair(a, b)

inline int read() {
  int x = 0, neg = 1; char op = getchar();
  while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); }
  while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); }
  return neg * x;
}
inline void print(int x) {
  if (x < 0) { putchar('-'); x = -x; }
  if (x >= 10) print(x / 10);
  putchar(x % 10 + '0');
}

const int N = 200005;

template <typename T>
void ckmin(T &a, T b) {
  if (a > b) a = b;
}

long long a[N], sum[N];
int p[N], loc[N], n;

struct SegmentTree {
  #define ls (u << 1)
  #define rs (u << 1 | 1)
  ll Min[N << 2], lzy[N << 2];
  void pushup(int u) {
    Min[u] = min(Min[ls], Min[rs]);
  }
  void pushdown(int u) {
    if (lzy[u] > 0) {
      lzy[ls] += lzy[u];
      lzy[rs] += lzy[u];
      Min[ls] += lzy[u];
      Min[rs] += lzy[u];
      lzy[u] = 0;
    }
  }
  void build(int u, int l, int r) {
    if (l == r) {
      Min[u] = sum[l];
      lzy[u] = 0;
      return ;
    }
    int mid = l + r >> 1;
    build(ls, l, mid);
    build(rs, mid + 1, r);
    pushup(u);
  }
  void update(int u, int l, int r, int ql, int qr, ll x) {
    if (l > r || ql > qr) return ;
    if (ql <= l && r <= qr) {
      lzy[u] += x;
      Min[u] += x;
      return ;
    }
    pushdown(u);
    int mid = l + r >> 1;
    if (ql <= mid) update(ls, l, mid, ql, qr, x);
    if (qr > mid) update(rs, mid + 1, r, ql, qr, x);
    pushup(u);
  }
  long long query(int u, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) {
      return Min[u];
    }
    pushdown(u);
    int mid = l + r >> 1;
    long long ret = 1e18;
    if (ql <= mid) ckmin(ret, query(ls, l, mid, ql, qr));
    if (qr > mid) ckmin(ret, query(rs, mid + 1, r, ql, qr));
    return ret;
  }
} smt;

int main() {
  n = read();
  for (rint i = 1; i <= n; i++) p[i] = read(), loc[p[i]] = i;
  for (rint i = 1; i <= n; i++) a[i] = read(), sum[i] = sum[i - 1] + a[i];
  smt.build(1, 1, n - 1);
  long long ans = min(a[1], a[n]);
  for (rint p = 1; p < n; p++) {
    smt.update(1, 1, n - 1, loc[p], n - 1, -a[loc[p]]);
    if (loc[p] > 1) smt.update(1, 1, n - 1, 1, loc[p] - 1, a[loc[p]]);
    ckmin(ans, smt.Min[1]);
  }
  printf("%lld\n", ans);
  return 0;
}


// Author: wlzhouzhuan
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define ull unsigned long long
#define rint register int
#define rep(i, l, r) for (rint i = l; i <= r; i++)
#define per(i, l, r) for (rint i = l; i >= r; i--)
#define mset(s, _) memset(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define mp(a, b) make_pair(a, b)

inline int read() {
  int x = 0, neg = 1; char op = getchar();
  while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); }
  while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); }
  return neg * x;
}
inline void print(int x) {
  if (x < 0) { putchar('-'); x = -x; }
  if (x >= 10) print(x / 10);
  putchar(x % 10 + '0');
}

const int N = 200005;

template <typename T>
void ckmin(T &a, T b) {
  if (a > b) a = b;
}

long long a[N], sum[N];
int p[N], loc[N], n;

struct SegmentTree {
  #define ls (u << 1)
  #define rs (u << 1 | 1)
  ll Min[N], lzy[N];
  void pushup(int u) {
    Min[u] = min(Min[ls], Min[rs]);
  }
  void pushdown(int u) {
    if (lzy[u] > 0) {
      lzy[ls] += lzy[u];
      lzy[rs] += lzy[u];
      Min[ls] += lzy[u];
      Min[rs] += lzy[u];
      lzy[u] = 0;
    }
  }
  void build(int u, int l, int r) {
    if (l == r) {
      Min[u] = sum[l];
      lzy[u] = 0;
      return ;
    }
    int mid = l + r >> 1;
    build(ls, l, mid);
    build(rs, mid + 1, r);
    pushup(u);
  }
  void update(int u, int l, int r, int ql, int qr, ll x) {
    if (l > r || ql > qr) return ;
    if (ql <= l && r <= qr) {
      lzy[u] += x;
      Min[u] += x;
      return ;
    }
    pushdown(u);
    int mid = l + r >> 1;
    if (ql <= mid) update(ls, l, mid, ql, qr, x);
    if (qr > mid) update(rs, mid + 1, r, ql, qr, x);
    pushup(u);
  }
  long long query(int u, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) {
      return Min[u];
    }
    pushdown(u);
    int mid = l + r >> 1;
    long long ret = 1e18;
    if (ql <= mid) ckmin(ret, query(ls, l, mid, ql, qr));
    if (qr > mid) ckmin(ret, query(rs, mid + 1, r, ql, qr));
    return ret;
  }
} smt;

int main() {
  n = read();
  for (rint i = 1; i <= n; i++) p[i] = read(), loc[p[i]] = i;
  for (rint i = 1; i <= n; i++) a[i] = read(), sum[i] = sum[i - 1] + a[i];
  smt.build(1, 1, n - 1);
  long long ans = min(a[1], a[n]);
  for (rint p = 1; p <= n; p++) {
    smt.update(1, 1, n - 1, loc[p], n - 1, -a[loc[p]]);
    if (loc[p] > 1) smt.update(1, 1, n - 1, 1, loc[p] - 1, a[loc[p]]);
    ckmin(ans, smt.Min[1]);
  }
  printf("%lld\n", ans);
  return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[202][202][10001];

int dfs(int num,int tot,int five,int twoo)//当前数字 选中数字 5的个数
{
	if(num==n+1||tot==k)
	{
		dp[num][tot][five]=min(five,twoo);
		return dp[num][tot][five];
	}
	int ret=0;
	if(dp[num][tot][five])
	{
		return dp[num][tot][five];
	}
	else
	{
		ret=max(dfs(num+1,tot+1,five+fiv[num],twoo+two[num]),dfs(num+1,tot,five,twoo));
		dp[num][tot][five]=ret;
		return ret;
	}
}
int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;long long x;
	for(int i=1;i<=n;i++)
	{
		scanf("%I64d",&x);
		while(!(x%5)){fiv[i]++;x/=5;nfiv++;}
		while(!(x%2)){two[i]++;x/=2;ntwo++;}
	}

	int ans=dfs(1,0,0,0);

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

	return 0;
}

//max_int 67108864


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[202][202][25*202];

int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;
	unsigned long long x;
	for(int i=1; i<=n; i++)
	{
		scanf("%I64d",&x);
		while(!(x%5))
		{
			fiv[i]++;
			x/=5;
			nfiv++;
		}
		while(!(x%2))
		{
			two[i]++;
			x/=2;
			ntwo++;
		}
	}

	memset(dp,-1,sizeof(dp));
	for(int i=0;i<=n;i++)for(int j=0;j<=n;j++)dp[i][j][0]=0;

	for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=min(k,i); j++)
		{
			for(int w=nfiv; w>=0;w--)
			{
				if(dp[i-1][j-1][w-fiv[i]]!=-1)dp[i][j][w]=max(dp[i-1][j][w],dp[i-1][j-1][w-fiv[i]]+two[i]);//前i个选j个有 k个5 dp=2的个数
				else dp[i][j][w]=dp[i-1][j][w];//避免访问不存在的位置
			}
		}
	}

	int ans=0;

	for(int i=0;i<=nfiv;i++)ans=max(ans,min(dp[n][k][i],i));//5多了2不一定够

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

	return 0;
}

//3 1 1000000000000000000 800000000000000000 625

//     5:18  2:18      5:17  2:20        5:4

//3 1 4 10 25


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[202][206][6*202];

int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;
	unsigned long long x;
	for(int i=1; i<=n; i++)
	{
		scanf("%I64d",&x);
		while(!(x%5))
		{
			fiv[i]++;
			x/=5;
			nfiv++;
		}
		while(!(x%2))
		{
			two[i]++;
			x/=2;
			ntwo++;
		}
	}

	int ii;
	for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=min(k,i); j++)
		{
			for(int k=nfiv; k>=fiv[i];k--)
			{
				dp[i][j][k]=max(dp[i-1][j][k],dp[i-1][j-1][k-fiv[i]]+two[i]);//前i个选j个有 k个5 dp=2的个数
				//num+1,tot+1,five+fiv[num],twoo+two[num]
			}
		}
	}

	int ans=0;

	ans=min(dp[n][k][nfiv],nfiv);

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

	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

//int dp[201][201][25*201];//数组大了
int dp[201][32*201];

int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;
	unsigned long long x;
	for(int i=1; i<=n; i++)
	{
		scanf("%I64d",&x);
		while(!(x%5))
		{
			fiv[i]++;
			x/=5;
			nfiv++;
		}
		while(!(x%2))
		{
			two[i]++;
			x/=2;
			ntwo++;
		}
	}

	memset(dp,-1,sizeof(dp));
	for(int j=0;j<=n;j++)dp[j][0]=0;

	for(int i=1; i<=n; i++)
	{
		for(int j=min(k,i); j>=1; j--)
		{
			for(int w=nfiv; w>=fiv[i];w--)//避免越界
			{
				if(dp[j-1][w-fiv[i]]!=-1)dp[j][w]=max(dp[j][w],dp[j-1][w-fiv[i]]+two[i]);//前i个选j个有 k个5 dp=2的个数
			//	else dp[j][w]=dp[j][w];//避免访问不存在的位置
			}
		}
	}

	int ans=0;

	for(int i=1;i<=nfiv;i++)ans=max(ans,min(dp[k][i],i));//5多了2不一定够

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

	return 0;
}

//3 1 1000000000000000000 800000000000000000 625

//     5:18  2:18      5:17  2:20        5:4

//3 1 4 10 25

//7 5 50 312500 10000 1250 2000000 250 1250000


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[202][202][1500];

int dfs(int num,int tot,int five,int twoo)//当前数字 选中数字 5的个数
{
	if(num==n+1||tot==k)
	{
		dp[num][tot][five]=min(five,twoo);
		return dp[num][tot][five];
	}
	int ret=0;
	if(dp[num][tot][five])
	{
		return dp[num][tot][five];
	}
	else
	{
		ret=max(dfs(num+1,tot+1,five+fiv[num],twoo+two[num]),dfs(num+1,tot,five,twoo));
		dp[num][tot][five]=ret;
		return ret;
	}
}
int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;long long x;
	for(int i=1;i<=n;i++)
	{
		scanf("%I64d",&x);
		while(!(x%5)){fiv[i]++;x/=5;nfiv++;}
		while(!(x%2)){two[i]++;x/=2;ntwo++;}
	}

	int ans=dfs(1,0,0,0);

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

	return 0;
}

//max_int 67108864


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k,a[206];
int fiv[206],two[206];

int dp[206][206][1001];

int dfs(int num,int tot,int five,int twoo)//��ǰ���� ѡ������ 5�ĸ���
{
	if(num==n+1||tot==k)
	{
		dp[num][tot][five]=min(five,twoo);
		return dp[num][tot][five];
	}
	int ret=0;
	if(dp[num][tot][five])
	{
		return dp[num][tot][five];
	}
	else
	{
		ret=max(dfs(num+1,tot+1,five+fiv[num],twoo+two[num]),dfs(num+1,tot,five,twoo));
		dp[num][tot][five]=ret;
		return ret;
	}
}
int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0,x;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		x=a[i];
		while(!(x%5)){fiv[i]++;x/=5;nfiv++;}
		while(!(x%2)){two[i]++;x/=2;ntwo++;}
	}

	int ans=dfs(1,0,0,0);

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

	return 0;
}

//max_int 67108864


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

//int dp[201][201][25*201];//数组大了
int dp[201][32*201];

int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;
	unsigned long long x;
	for(int i=1; i<=n; i++)
	{
		scanf("%I64d",&x);
		while(!(x%5))
		{
			fiv[i]++;
			x/=5;
			nfiv++;
		}
		while(!(x%2))
		{
			two[i]++;
			x/=2;
			ntwo++;
		}
	}

	memset(dp,-1,sizeof(dp));
	for(int j=0;j<=n;j++)dp[j][0]=0;

	for(int i=1; i<=n; i++)
	{
		for(int j=min(k,i); j>=1; j--)
		{
			for(int w=nfiv; w>=0;w--)
			{
				if(dp[j-1][w-fiv[i]]!=-1)dp[j][w]=max(dp[j][w],dp[j-1][w-fiv[i]]+two[i]);//前i个选j个有 k个5 dp=2的个数
			//	else dp[j][w]=dp[j][w];//避免访问不存在的位置
			}
		}
	}

	int ans=0;

	for(int i=0;i<=nfiv;i++)ans=max(ans,min(dp[k][i],i));//5多了2不一定够

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

	return 0;
}

//3 1 1000000000000000000 800000000000000000 625

//     5:18  2:18      5:17  2:20        5:4

//3 1 4 10 25


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[202][202][1633];

int dfs(int num,int tot,int five,int twoo)//当前数字 选中数字 5的个数
{
	if(num==n+1||tot==k)
	{
		dp[num][tot][five]=min(five,twoo);
		return dp[num][tot][five];
	}
	int ret=0;
	if(dp[num][tot][five])
	{
		return dp[num][tot][five];
	}
	else
	{
		ret=max(dfs(num+1,tot+1,five+fiv[num],twoo+two[num]),dfs(num+1,tot,five,twoo));
		dp[num][tot][five]=ret;
		return ret;
	}
}
int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;long long x;
	for(int i=1;i<=n;i++)
	{
		scanf("%I64d",&x);
		while(!(x%5)){fiv[i]++;x/=5;nfiv++;}
		while(!(x%2)){two[i]++;x/=2;ntwo++;}
	}

	int ans=dfs(1,0,0,0);

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

	return 0;
}

//max_int 67108864


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[202][206][6*202];

int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;
	unsigned long long x;
	for(int i=1; i<=n; i++)
	{
		scanf("%I64d",&x);
		while(!(x%5))
		{
			fiv[i]++;
			x/=5;
			nfiv++;
		}
		while(!(x%2))
		{
			two[i]++;
			x/=2;
			ntwo++;
		}
	}

	memset(dp,-1,sizeof(dp));
	for(int i=0;i<=n;i++)for(int j=0;j<=n;j++)dp[i][j][0]=0;

	for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=min(k,i); j++)
		{
			for(int w=nfiv; w>=0;w--)
			{
				if(dp[i-1][j-1][w-fiv[i]]!=-1)dp[i][j][w]=max(dp[i-1][j][w],dp[i-1][j-1][w-fiv[i]]+two[i]);//前i个选j个有 k个5 dp=2的个数
				else dp[i][j][w]=dp[i-1][j][w];//避免访问不存在的位置
			}
		}
	}

	int ans=0;

	for(int i=0;i<=nfiv;i++)ans=max(ans,min(dp[n][k][i],i));//5多了2不一定够

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

	return 0;
}

//3 1 1000000000000000000 800000000000000000 625

//     5:18  2:18      5:17  2:20        5:4

//3 1 4 10 25


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[202][202][1635];

int dfs(int num,int tot,int five,int twoo)//当前数字 选中数字 5的个数
{
	if(num==n+1||tot==k)
	{
		dp[num][tot][five]=min(five,twoo);
		return dp[num][tot][five];
	}
	int ret=0;
	if(dp[num][tot][five])
	{
		return dp[num][tot][five];
	}
	else
	{
		ret=max(dfs(num+1,tot+1,five+fiv[num],twoo+two[num]),dfs(num+1,tot,five,twoo));
		dp[num][tot][five]=ret;
		return ret;
	}
}
int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;long long x;
	for(int i=1;i<=n;i++)
	{
		scanf("%I64d",&x);
		while(!(x%5)){fiv[i]++;x/=5;nfiv++;}
		while(!(x%2)){two[i]++;x/=2;ntwo++;}
	}

	int ans=dfs(1,0,0,0);

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

	return 0;
}

//max_int 67108864


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[201][201][25*201];

int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;
	unsigned long long x;
	for(int i=1; i<=n; i++)
	{
		scanf("%I64d",&x);
		while(!(x%5))
		{
			fiv[i]++;
			x/=5;
			nfiv++;
		}
		while(!(x%2))
		{
			two[i]++;
			x/=2;
			ntwo++;
		}
	}

	memset(dp,-1,sizeof(dp));
	for(int i=0;i<=n;i++)for(int j=0;j<=n;j++)dp[i][j][0]=0;

	for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=min(k,i); j++)
		{
			for(int w=nfiv; w>=0;w--)
			{
				if(dp[i-1][j-1][w-fiv[i]]!=-1)dp[i][j][w]=max(dp[i-1][j][w],dp[i-1][j-1][w-fiv[i]]+two[i]);//前i个选j个有 k个5 dp=2的个数
				else dp[i][j][w]=dp[i-1][j][w];//避免访问不存在的位置
			}
		}
	}

	int ans=0;

	for(int i=0;i<=nfiv;i++)ans=max(ans,min(dp[n][k][i],i));//5多了2不一定够

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

	return 0;
}

//3 1 1000000000000000000 800000000000000000 625

//     5:18  2:18      5:17  2:20        5:4

//3 1 4 10 25


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[202][206][6*202];

int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;
	unsigned long long x;
	for(int i=1; i<=n; i++)
	{
		scanf("%I64d",&x);
		while(!(x%5))
		{
			fiv[i]++;
			x/=5;
			nfiv++;
		}
		while(!(x%2))
		{
			two[i]++;
			x/=2;
			ntwo++;
		}
	}

	memset(dp,-1,sizeof(dp));
	for(int i=0;i<=n;i++)for(int j=0;j<=n;j++)dp[i][j][0]=0;

	for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=min(k,i); j++)
		{
			for(int w=nfiv; w>=fiv[i];w--)
			{
				if(dp[i-1][j-1][w-fiv[i]]!=-1)dp[i][j][w]=max(dp[i-1][j][w],dp[i-1][j-1][w-fiv[i]]+two[i]);//前i个选j个有 k个5 dp=2的个数
				else dp[i][j][w]=dp[i-1][j][w];//避免访问不存在的位置
			}
		}
	}

	int ans=0;

	for(int i=0;i<=nfiv;i++)ans=max(ans,min(dp[n][k][i],i));//5多了2不一定够

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

	return 0;
}

//3 1 1000000000000000000 800000000000000000 625

//     5:18  2:18      5:17  2:20        5:4


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[202][202][1600];

int dfs(int num,int tot,int five,int twoo)//当前数字 选中数字 5的个数
{
	if(num==n+1||tot==k)
	{
		dp[num][tot][five]=min(five,twoo);
		return dp[num][tot][five];
	}
	int ret=0;
	if(dp[num][tot][five])
	{
		return dp[num][tot][five];
	}
	else
	{
		ret=max(dfs(num+1,tot+1,five+fiv[num],twoo+two[num]),dfs(num+1,tot,five,twoo));
		dp[num][tot][five]=ret;
		return ret;
	}
}
int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;long long x;
	for(int i=1;i<=n;i++)
	{
		scanf("%I64d",&x);
		while(!(x%5)){fiv[i]++;x/=5;nfiv++;}
		while(!(x%2)){two[i]++;x/=2;ntwo++;}
	}

	int ans=dfs(1,0,0,0);

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

	return 0;
}

//max_int 67108864


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[202][202][1625];

int dfs(int num,int tot,int five,int twoo)//当前数字 选中数字 5的个数
{
	if(num==n+1||tot==k)
	{
		dp[num][tot][five]=min(five,twoo);
		return dp[num][tot][five];
	}
	int ret=0;
	if(dp[num][tot][five])
	{
		return dp[num][tot][five];
	}
	else
	{
		ret=max(dfs(num+1,tot+1,five+fiv[num],twoo+two[num]),dfs(num+1,tot,five,twoo));
		dp[num][tot][five]=ret;
		return ret;
	}
}
int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;unsigned long long x;
	for(int i=1;i<=n;i++)
	{
		scanf("%I64d",&x);
		while(!(x%5)){fiv[i]++;x/=5;nfiv++;}
		while(!(x%2)){two[i]++;x/=2;ntwo++;}
	}

	int ans=dfs(1,0,0,0);

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

	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[202][202][1631];

int dfs(int num,int tot,int five,int twoo)//当前数字 选中数字 5的个数
{
	if(num==n+1||tot==k)
	{
		dp[num][tot][five]=min(five,twoo);
		return dp[num][tot][five];
	}
	int ret=0;
	if(dp[num][tot][five])
	{
		return dp[num][tot][five];
	}
	else
	{
		ret=max(dfs(num+1,tot+1,five+fiv[num],twoo+two[num]),dfs(num+1,tot,five,twoo));
		dp[num][tot][five]=ret;
		return ret;
	}
}
int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;long long x;
	for(int i=1;i<=n;i++)
	{
		scanf("%I64d",&x);
		while(!(x%5)){fiv[i]++;x/=5;nfiv++;}
		while(!(x%2)){two[i]++;x/=2;ntwo++;}
	}

	int ans=dfs(1,0,0,0);

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

	return 0;
}

//max_int 67108864


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<set>
#include<queue>
#include<cmath>

using namespace std;

int n,k;
int fiv[206],two[206];

int dp[202][202][1625];

int dfs(int num,int tot,int five,int twoo)//当前数字 选中数字 5的个数
{
	if(num==n+1||tot==k)
	{
		dp[num][tot][five]=min(five,twoo);
		return dp[num][tot][five];
	}
	int ret=0;
	if(dp[num][tot][five])
	{
		return dp[num][tot][five];
	}
	else
	{
		ret=max(dfs(num+1,tot+1,five+fiv[num],twoo+two[num]),dfs(num+1,tot,five,twoo));
		dp[num][tot][five]=ret;
		return ret;
	}
}
int main()
{
	scanf("%d%d",&n,&k);
	int nfiv=0,ntwo=0;long long x;
	for(int i=1;i<=n;i++)
	{
		scanf("%I64d",&x);
		while(!(x%5)){fiv[i]++;x/=5;nfiv++;}
		while(!(x%2)){two[i]++;x/=2;ntwo++;}
	}

	int ans=dfs(1,0,0,0);

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

	return 0;
}

//max_int 67108864