// SRM 683, d1-med, by Errichto
#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int nax = 1e7 + 5;
bool isPrime[nax];
vector<int> primes;
set<pair<int,int>> s[nax/10];
map<int,int> occurrences; // occurrences of primes
int mapuj[nax]; // primes into compressed numbers
int true_value[nax/10]; // true value of compressed prime number
struct Factor {
map<int,int> m;
Factor(){}
Factor(int n) {
for(int p : primes) {
int x = true_value[p];
if(x * x > n) break;
while(n % x == 0) {
n /= x;
++m[p];
}
}
if(n > 1) {
assert(isPrime[n]);
++m[mapuj[n]];
}
// for(pair<int,int> p : m) printf("%d:%d ", p.first, p.second);
// puts("");
}
void eat(Factor & other) {
// I am LCM, 'other' is GCD
map<int,int> m2;
for(pair<int,int> p : other.m) {
auto it = m.find(p.first);
if(it != m.end()) {
int tmp = (*it).second;
m2[p.first] = min(tmp, p.second);
m[p.first] = max(tmp, p.second);
}
else m[p.first] = p.second;
}
other.m = m2;
}
void add_to_structures(int i) {
for(pair<int,int> p : m) {
occurrences[p.first]++;
s[p.first].insert(make_pair(p.second, i));
}
}
void remove_from_structures(int i) {
for(pair<int,int> p : m) {
if(occurrences[p.first] == 1) occurrences.erase(p.first);
else --occurrences[p.first];
s[p.first].erase(make_pair(p.second, i));
}
}
} t[nax/10];
class GCDLCM2 {
public : int getMaximalSum(vector <int> start, vector <int> d, vector <int> cnt) {
for(int i = 2; i < nax; ++i) isPrime[i] = true;
for(int i = 2; i * i < nax; ++i) if(isPrime[i])
for(int j = i * i; j < nax; j += i) isPrime[j] = false;
int T = 0;
for(int i = 2; i < nax; ++i) if(isPrime[i]) {
++T;
primes.push_back(T);
true_value[T] = i;
mapuj[i] = T;
}
vector<int> in;
for(int i = 0; i < (int) start.size(); ++i)
for(int j = 0; j < cnt[i]; ++j)
in.push_back(start[i] + d[i] * j);
int n = (int) in.size();
if(n < 50) {
for(int x : in) printf("%d ", x);
puts("");
}
for(int i = 0; i < n; ++i) {
t[i] = Factor(in[i]);
t[i].add_to_structures(i);
}
int answer = n;
while(!occurrences.empty()) {
set<int> bigs;
for(pair<int,int> p : occurrences) {
int prime = p.first;
auto it = s[prime].end();
--it;
bigs.insert((*it).second); // I'm adding index i \in [0,n-1]
}
int lcm = *(bigs.begin()); // index i
t[lcm].remove_from_structures(lcm);
for(int other : bigs) if(other != lcm) {
t[other].remove_from_structures(other);
t[lcm].eat(t[other]);
t[other].add_to_structures(other);
}
int mul = 1;
for(pair<int,int> p : t[lcm].m)
for(int i = 0; i < p.second; ++i)
mul = (long long) mul * true_value[p.first] % mod;
answer = (answer + mul) % mod;
t[lcm].m.clear();
answer = (answer + mod - 1) % mod;
//for(int b : bigs) printf("%d ", b);
//return -124;
}
return answer;
}
};
int main() {
class GCDLCM2 o;
vector<int> in = vector<int>{4,6,12,18,1000003};
vector<int> tmp; while(tmp.size() < in.size()) tmp.push_back(1);
typedef vector<int> vi;
vi a = vi{5,6};
vi b = vi{23,45};
vi c = vi{50000,50000};
printf("%d\n", o.getMaximalSum(a,b,c));
//printf("%d\n", o.getMaximalSum(in, tmp, tmp));
return 0;
}