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 Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.util.*;

public class Main {

  static class MaxFlow {
        class Edge {
            public final int to, rev;
            public long cap;
 
            public Edge(int to, int rev, long cap) {
                this.to = to;
                this.rev = rev;
                this.cap = cap;
            }
        }
 
        int v;
        List<Edge> G[];
        boolean used[];
 
        public MaxFlow(int v) {
            this.v = v;
            G = new List[v];
            for (int i = 0; i < v; ++i) {
                G[i] = new ArrayList<>();
            }
            used = new boolean[v];
        }
 
        public void add_edge(int from, int to, long cap) {
            G[from].add(new Edge(to, G[to].size(), cap));
            G[to].add(new Edge(from, G[from].size() - 1, 0));
        }
 
        long dfs(int v, int t, long f) {
            if (v == t) return f;
            used[v] = true;
            for (Edge e : G[v]) {
                if (!used[e.to] && e.cap > 0) {
                    long d = dfs(e.to, t, Math.min(f, e.cap));
                    if (d > 0) {
                        e.cap -= d;
                        G[e.to].get(e.rev).cap += d;
                        return d;
                    }
                }
            }
            return 0;
        }
 
        public long max_flow(int s, int t) {
            long flow = 0;
            while (true) {
                Arrays.fill(used, false);
                long f = dfs(s, t, Long.MAX_VALUE);
                if (f == 0) return flow;
                flow += f;
            }
        }
    }

    public static long solve(int n, long[] a) {
      MaxFlow flow = new MaxFlow(n + 2);
      long ans = 0;
      for(int i = 0; i < n; i++) {
        if(a[i] > 0) ans += a[i];
      }

      for(int i = 0; i < n; i++) {
        if(a[i] > 0) flow.add_edge(i, n + 1, (int)a[i]);
        if(a[i] <= 0) flow.add_edge(n, i, (-1) * (int)a[i]);
      }
      for(int i = 0; i < n; i++) {
        for(int j = 1; (i + 1) * j <= n; j++) {
          flow.add_edge(i, (i + 1) * j - 1, Long.MAX_VALUE / 2);
        }
      }
      return ans - flow.max_flow(n, n + 1);
    }

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int N = sc.nextInt();
    long a[] = new long[N];

    long ans = solve(N, a);

    System.out.println(ans);
  }
}