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

import java.util.*;

class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        long[] A = new long[n+1];
        for(int i = 1; i<=n;i++) A[i] =sc.nextLong();
        Flow sl = new Flow(A);
        long res = sl.max_flow(0,n+1);
        long sum = 0;
        for(int i=1;i<=n;i++) sum += Math.max(0,A[i]);
        System.out.println(sum-res);
    }
    static class Flow{
        long inf = Long.MAX_VALUE/10000;
        int n;
        int[] level;
        int[] iter;
        ArrayList<Edge>[] map;

        public Flow(long[] A){
            n = A.length-1;
            level = new int[n+2];
            iter = new int[n+2];
            map = new ArrayList[n+2];
            for(int i=0;i<=n+1;i++) map[i] = new ArrayList<>();
            for(int i=1;i<=n;i++){
                if(A[i]<=0) add_Edge(0,i,Math.abs(A[i]));
                if(A[i]>0) add_Edge(i,n+1,A[i]);
            }
            for(int i=1;i<=n;i++){
                for(int j=2*i; j<=n; j+=i) add_Edge(i, j, inf);
            }
        }

        void add_Edge(int from, int to, long cap){
            map[from].add(new Edge(to, cap, map[to].size()));
            map[to].add(new Edge(from, 0, map[from].size()-1));
        }

        void bfs(int s){
            Arrays.fill(level, -1);
            LinkedList<Integer> que = new LinkedList<>();
            level[s]=0;
            que.add(s);
            while(que.size()>0){
                int v = que.poll();
                for(int i=0;i<map[v].size();i++){
                    Edge e = map[v].get(i);
                    if(e.cap>0&&level[e.to]<0){
                        level[e.to] = level[v]+1;
                        que.add(e.to);
                    }
                }
            }
        }

        long dfs(int v, int t, long f){
            if(v==t) return f;
            int start = iter[v];
            for(int i=start;i<map[v].size();i++){
                Edge e = map[v].get(i);
                if(e.cap>0&&level[v]<level[e.to]){
                    long d = dfs(e.to,t,Math.min(f,e.cap));
                    if(d>0){
                        e.cap -= d;
                        map[e.to].get(e.rev).cap += d;
                        return d;
                    }
                }
                iter[v]++;
            }
            return 0;
        }

        long max_flow(int s, int t){
            long flow = 0;
            for(;;){
                bfs(s);
                if(level[t]<0) return flow;
                Arrays.fill(iter,0);
                long f = dfs(s,t,inf);
                while(f>0){
                    flow += f;
                    f = dfs(s,t,inf);
                }
            }
        }

    }
    static class Edge{
        long cap;
        int to;
        int rev;
        public Edge(int t, long c, int r){
            this.to = t;
            this.cap = c;
            this.rev = r;
        }
    }
}