#include using namespace std; //divisor O(sqrt(N)) set Divisor(long long N) { set ret; for (long long i = 1; i*i <= N; ++i) { if (N%i == 0) { ret.insert(i); ret.insert(N / i); } } return ret; } //Greatest Common Divisor long long GCD(long long a, long long b) { return ((b == 0) ? a : GCD(b, a % b)); } int main() { int N,MAX_A = 2000; cin >> N; assert(1<=N && N <= 40); vector A(N); for(int i = 0; i < N; ++i) cin >> A[i]; for(int i = 0; i < N; ++i) assert(1 <= A[i] && A[i] <= 1000); // gcdを前計算 O(MAX_A*MAX_A*log(MAX_A)) vector> gcd(MAX_A+1,vector(MAX_A+1,0)); for(int i = 1; i <= MAX_A; ++i) for(int j = i; j <= MAX_A; ++j) gcd[i][j] = gcd[j][i] = GCD(i,j); //約数のindexをメモするテーブル vector table(MAX_A+1,0); //左端決め打ち全探索 O(N*N*N*M+N*sqrt(A)+N*M*logM) long long ans = 0; for(int i = 0; i < N; ++i) { //約数列挙 O(sqrt(A)) auto d = Divisor(A[i]); int M = d.size(),idx = 0; vector val; //添え字前計算 O(M*logM) for(auto& e:d) { table[e] = idx++; val.push_back(e); } // dp[i][j] := (最後にA[i]を使ってgcdがval[j]になるような場合の数) vector> dp(N, vector(M,0)); dp[i][table[A[i]]] = 1; // 遷移 O(N*N*M) for(int j = i; j < N; ++j) { for(int k = j + 1; k < N; ++k){ for(int l = 0; l < M; ++l){ dp[k][table[gcd[val[l]][A[k]]]] += dp[j][l]; } } ans += dp[j][table[1]]; } } cout << ans << endl; return 0; }