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 Rust (1.42.0) (judge verdict: Accepted)

use proconio::input;

#[derive(Debug, Clone)]
struct FlowEdge {
    to: usize,
    cap: u64,
    rev: usize,
}

fn main() {
    input!(n: usize, a: [i64; n]);
    let mut g = vec![vec![]; n + 2];
    fn insert(u: usize, v: usize, cap: u64, g: &mut [Vec<FlowEdge>]) {
        let lu = g[u].len();
        let lv = g[v].len();
        g[u].push(FlowEdge {
            to: v,
            cap,
            rev: lv,
        });
        g[v].push(FlowEdge {
            to: u,
            cap: 0,
            rev: lu,
        });
    }
    let s = 0;
    let t = n + 1;
    for i in 1..=n {
        for j in std::iter::successors(Some(2 * i), |x| Some(x + i)).take_while(|&x| x <= n) {
            insert(j, i, std::u64::MAX, &mut g);
        }
        let x = a[i - 1];
        if 0 < x {
            insert(s, i, x as u64, &mut g);
        }
        if x < 0 {
            insert(i, t, (-x) as u64, &mut g);
        }
    }

    let mut flow = 0;
    loop {
        let mut dist = vec![std::usize::MAX; n + 2];
        dist[s] = 0;
        let mut queue = std::collections::VecDeque::from(vec![s]);
        while let Some(from) = queue.pop_front() {
            for &FlowEdge { to, cap: _, rev: _ } in g[from].iter().filter(|&e| e.cap != 0) {
                if dist[to] != std::usize::MAX {
                    continue;
                }
                dist[to] = dist[from] + 1;
                queue.push_back(to);
            }
        }

        fn dfs(
            from: usize,
            d: u64,
            g: &[Vec<FlowEdge>],
            dist: &[usize],
            path: &mut Vec<FlowEdge>,
        ) -> u64 {
            if from == g.len() - 1 {
                return d;
            }
            for &FlowEdge { to, cap, rev } in g[from]
                .iter()
                .filter(|&&FlowEdge { to, cap, rev: _ }| dist[from] + 1 == dist[to] && cap != 0)
            {
                let e = dfs(to, d.min(cap), g, dist, path);
                if e != 0 {
                    path.push(FlowEdge { to, cap, rev });
                    return e;
                }
            }
            0
        }
        let mut path = Vec::new();
        let e = dfs(
            s,
            std::u64::MAX,
            g.as_mut_slice(),
            dist.as_slice(),
            &mut path,
        );

        for FlowEdge { to, cap: _, rev } in path {
            g[to][rev].cap += e;
            let FlowEdge {
                to: from,
                cap: _,
                rev: i,
            } = g[to][rev];
            g[from][i].cap -= e;
        }
        flow += e;

        if e == 0 {
            break;
        }
    }

    println!("{}", a.iter().map(|&x| x.max(0)).sum::<i64>() - flow as i64);
}