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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
using namespace std;
int N;
int a[128];
bool flag[128];

#define MAX_N 128
#define INF (2<<21)

class dinic {
private:
	struct edge { int to, cap, rev; };
	vector<edge> G[MAX_N];
	//sからの深さを記憶
	vector<int> level;
	int V;

	//深さ優先で経路を検索
	//経路を見つけたら流して更新
	int dfs(int v, int t, int f) {
		if (v == t) return f;
		for (int i = 0; i < G[v].size(); i++) {
			edge &e = G[v][i];
			if (e.cap <= 0) continue;
			if (level[v] >= level[e.to]) continue;
			int d = dfs(e.to, t, min(f, e.cap));
			if (d > 0) {
				e.cap -= d;
				G[e.to][e.rev].cap += d;
				return d;
			}
		}
		return 0;
	}

	//幅優先
	void bfs(int s) {
		level.assign(V, -1);
		queue<int> q;
		q.push(s);
		level[s] = 0;
		for (; !q.empty();) {
			int v = q.front(); q.pop();
			for (int i = 0; i < G[v].size(); i++) {
				struct edge e = G[v][i];
				if (e.cap <= 0) continue;
				//既に通った辺なら
				if (level[e.to] >= 0) continue;
				level[e.to] = level[v] + 1;
				q.push(e.to);
			}
		}
	}


public:
	dinic(int v) {
		V = v;
	}
	void add_edge(int from, int to, int cap) {
		struct edge tmp;
		tmp = { to, cap, int(G[to].size()) };
		G[from].push_back(tmp);
		tmp = { from, 0, int(G[from].size() - 1) };
		G[to].push_back(tmp);
	}

	int run(int s, int t) {
		int f = 0;
		for (;;) {
			bfs(s);
			if (level[t] < 0) break;
			f += dfs(s, t, INF);
		}
		return f;
	}
};

void MUL() {
	cin >> N;
	for (int i = 0; i < N; i++) {
		cin >> a[i];
	}
	//後半で負の宝石は問答無用で叩き割る
	for (int i = (N + 1 / 2); i < N; i++) {
		a[i] = a[i] < 0 ? 0 : a[i];
	}

	int ideal = 0;
	for (int i = 0; i < N; i++) {
		ideal += a[i] > 0 ? a[i] : 0;
	}

	memset(flag, 0, sizeof(flag));

	dinic d(N + 2);
	for (int i = 0; i < N; i++) {
		if (a[i] > 0) {
			d.add_edge(0, i + 1, a[i]);
			d.add_edge(i + 1, N + 1, 0);
		}
		else {
			d.add_edge(i + 1, N + 1, -a[i]);
			d.add_edge(0, i + 1, 0);
		}
		for (int j = (i + 1) * 2; j < N + 1; j += i + 1) {
			d.add_edge(j, (i + 1), INF);
		}
	}
	cout << ideal - d.run(0, N + 1) << endl;
}

int main() {
	MUL();
	return 0;
}