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: Accepted)

#include "bits/stdc++.h"
using namespace std;

#define MAX 102
int n;
vector<int> A;

struct MaximumFlow {
	typedef int Index;
	typedef long long int Flow;
	static const Flow InfCapacity = LLONG_MAX;
	struct Edge {
		Index to;
		Flow capacity;
		Index rev;
	};
	vector<vector<Edge> > g;
	void init(Index n) { g.assign(n, vector<Edge>()); }
	void add(Index i, Index j, Flow capacity) {
		Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = 0;
		g[i].push_back(e); g[j].push_back(f);
		g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
	}
	void addB(Index i, Index j, Flow capacity) {  //双方向
		Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = capacity;
		g[i].push_back(e); g[j].push_back(f);
		g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
	}
	//gを破壊する
	Flow maximumFlow(int s, int t) {
		int n = g.size();
		vector<Index> level(n);
		Flow total = 0; bool update;
		do {
			update = false;
			fill(level.begin(), level.end(), -1); level[s] = 0;
			queue<Index> q; q.push(s);
			for (Index d = n; !q.empty() && level[q.front()] < d;) {
				int u = q.front(); q.pop();
				if (u == t) d = level[u];
				for (auto e = g[u].begin(); e != g[u].end(); e++) if (e->capacity > 0 && level[e->to] == -1)
					q.push(e->to), level[e->to] = level[u] + 1;
			}
			vector<Index> iter(n);
			for (Index i = 0; i < n; i++) iter[i] = (int)g[i].size() - 1;
			while (1) {
				Flow f = augment(level, iter, s, t, InfCapacity);
				if (f == 0) break;
				total += f; update = true;
			}
		} while (update);
		return total;
	}
	Flow augment(vector<Index> &level, vector<Index> &iter, Index u, Index t, Flow f) {
		if (u == t || f == 0) return f;
		Index lv = level[u];
		if (lv == -1) return 0;
		level[u] = -1;
		for (; iter[u] >= 0; --iter[u]) {
			Edge &e = g[u][iter[u]];
			if (level[e.to] <= lv) continue;
			Flow l = augment(level, iter, e.to, t, min(f, e.capacity));
			if (l == 0) continue;
			e.capacity -= l; g[e.to][e.rev].capacity += l;
			level[u] = lv;
			return l;
		}
		return 0;
	}
};

int main() {
	cin >> n;
	vector<int> pos;
	vector<int> neg;
	long long int sum = 0;
	A.push_back(0);
	for (int i = 0; i < n; i++) {
		int a;
		scanf("%d", &a);
		A.push_back(a);
		sum += max(0, a);
		if (a < 0) {
			neg.push_back(i+1);
		}
		else {
			pos.push_back(i+1);
		}
	}
	MaximumFlow mf;
	mf.init(pos.size() + neg.size() + 2);
	int star = pos.size() + neg.size();
	int en = star + 1;
	for (int i = 0; i < neg.size(); i++) {
		for (int j = 0; j < pos.size(); j++) {
			if (pos[j] % neg[i] == 0) {
				mf.add(i, neg.size() + j, sum + 2LL);
			}
			if (i == 0) {
				mf.add(neg.size()+j, en, A[pos[j]]);
			}
		}
		mf.add(star, i, -A[neg[i]]);
	}
	long long int u = mf.maximumFlow(star, en);
	sum -= u;
	printf("%lld\n", sum);
	return 0;
}