// 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;
}
	
