/*
Linkedin: https://w...content-available-to-author-only...n.com/in/sai-suman-chitturi-9727a2196/
Hackerrank: https://w...content-available-to-author-only...k.com/skynetasspyder?hr_r=1
Codechef: https://w...content-available-to-author-only...f.com/users/suman_18733097
Codeforces: http://c...content-available-to-author-only...s.com/profile/saisumanchitturi
Github: https://g...content-available-to-author-only...b.com/ChitturiSaiSuman
Hackerearth: https://w...content-available-to-author-only...h.com/@chitturi7
SPOJ: Sai Suman Chitturi @out_of_bound
*/
// _____ _ _ __ __ ____ __ _
// / ____| | | | | | \ / | / \ | \ | |
// | |___ | | | | | \/ | / _ \ | . \ | |
// \____ \ | | | | | |\__/| | | /_\ | | |\ \| |
// ____| | | \__/ | | | | | | __ | | | \ ` |
// |_____/ \______/ |_| |_| |__| |__| |_| \__|
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
#include <time.h>
#include <limits.h>
#include <ctype.h>
#include <assert.h>
#define and &&
#define or ||
#define not !
#define is ==
#define newline printf("\n")
#define space printf(" ")
#define endl printf("\n")
#define iter(x,a,b) for(int x=a;x<=b;x++)
#define FOR(x,N) for(int x=0;x<N;x++)
#define For(x,N) for(int x=0;x<N;x++)
#define caseprint printf("Case #%d: ",test+1)
#define inverse(a,p) power(a,p-2,p)
#define scan(a) scanf("%d",&a)
#define scanll(a) scanf("%lld",&a)
#define print(a) printf("%lld",((ll)a))
#define println(a) printf("%lld\n",((ll)a))
#define getName(var) #var
#define debug(var) fprintf(stderr,"%s = %lld\n",getName(var),((ll)var));
#define readInt(arr,nax) FOR(IT,nax) {scan(arr[IT]);}
#define readLL(arr,nax) FOR(IT,nax) {scanll(arr[IT]);}
#define write(arr,nax) FOR(IT,nax) {print(arr[IT]);space;}
#define fill(arr,nax,value) FOR(IT,nax) {arr[IT] = value;}
#define sort123(arr,nax) qsort(arr,nax,sizeof(int),ascending)
#define sort321(arr,nax) qsort(arr,nax,sizeof(int),descending)
#define reverse(arr,nax) FOR(x,nax/2) {arr[x]=arr[nax-x-1];}
#define newInt(nax) (int*)malloc(sizeof(int)*nax)
#define newLong(nax) (ll *)malloc(sizeof(ll)*nax)
#define newString(nax) (char *)malloc(sizeof(char)*nax)
#define copy(from,to,nax) FOR(IT,nax) {to[IT] = from[IT];}
typedef unsigned long long int ull;
typedef long long int ll;
const ll mod = ((ll)(1e9+7)); // 10**9+7
const ll hell = ((ll)(1e9+9)); // 10**9+9
const ll inf = ((ll)(1e18)); // 10**18
static inline void swapInt(int *a, int *b) {int temp=*a;*a=*b;*b=temp;}
static inline void swapChar(char *a, char *b) {char c=*a;*a=*b;*b=c;}
static inline void swapLong(ll *a, ll *b) {ll temp=*a;*a=*b;*b=temp;}
static inline int setBitCount(ll n) {int ans=0;for(;n>0;ans+=(n&1),n>>=1);return ans;}
static inline ll gcd(ll a, ll b) {for(ll rem;b>0;rem=a%b,a=b,b=rem);return a;}
static inline ll lcm(ll a, ll b) {return (a*b)/(gcd(a,b));}
static inline ll max(ll a, ll b) {return (a>b?a:b);}
static inline ll min(ll a, ll b) {return (a<b?a:b);}
static inline ll mul(ll a, ll b, ll p) {return ((a%p*b%p)%p);}
static inline ll add(ll a, ll b, ll p) {return ((a%p+b%p)%p);}
static inline ll sub(ll a, ll b, ll p) {return ((a%p-b%p)+p)%p;}
static inline int sumOfDigits(ll n) {return n>0?n%10+sumOfDigits(n/10):0;}
static inline int numberOfDigits(ll n) {return n>0?1+numberOfDigits(n/10):0;}
static inline void LLFraction(ll *a, ll *b) {ll g = gcd(*a,*b); (*a)/=g; (*b)/=g;}
static inline void IntFraction(int *a, int *b) {int g = gcd(*a,*b); (*a)/=g; (*b)/=g;}
int ascending (const void *a, const void *b) {return *(int*)a>=*(int*)b?1:-1;}
int descending(const void *a, const void *b) {return *(int*)b>=*(int*)a?1:-1;}
ll power(ll x, ll y, ll p)
{
ll result=1;
for(;y>0;y>>=1,x=mul(x,x,p))
{
if(y&1)
result = mul(result,x,p);
}
return result;
}
bool isPrime(ll n)
{
if(n==0 or n==1)
return false;
else if(n==2 or n==3)
return true;
else if(n%2==0 or n%3==0)
return false;
for(int i
=5;i
<=sqrt(n
);i
+=6) if(n%i==0 or n%(i+2)==0)
return false;
return true;
}
typedef struct tuple
{
int value;
}tuple;
int compare(const void *a,const void *b)
{
tuple *t1 = (tuple *)a;
tuple *t2 = (tuple *)b;
int v1 = t1->value;
int v2 = t2->value;
return v1>v2?1:-1;
}
#define size 2000003 // 2 * 10**6+3
int spf[size]={0};
ll count[size] = {0};
void preCompute()
{
for(int i=1;i<size;i+=2)
spf[i]=i;
for(int i=2;i<size;i+=2)
spf[i]=2;
for(int i=3;i*i<size;i+=2)
if(spf[i] is i)
for(int j=i*i;j<size;j+=i)
if(spf[j] is j)
spf[j]=i;
}
void factor(ll x, ll y) {
while(x>1) {
ll c = 0;
int temp = spf[x];
while(x > 1 and spf[x] == temp) {
c++;
x/=temp;
}
count[temp] = count[temp] + c * y;
// debug(temp);
// debug(count[temp]);
}
}
void solve()
{
int n;
scan(n);
FOR(i,n) {
ll x, y;
scanll(x);scanll(y);
factor(x, y);
}
ll ans = 1;
FOR(i, size)
if(count[i] & 1)
count[i]--;
FOR(i, size) {
if(count[i] > 0) {
debug(count[i]);
ll num = sub(power(i, count[i]+2, mod), 1, mod);
ll den = sub(power(i, 2, mod), 1, mod);
ll value = mul(num, inverse(den, mod), mod);
ans = mul(ans, value, mod);
}
}
println(ans);
}
int main()
{
int t=1;
if(!t) scan(t);
preCompute();
For(test,t)
{
// caseprint;
solve();
}
return 0;
}
LyoKTGlua2VkaW46IGh0dHBzOi8vdy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4ubi5jb20vaW4vc2FpLXN1bWFuLWNoaXR0dXJpLTk3MjdhMjE5Ni8KSGFja2VycmFuazogaHR0cHM6Ly93Li4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5rLmNvbS9za3luZXRhc3NweWRlcj9ocl9yPTEKQ29kZWNoZWY6IGh0dHBzOi8vdy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4uZi5jb20vdXNlcnMvc3VtYW5fMTg3MzMwOTcKQ29kZWZvcmNlczogaHR0cDovL2MuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLnMuY29tL3Byb2ZpbGUvc2Fpc3VtYW5jaGl0dHVyaQpHaXRodWI6IGh0dHBzOi8vZy4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4uYi5jb20vQ2hpdHR1cmlTYWlTdW1hbgpIYWNrZXJlYXJ0aDogaHR0cHM6Ly93Li4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5oLmNvbS9AY2hpdHR1cmk3ClNQT0o6IFNhaSBTdW1hbiBDaGl0dHVyaSBAb3V0X29mX2JvdW5kCiovCgovLwkgIF9fX19fICAgXyAgICBfICAgX18gICAgX18gICAgIF9fX18gICAgIF9fICAgIF8KLy8JIC8gX19fX3wgfCB8ICB8IHwgfCAgXCAgLyAgfCAgIC8gICAgXCAgIHwgIFwgIHwgfAovLwkgfCB8X19fICB8IHwgIHwgfCB8ICAgXC8gICB8ICAvICAgXyAgXCAgfCAuIFwgfCB8Ci8vCSBcX19fXyBcIHwgfCAgfCB8IHwgfFxfXy98IHwgfCAgIC9fXCAgfCB8IHxcIFx8IHwKLy8JIF9fX198IHwgfCBcX18vIHwgfCB8ICAgIHwgfCB8ICAgX18gICB8IHwgfCBcIGAgfAovLwkgfF9fX19fLyBcX19fX19fLyB8X3wgICAgfF98IHxfX3wgIHxfX3wgfF98ICBcX198Ci8vCgkJCQkJCQojaW5jbHVkZSA8c3RkaW8uaD4JCQkKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxtYXRoLmg+CiNpbmNsdWRlIDxzdGRib29sLmg+CiNpbmNsdWRlIDx0aW1lLmg+CiNpbmNsdWRlIDxsaW1pdHMuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KCiNkZWZpbmUgYW5kIAkJCQkJJiYKI2RlZmluZSBvciAJCQkJCQl8fAojZGVmaW5lIG5vdCAJCQkJCSEKI2RlZmluZSBpcyAJCQkJCQk9PQojZGVmaW5lIG5ld2xpbmUgCQkJCXByaW50ZigiXG4iKQojZGVmaW5lIHNwYWNlCQkJCQlwcmludGYoIiAiKQojZGVmaW5lIGVuZGwJCQkJCXByaW50ZigiXG4iKQojZGVmaW5lIGl0ZXIoeCxhLGIpIAkJCWZvcihpbnQgeD1hO3g8PWI7eCsrKQojZGVmaW5lIEZPUih4LE4pIAkJCQlmb3IoaW50IHg9MDt4PE47eCsrKQojZGVmaW5lIEZvcih4LE4pIAkJCQlmb3IoaW50IHg9MDt4PE47eCsrKQojZGVmaW5lIGNhc2VwcmludCAJCQkJcHJpbnRmKCJDYXNlICMlZDogIix0ZXN0KzEpCiNkZWZpbmUgaW52ZXJzZShhLHApIAkJCXBvd2VyKGEscC0yLHApCiNkZWZpbmUgc2NhbihhKSAJCQkJc2NhbmYoIiVkIiwmYSkKI2RlZmluZSBzY2FubGwoYSkJCQkJc2NhbmYoIiVsbGQiLCZhKQojZGVmaW5lIHByaW50KGEpIAkJCQlwcmludGYoIiVsbGQiLCgobGwpYSkpCiNkZWZpbmUgcHJpbnRsbihhKQkJCQlwcmludGYoIiVsbGRcbiIsKChsbClhKSkKI2RlZmluZSBnZXROYW1lKHZhcikJCQkjdmFyCiNkZWZpbmUgZGVidWcodmFyKQkJCQlmcHJpbnRmKHN0ZGVyciwiJXMgPSAlbGxkXG4iLGdldE5hbWUodmFyKSwoKGxsKXZhcikpOwojZGVmaW5lIHJlYWRJbnQoYXJyLG5heCkJCUZPUihJVCxuYXgpIHtzY2FuKGFycltJVF0pO30KI2RlZmluZSByZWFkTEwoYXJyLG5heCkJCQlGT1IoSVQsbmF4KSB7c2NhbmxsKGFycltJVF0pO30KI2RlZmluZSB3cml0ZShhcnIsbmF4KQkJCUZPUihJVCxuYXgpIHtwcmludChhcnJbSVRdKTtzcGFjZTt9CiNkZWZpbmUgZmlsbChhcnIsbmF4LHZhbHVlKQkJRk9SKElULG5heCkge2FycltJVF0gPSB2YWx1ZTt9CiNkZWZpbmUgc29ydDEyMyhhcnIsbmF4KQkJcXNvcnQoYXJyLG5heCxzaXplb2YoaW50KSxhc2NlbmRpbmcpCiNkZWZpbmUgc29ydDMyMShhcnIsbmF4KQkJcXNvcnQoYXJyLG5heCxzaXplb2YoaW50KSxkZXNjZW5kaW5nKQojZGVmaW5lIHJldmVyc2UoYXJyLG5heCkJCUZPUih4LG5heC8yKSB7YXJyW3hdPWFycltuYXgteC0xXTt9CiNkZWZpbmUgbmV3SW50KG5heCkJCQkJKGludCopbWFsbG9jKHNpemVvZihpbnQpKm5heCkKI2RlZmluZSBuZXdMb25nKG5heCkJCQkobGwgKiltYWxsb2Moc2l6ZW9mKGxsKSpuYXgpCiNkZWZpbmUgbmV3U3RyaW5nKG5heCkJCQkoY2hhciAqKW1hbGxvYyhzaXplb2YoY2hhcikqbmF4KQojZGVmaW5lIGNvcHkoZnJvbSx0byxuYXgpICAgICAgIEZPUihJVCxuYXgpIHt0b1tJVF0gPSBmcm9tW0lUXTt9Cgp0eXBlZGVmIHVuc2lnbmVkIGxvbmcgbG9uZyBpbnQgdWxsOwp0eXBlZGVmIGxvbmcgbG9uZyBpbnQgbGw7CmNvbnN0IGxsIG1vZCA9ICgobGwpKDFlOSs3KSk7IC8vIDEwKio5KzcKY29uc3QgbGwgaGVsbCA9ICgobGwpKDFlOSs5KSk7IC8vIDEwKio5KzkKY29uc3QgbGwgaW5mID0gKChsbCkoMWUxOCkpOyAvLyAxMCoqMTgKCnN0YXRpYyBpbmxpbmUgdm9pZCBzd2FwSW50KGludCAqYSwgaW50ICpiKSAJCXtpbnQgdGVtcD0qYTsqYT0qYjsqYj10ZW1wO30Kc3RhdGljIGlubGluZSB2b2lkIHN3YXBDaGFyKGNoYXIgKmEsIGNoYXIgKmIpCXtjaGFyIGM9KmE7KmE9KmI7KmI9Yzt9CnN0YXRpYyBpbmxpbmUgdm9pZCBzd2FwTG9uZyhsbCAqYSwgbGwgKmIpCQl7bGwgdGVtcD0qYTsqYT0qYjsqYj10ZW1wO30Kc3RhdGljIGlubGluZSBpbnQgc2V0Qml0Q291bnQobGwgbikJCQkJe2ludCBhbnM9MDtmb3IoO24+MDthbnMrPShuJjEpLG4+Pj0xKTtyZXR1cm4gYW5zO30Kc3RhdGljIGlubGluZSBsbCBnY2QobGwgYSwgbGwgYikgCQkJCXtmb3IobGwgcmVtO2I+MDtyZW09YSViLGE9YixiPXJlbSk7cmV0dXJuIGE7fQpzdGF0aWMgaW5saW5lIGxsIGxjbShsbCBhLCBsbCBiKSAJCQkJe3JldHVybiAoYSpiKS8oZ2NkKGEsYikpO30Kc3RhdGljIGlubGluZSBsbCBtYXgobGwgYSwgbGwgYikgCQkJCXtyZXR1cm4gKGE+Yj9hOmIpO30Kc3RhdGljIGlubGluZSBsbCBtaW4obGwgYSwgbGwgYikgCQkJCXtyZXR1cm4gKGE8Yj9hOmIpO30Kc3RhdGljIGlubGluZSBsbCBtdWwobGwgYSwgbGwgYiwgbGwgcCkgCQkJe3JldHVybiAoKGElcCpiJXApJXApO30Kc3RhdGljIGlubGluZSBsbCBhZGQobGwgYSwgbGwgYiwgbGwgcCkgCQkJe3JldHVybiAoKGElcCtiJXApJXApO30Kc3RhdGljIGlubGluZSBsbCBzdWIobGwgYSwgbGwgYiwgbGwgcCkgCQkJe3JldHVybiAoKGElcC1iJXApK3ApJXA7fQpzdGF0aWMgaW5saW5lIGludCBzdW1PZkRpZ2l0cyhsbCBuKSAJCQl7cmV0dXJuIG4+MD9uJTEwK3N1bU9mRGlnaXRzKG4vMTApOjA7fQpzdGF0aWMgaW5saW5lIGludCBudW1iZXJPZkRpZ2l0cyhsbCBuKQkJCXtyZXR1cm4gbj4wPzErbnVtYmVyT2ZEaWdpdHMobi8xMCk6MDt9CnN0YXRpYyBpbmxpbmUgdm9pZCBMTEZyYWN0aW9uKGxsICphLCBsbCAqYikgCXtsbCBnID0gZ2NkKCphLCpiKTsgKCphKS89ZzsgKCpiKS89Zzt9CnN0YXRpYyBpbmxpbmUgdm9pZCBJbnRGcmFjdGlvbihpbnQgKmEsIGludCAqYikJe2ludCBnID0gZ2NkKCphLCpiKTsgKCphKS89ZzsgKCpiKS89Zzt9CgppbnQgYXNjZW5kaW5nIChjb25zdCB2b2lkICphLCBjb25zdCB2b2lkICpiKQl7cmV0dXJuICooaW50KilhPj0qKGludCopYj8xOi0xO30KaW50IGRlc2NlbmRpbmcoY29uc3Qgdm9pZCAqYSwgY29uc3Qgdm9pZCAqYikJe3JldHVybiAqKGludCopYj49KihpbnQqKWE/MTotMTt9CgpsbCBwb3dlcihsbCB4LCBsbCB5LCBsbCBwKQp7CglsbCByZXN1bHQ9MTsKCWZvcig7eT4wO3k+Pj0xLHg9bXVsKHgseCxwKSkKCXsKCQlpZih5JjEpCgkJCXJlc3VsdCA9IG11bChyZXN1bHQseCxwKTsKCX0KCXJldHVybiByZXN1bHQ7Cn0KCmJvb2wgaXNQcmltZShsbCBuKQp7CglpZihuPT0wIG9yIG49PTEpCgkJcmV0dXJuIGZhbHNlOwoJZWxzZSBpZihuPT0yIG9yIG49PTMpCgkJcmV0dXJuIHRydWU7CgllbHNlIGlmKG4lMj09MCBvciBuJTM9PTApCgkJcmV0dXJuIGZhbHNlOwoJZm9yKGludCBpPTU7aTw9c3FydChuKTtpKz02KQoJCWlmKG4laT09MCBvciBuJShpKzIpPT0wKQoJCQlyZXR1cm4gZmFsc2U7CglyZXR1cm4gdHJ1ZTsKfQoKdHlwZWRlZiBzdHJ1Y3QgdHVwbGUKewoJaW50IHZhbHVlOwp9dHVwbGU7CgppbnQgY29tcGFyZShjb25zdCB2b2lkICphLGNvbnN0IHZvaWQgKmIpCnsKCXR1cGxlICp0MSA9ICh0dXBsZSAqKWE7Cgl0dXBsZSAqdDIgPSAodHVwbGUgKiliOwoJaW50IHYxID0gdDEtPnZhbHVlOwoJaW50IHYyID0gdDItPnZhbHVlOwoJcmV0dXJuIHYxPnYyPzE6LTE7Cn0KCiNkZWZpbmUgc2l6ZSAyMDAwMDAzIC8vIDIgKiAxMCoqNiszCgppbnQgc3BmW3NpemVdPXswfTsKbGwgY291bnRbc2l6ZV0gPSB7MH07Cgp2b2lkIHByZUNvbXB1dGUoKQp7Cglmb3IoaW50IGk9MTtpPHNpemU7aSs9MikKCQlzcGZbaV09aTsKCWZvcihpbnQgaT0yO2k8c2l6ZTtpKz0yKQoJCXNwZltpXT0yOwoJZm9yKGludCBpPTM7aSppPHNpemU7aSs9MikKCQlpZihzcGZbaV0gaXMgaSkKCQkJZm9yKGludCBqPWkqaTtqPHNpemU7ais9aSkKCQkJCWlmKHNwZltqXSBpcyBqKQoJCQkJCXNwZltqXT1pOwp9Cgp2b2lkIGZhY3RvcihsbCB4LCBsbCB5KSB7Cgl3aGlsZSh4PjEpIHsKCQlsbCBjID0gMDsKCQlpbnQgdGVtcCA9IHNwZlt4XTsKCQl3aGlsZSh4ID4gMSBhbmQgc3BmW3hdID09IHRlbXApIHsKCQkJYysrOwoJCQl4Lz10ZW1wOwoJCX0KCQljb3VudFt0ZW1wXSA9IGNvdW50W3RlbXBdICsgYyAqIHk7CgkJLy8gZGVidWcodGVtcCk7CgkJLy8gZGVidWcoY291bnRbdGVtcF0pOwoJfQp9Cgp2b2lkIHNvbHZlKCkKewoJaW50IG47CglzY2FuKG4pOwoJRk9SKGksbikgewoJCWxsIHgsIHk7CgkJc2NhbmxsKHgpO3NjYW5sbCh5KTsKCQlmYWN0b3IoeCwgeSk7Cgl9CglsbCBhbnMgPSAxOwoJRk9SKGksIHNpemUpCgkJaWYoY291bnRbaV0gJiAxKQoJCQljb3VudFtpXS0tOwoJRk9SKGksIHNpemUpIHsKCQlpZihjb3VudFtpXSA+IDApIHsKCQkJZGVidWcoY291bnRbaV0pOwoJCQlsbCBudW0gPSBzdWIocG93ZXIoaSwgY291bnRbaV0rMiwgbW9kKSwgMSwgbW9kKTsKCQkJbGwgZGVuID0gc3ViKHBvd2VyKGksIDIsIG1vZCksIDEsIG1vZCk7CgkJCWxsIHZhbHVlID0gbXVsKG51bSwgaW52ZXJzZShkZW4sIG1vZCksIG1vZCk7CgkJCWFucyA9IG11bChhbnMsIHZhbHVlLCBtb2QpOwoJCX0KCX0KCXByaW50bG4oYW5zKTsKfQoKaW50IG1haW4oKQp7CglpbnQgdD0xOwoJaWYoIXQpIHNjYW4odCk7CglwcmVDb21wdXRlKCk7CglGb3IodGVzdCx0KQoJewoJCS8vIGNhc2VwcmludDsKCQlzb2x2ZSgpOwoJfQoJcmV0dXJuIDA7Cn0=