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.15.1) (judge verdict: Wrong Answer)

/// Thank you tanakh!!!
/// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

use std::cmp;
use std::collections::BTreeSet;

fn main() {
    input!(n: usize, b: [i64; n]);
    let a = (1..(n + 1)).collect::<Vec<usize>>();
    let mut div = BTreeSet::new();
    for &a in a.iter() {
        let mut a = a;
        if a % 2 == 0 {
            div.insert(2);
            while a % 2 == 0 {
                a /= 2;
            }
        }

        let mut p = 3;
        while p * p <= a {
            if a % p == 0 {
                while a % p == 0 {
                    a /= p;
                }
                div.insert(p);
            }
            p += 2;
        }
        if a > 1 {
            div.insert(a);
        }
    }

    let div = div.iter().map(|&d| d).collect::<Vec<_>>();
    let mut can_divide = vec![vec![false; n]; div.len()];
    for i in 0..div.len() {
        let div = div[i];
        for j in 0..n {
            let a = a[j];
            if a % div == 0 {
                can_divide[i][j] = true;
            }
        }
    }

    let mut selected_div = vec![];
    let mut independent = vec![];
    for i in 0..div.len() {
        let mut only = true;
        for j in (i + 1)..div.len() {
            if can_divide[i] == can_divide[j] {
                only = false;
                break;
            }
        }

        let count = can_divide[i]
            .iter()
            .map(|&b| if b { 1 } else { 0 })
            .sum::<usize>();
        if only {
            if count > 1 {
                selected_div.push(div[i]);
            } else {
                assert!(count == 1);
                let mut pos = 0;
                for j in 0..n {
                    if can_divide[i][j] {
                        pos = j;
                    }
                }
                independent.push(pos);
            }
        }
    }

    assert!(selected_div.len() < 26);
    let m = selected_div.len();

    let mut div_masks = vec![0; n];
    for i in 0..n {
        let mut mask = 0;
        let a = a[i];
        for i in 0..m {
            if a % selected_div[i] == 0 {
                mask |= 1 << i;
            }
        }
        div_masks[i] = mask;
    }

    let mut ans = 0;
    for mask in 0..(1 << m) {
        let mut broken = vec![false; n];
        for i in 0..n {
            if mask & div_masks[i] != 0 {
                broken[i] = true;
            }
        }

        for &i in independent.iter() {
            if !broken[i] && b[i] < 0 {
                broken[i] = true;
            }
        }

        let mut sum = 0;
        for i in 0..n {
            if !broken[i] {
                sum += b[i];
            }
        }

        ans = cmp::max(ans, sum);
    }

    println!("{}", ans);
}