#include typedef long long ll; typedef unsigned long long ull; #define FOR(i,a,b) for(int (i)=(a);i<(b);i++) #define REP(i,n) FOR(i,0,n) #define RANGE(vec) (vec).begin(),(vec).end() using namespace std; const ll Mod = (int)(1E+9)+7; class Invigilator2 { public: // // x^(10^k) = x^(10^(k-1)*10) // = x^(10^(k-1)) * ... * x^(10^(k-1)) // なので計算量が落とせる ll tenPow(ll a, string k) { reverse(RANGE(k)); ll ret = 1LL; ll prev = a; // a^(10^(k-1)) for (auto c : k) { ll cur = 1LL; ll ten = 1LL; REP(i,c-'0') (cur *= prev) %= Mod; (ret *= cur) %= Mod; REP(i,10) (ten *= prev) %= Mod; prev = ten; } return ret; } // P(x) := x 個いすがある机で x 番目に座る // Q(x) := x 個いすがある机で x 番目に座らない // とすると // // P(x+1) = Q(x) // Q(x+1) = P(x)+Q(x) // の関係式となる // // R(x) = P(x)+Q(x) が求める組み合わせ数で // R(x+1) = Q(x) + P(x) + Q(x) // = R(x) + R(x-1) // R(0) = 1 // R(1) = 2 // // よりこれはフィボナッチ数列となる // フィボナッチ数は行列累乗で O(log(n)) で解ける // // |R(x+1)| |1 1| |R(x) | // | | = | |*| | // |R(x) | |1 0| |R(x-1)| // // S(x+1) = B*S(x) // S(x) = B^x * S(0) // typedef array Mat; Mat mul(const Mat &a, const Mat &b) { return Mat{(a[0]*b[0]%Mod+a[1]*b[2]%Mod)%Mod, (a[0]*b[1]%Mod+a[1]*b[3]%Mod)%Mod, (a[2]*b[0]%Mod+a[3]*b[2]%Mod)%Mod, (a[2]*b[1]%Mod+a[3]*b[3]%Mod)%Mod}; } Mat mpow(const Mat &x, ll k) { Mat a = x; Mat b{1,0, 0,1}; while (k > 0) { if (k & 1) b = mul(b,a); a = mul(a,a); k >>= 1; } return b; } ll calc(ll x) { auto a = mpow(Mat{1,1,1,0}, x); return mul(a, Mat{2,0, 1,0})[2]; } void solve(void) { int N; cin>>N; vector C(N); vector D(N); REP(i,N) { cin>>C[i]>>D[i]; } ll cnt = 1LL; REP(i,N) { (cnt *= tenPow(calc(C[i]), D[i])) %= Mod; } cout<solve(); delete obj; return 0; } #endif