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)

mod flow {
use std;
use std::collections::VecDeque;

type CapValue = isize;
const INF: CapValue = 999999999999999;

#[derive(Clone, Copy)]
struct Edge {
    to: usize,
    cap: CapValue,
    rev: usize,
}

///最大流を計算(Dinicのアルゴリズム)
pub struct Dinic {
    n: usize,
    g: Vec<Vec<Edge>>,
    iter: Vec<usize>,
    level: Vec<isize>,
}

impl Dinic {
    ///要素数nのグラフを構築する。
    #[warn(dead_code)]
    pub fn new(n: usize) -> Dinic {
        let res = Dinic {
            n: n,
            g: vec![vec![]; n],
            iter: vec![],
            level: vec![],
        };
        res
    }
    #[warn(dead_code)]
    fn bfs(&mut self, s: usize) {
        self.level = vec![-1; self.n];
        let mut que = VecDeque::new();
        self.level[s] = 0;
        que.push_back(s);
        while !que.is_empty() {
            let v = que.pop_front().unwrap();
            for i in 0..self.g[v].len() {
                let e = &self.g[v][i];
                if e.cap > 0 && self.level[e.to] < 0 {
                    self.level[e.to] = self.level[v] + 1;
                    que.push_back(e.to);
                }
            }
        }
    }
    #[warn(dead_code)]
    fn dfs(&mut self, k: usize, t: usize, f: CapValue) -> CapValue {
        if k == t {
            return f;
        }
        for i in self.iter[k]..self.g[k].len() {
            let e = self.g[k][i];
            if e.cap > 0 && self.level[k] < self.level[e.to] {
                let r = self.dfs(e.to, t, std::cmp::min(f, e.cap));
                if r > 0 {
                    self.g[k][i].cap -= r;
                    self.g[e.to][e.rev].cap += r;
                    return r;
                }
            }
        }

        0
    }
    ///最大フローを求める。
    #[warn(dead_code)]
    pub fn get_maxflow(&mut self, s: usize, t: usize) -> CapValue {
        let mut res = 0;
        loop {
            self.bfs(s);
            if self.level[t] < 0 {
                return res;
            }
            self.iter = vec![0; self.n];
            loop {
                let f = self.dfs(s, t, INF);
                if f == 0 {
                    break;
                }
                res += f;
            }
        }
    }
    ///辺の追加
    ///
    /// f->tにvalueの容量を持つ辺を追加する。
    #[warn(dead_code)]
    pub fn add_edge(&mut self, f: usize, t: usize, value: CapValue) {
        let idx_t = self.g[t].len();
        let idx_f = self.g[f].len();
        self.g[f].push(Edge {
            to: t,
            cap: value,
            rev: idx_t,
        });
        self.g[t].push(Edge {
            to: f,
            cap: 0,
            rev: idx_f,
        });
    }
}

///最大流を計算(Ford-Fulkersonのアルゴリズム)
pub struct FordFulkerson {
    n: usize,
    g: Vec<Vec<Edge>>,
    used: Vec<bool>,
}

impl FordFulkerson {
    ///要素数nのグラフを構築する。
    #[warn(dead_code)]
    pub fn new(n: usize) -> FordFulkerson {
        let res = FordFulkerson {
            n: n,
            g: vec![vec![]; n],
            used: vec![],
        };
        res
    }
    #[warn(dead_code)]
    fn dfs(&mut self, k: usize, t: usize, f: CapValue) -> CapValue {
        if k == t {
            return f;
        }
        self.used[k] = true;
        for i in 0..self.g[k].len() {
            let e = self.g[k][i];
            if !self.used[e.to] && e.cap > 0 {
                let r = self.dfs(e.to, t, std::cmp::min(f, e.cap));
                if r > 0 {
                    self.g[k][i].cap -= r;
                    self.g[e.to][e.rev].cap += r;
                    return r;
                }
            }
        }

        0
    }
    ///最大フローを求める。
    #[warn(dead_code)]
    pub fn get_maxflow(&mut self, s: usize, t: usize) -> CapValue {
        let mut res = 0;
        loop {
            self.used = vec![false; self.n];
            let f = self.dfs(s, t, INF);
            if f == 0 {
                return res;
            }
            res += f;
        }
    }
    ///辺の追加
    ///
    /// f->tにvalueの容量を持つ辺を追加する。
    #[warn(dead_code)]
    pub fn add_edge(&mut self, f: usize, t: usize, value: CapValue) {
        let idx_t = self.g[t].len();
        let idx_f = self.g[f].len();
        self.g[f].push(Edge {
            to: t,
            cap: value,
            rev: idx_t,
        });
        self.g[t].push(Edge {
            to: f,
            cap: 0,
            rev: idx_f,
        });
    }
}
}

#[allow(unused_imports)]
use proconio::{
    fastout, input,
    marker::{Bytes, Chars, Isize1, Usize1},
};

use flow::*;

fn main() {
    input! {
        n:usize,
        a:[isize;n]
    }
    let mut f = FordFulkerson::new(n + 2);
    for i in 0..a.len() {
        if a[i] <= 0 {
            f.add_edge(0, i + 1, -1 * a[i]);
        } else {
            f.add_edge(i + 1, n + 1, a[i]);
        }
        let mut k = (i + 1) * 2;
        while k <= n {
            f.add_edge(i + 1, k, 999999999999999);
            k += i + 1;
        }
    }
    println!(
        "{}",
        a.iter().filter(|z| **z > 0).sum::<isize>() - f.get_maxflow(0, n + 1)
    );
}