Problem:
Score : 700 points

Problem Statement

We have N gemstones labeled 1 through N.

You can perform the following operation any number of times (possibly zero).

Select a positive integer x, and smash all the gems labeled with multiples of x.

Then, for each i, if the gem labeled i remains without getting smashed, you will receive a_i yen (the currency of Japan).
However, a_i may be negative, in which case you will be charged money.

By optimally performing the operation, how much yen can you earn?

Constraints

All input values are integers.

1 \leq N \leq 100

|a_i| \leq 10^9

Input

Input is given from Standard Input in the following format:

N
a_1 a_2 ... a_N

Output

Print the maximum amount of money that can be earned.

Sample Input 1

6
1 2 -6 4 5 3

Sample Output 1

12

It is optimal to smash Gem 3 and 6.

Sample Input 2

6
100 -100 -100 -100 100 -100

Sample Output 2

200

Sample Input 3

5
-1 -2 -3 -4 -5

Sample Output 3

0

It is optimal to smash all the gems.

Sample Input 4

2
-1000 100000

Sample Output 4

99000

Solution in C (GCC 5.4.1) (judge verdict: Accepted)

#include <stdio.h>
#define ll long long
#define rep(i,l,r)for(ll i=(l);i<(r);i++)
#define repp(i,l,r,k)for(ll i=(l);i<(r);i+=(k))
#define min(p,q)((p)<(q)?(p):(q))
#define INF ((1LL<<62)-(1LL<<31))

//dinicここから
#define dinicVmax 110
#define resflow(a,b)(capa[a][b]-flow[a][b])
ll vcnt;//頂点数
ll capa[dinicVmax][dinicVmax];//容量
ll flow[dinicVmax][dinicVmax];//実際の流量
ll dist[dinicVmax];//ソースからの距離
ll checked[dinicVmax];//dfsの行き止まりフラグ
void dinicbfs(ll s){
	rep(i,0,vcnt)dist[i]=-1;
	dist[s]=0;
	//まだ流せる辺だけを使ってbfs
	ll que[dinicVmax*dinicVmax];
	ll qcnt=0,qptr=0;
	que[qcnt++]=s;
	while(qcnt!=qptr){
		ll a=que[qptr++];
		rep(b,0,vcnt)if(resflow(a,b)>0&&dist[b]==-1){
			dist[b]=dist[a]+1;
			que[qcnt++]=b;
		}
	}
}
ll dinicdfs(ll a,ll t,ll m){
	//aはm受け取ってる(⇔aから最大m流せる)
	//いくら流せるかを返す
	if(a==t)return m;
	if(checked[a])return 0;
	ll ans=0;
	checked[a]=1;
	rep(b,0,vcnt)if(dist[b]>dist[a]&&resflow(a,b)>0){
		ll addedflow=dinicdfs(b,t,min(m,resflow(a,b)));
		if(addedflow){
			flow[a][b]+=addedflow;
			flow[b][a]-=addedflow;
			checked[a]=0;
			ans+=addedflow;
			m-=addedflow;
			if(m<=0)break;
		}
	}
	return ans;
}
//ソース,シンク
ll dinic(ll s,ll t){
	ll ans=0;
	ll flag=1;
	while(flag){
		flag=0;//更新フラグ
		dinicbfs(s);
		while(!checked[s]){
			ll addedflow=dinicdfs(s,t,INF);
			ans+=addedflow;
			if(addedflow)flag=1;
		}
		rep(i,0,vcnt)checked[i]=0;
	}
	return ans;
}
//dinicここまで

int main(){
	//ソースを0、シンクをN+1として、破壊する側をソース、しない側をシンクに集める
	//以下の条件で与えられるペナルティーを最小化する
	//・a[i]<0のとき、a[i]を破壊しないと|a[i]|のペナルティー→ソースからiを|a[i]|で結ぶ
	//・a[i]>=0のとき、a[i]を破壊しないのを基礎点として、破壊するとa[i]のペナルティー→iからシンクをa[i]で結ぶ
	//・a[i]が破壊されていてかつa[k*i]が破壊されていないとき、∞点のペナルティー→iからk*iを∞で結ぶ
	//基礎点としてもらえる(Σ_{i\in\{j|a[j]>=0\}}a[i])点からペナルティーを引いたものが答え
	ll n;
	scanf("%lld",&n);
	ll base=0;
	rep(i,1,n+1){
		ll t;
		scanf("%lld",&t);
		if(t<0){
			capa[0][i]=-t;
		}else{
			capa[i][n+1]=t;
			base+=t;
		}
	}
	rep(i,1,n+1)repp(j,i*2,n+1,i)capa[i][j]=INF;
	vcnt=n+2;
	printf("%lld\n",base-dinic(0,n+1));
	return 0;
}