// Original C++ solution (slower):
//

// Created by yamunaku on 2019/11/15.

//



#include <bits/stdc++.h>



using namespace std;



#define rep(i, n) for(int i = 0; i < (n); i++)

#define repl(i, l, r) for(int i = (l); i < (r); i++)

#define per(i, n) for(int i = ((n)-1); i >= 0; i--)

#define perl(i, l, r) for(int i = ((r)-1); i >= (l); i--)

#define all(x) (x).begin(),(x).end()

#define MOD9 998244353

#define MOD1 1000000007

#define IINF 1000000000

#define LINF 1000000000000000000

#define SP <<" "<<

#define CYES cout<<"Yes"<<endl

#define CNO cout<<"No"<<endl

#define CFS cin.tie(0);ios::sync_with_stdio(false)

#define CST(x) cout<<fixed<<setprecision(x)



using ll = long long;

using ld = long double;

using vi = vector<int>;

using mti = vector<vector<int>>;

using vl = vector<ll>;

using mtl = vector<vector<ll>>;

using pi = pair<int, int>;

using pl = pair<ll, ll>;

template<typename T>

using heap = priority_queue<T, vector<T>, function<bool(const T, const T)>>;



template<typename flow_t>

struct Dinic{

    const flow_t INF;



    struct edge{

        int to;

        flow_t cap;

        int rev;

        bool isrev;

        int idx;

    };



    vector<vector<edge> > graph;

    vector<int> min_cost, iter;



    Dinic(int V) : INF(numeric_limits<flow_t>::max()), graph(V){}



    void add_edge(int from, int to, flow_t cap, int idx = -1){

        graph[from].emplace_back((edge) {to, cap, (int) graph[to].size(), false, idx});

        graph[to].emplace_back((edge) {from, 0, (int) graph[from].size() - 1, true, idx});

    }



    bool bfs(int s, int t){

        min_cost.assign(graph.size(), -1);

        queue<int> que;

        min_cost[s] = 0;

        que.push(s);

        while(!que.empty() && min_cost[t] == -1){

            int p = que.front();

            que.pop();

            for(auto &e : graph[p]){

                if(e.cap > 0 && min_cost[e.to] == -1){

                    min_cost[e.to] = min_cost[p] + 1;

                    que.push(e.to);

                }

            }

        }

        return min_cost[t] != -1;

    }



    flow_t dfs(int idx, const int t, flow_t flow){

        if(idx == t) return flow;

        for(int &i = iter[idx]; i < graph[idx].size(); i++){

            edge &e = graph[idx][i];

            if(e.cap > 0 && min_cost[idx] < min_cost[e.to]){

                flow_t d = dfs(e.to, t, min(flow, e.cap));

                if(d > 0){

                    e.cap -= d;

                    graph[e.to][e.rev].cap += d;

                    return d;

                }

            }

        }

        return 0;

    }



    flow_t max_flow(int s, int t){

        flow_t flow = 0;

        while(bfs(s, t)){

            iter.assign(graph.size(), 0);

            flow_t f = 0;

            while((f = dfs(s, t, INF)) > 0) flow += f;

        }

        return flow;

    }



    void output(){

        for(int i = 0; i < graph.size(); i++){

            for(auto &e : graph[i]){

                if(e.isrev) continue;

                auto &rev_e = graph[e.to][e.rev];

                cout << i << "->" << e.to << " (flow: " << rev_e.cap << "/" << e.cap + rev_e.cap << ")" << endl;

            }

        }

    }

};



int main(){

    // CFS;

    int n;

    cin >> n;

    vl a(n);

    Dinic<ll> dc(n + 2);

    int s = n, t = n + 1;

    ll total = 0;

    rep(i, n){

        cin >> a[i];

        if(a[i] > 0){

            total += a[i];

            dc.add_edge(i, t, a[i]);

        }else if(a[i] < 0){

            dc.add_edge(s, i, -a[i]);

        }

    }

    rep(i, n){

        for(int j = i + i+1; j < n; j += i+1){

            dc.add_edge(i, j, IINF);

        }

    }

    cout << total - dc.max_flow(s, t) << endl;

    return 0;

}

// Optimized solution to the same problem (faster):
#include <algorithm>

#include <cstdio>

using namespace std;

 

int N;

long long A[101], B[101];

int op[101], bb, cc, dd;

 

long long bf(int n) {

  if(n == bb) {

    long long ans = 0;

    for(int i = bb; i < cc; i++) {

      if(op[i] == 0) {

//        vis[i] = 1, vis[i + i] = 1;

        ans += max(0LL, A[i] + (op[i + i] == 0 ? B[i + i] : 0));

      }

    }

    for(int i = cc; i < dd; i++) {

      if(op[i] == 0) {

//        vis[i] = 1;

        ans += B[i];

      }

    }

    for(int i = dd + 1; i <= N; i+=2) {

      if(op[i] == 0) {

//        vis[i] = 1;

        ans += B[i];

      }

    }

    return ans;

  }

  if(op[n]) {

    return bf(n + 1);

  }else {

    long long now = A[n] + bf(n + 1);

    for(int i = n + n; i <= N; i += n) {

      op[i]++;

    }

    now = max(now, bf(n + 1));

    for(int i = n + n; i <= N; i += n) {

      op[i]--;

    }

    return now;

  }

}

 

long long bf2(int n) {

  if(n + n > N) {

    long long ans = 0;

    for(int i = n; i <= N; i++) {

      if(op[i] == 0) ans += B[i];

    }

    return ans;

  }

  if(op[n]) {

    return bf2(n + 1);

  }else {

    long long now = A[n] + bf2(n + 1);

    for(int i = n + n; i <= N; i += n) {

      op[i]++;

    }

    now = max(now, bf2(n + 1));

    for(int i = n + n; i <= N; i += n) {

      op[i]--;

    }

    return now;

  }

}

 

 

int main() {

  scanf("%d", &N);

  bb = N / 3 + 1;

  cc = N / 2 + 1;

  dd = bb + bb;

  for(int i = 1; i <= N; i++) {

    scanf("%lld", &A[i]);

    if(A[i] > 0) B[i] = A[i];

  }

  if(N < 10) printf("%lld\n", max(0LL, A[1] + bf2(2)));

  else printf("%lld\n", max(0LL, A[1] + bf(2)));

//  for(int i = 1; i <= N; i++) if(!vis[i])cout << i << "\n";

}

// Fastest known solution for this problem: