#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define MD (1000000007U)
struct Modint{
  unsigned val;
  Modint(){
    val=0;
  }
  Modint(int a){
    val = ord(a);
  }
  Modint(unsigned a){
    val = ord(a);
  }
  Modint(long long a){
    val = ord(a);
  }
  Modint(unsigned long long a){
    val = ord(a);
  }
  inline unsigned ord(unsigned a){
    return a%MD;
  }
  inline unsigned ord(int a){
    a %= MD;
    if(a < 0){
      a += MD;
    }
    return a;
  }
  inline unsigned ord(unsigned long long a){
    return a%MD;
  }
  inline unsigned ord(long long a){
    a %= MD;
    if(a < 0){
      a += MD;
    }
    return a;
  }
  inline unsigned get(){
    return val;
  }
  inline Modint &operator+=(Modint a){
    val += a.val;
    if(val >= MD){
      val -= MD;
    }
    return *this;
  }
  inline Modint &operator-=(Modint a){
    if(val < a.val){
      val = val + MD - a.val;
    }
    else{
      val -= a.val;
    }
    return *this;
  }
  inline Modint &operator*=(Modint a){
    val = ((unsigned long long)val*a.val)%MD;
    return *this;
  }
  inline Modint &operator/=(Modint a){
    return *this *= a.inverse();
  }
  inline Modint operator+(Modint a){
    return Modint(*this)+=a;
  }
  inline Modint operator-(Modint a){
    return Modint(*this)-=a;
  }
  inline Modint operator*(Modint a){
    return Modint(*this)*=a;
  }
  inline Modint operator/(Modint a){
    return Modint(*this)/=a;
  }
  inline Modint operator+(int a){
    return Modint(*this)+=Modint(a);
  }
  inline Modint operator-(int a){
    return Modint(*this)-=Modint(a);
  }
  inline Modint operator*(int a){
    return Modint(*this)*=Modint(a);
  }
  inline Modint operator/(int a){
    return Modint(*this)/=Modint(a);
  }
  inline Modint operator+(long long a){
    return Modint(*this)+=Modint(a);
  }
  inline Modint operator-(long long a){
    return Modint(*this)-=Modint(a);
  }
  inline Modint operator*(long long a){
    return Modint(*this)*=Modint(a);
  }
  inline Modint operator/(long long a){
    return Modint(*this)/=Modint(a);
  }
  inline Modint operator-(void){
    Modint res;
    if(val){
      res.val=MD-val;
    }
    else{
      res.val=0;
    }
    return res;
  }
  inline operator bool(void){
    return val!=0;
  }
  inline operator int(void){
    return get();
  }
  inline operator long long(void){
    return get();
  }
  inline Modint inverse(){
    int a = val;
    int b = MD;
    int u = 1;
    int v = 0;
    int t;
    Modint res;
    while(b){
      t = a / b;
      a -= t * b;
      swap(a, b);
      u -= t * v;
      swap(u, v);
    }
    if(u < 0){
      u += MD;
    }
    res.val = u;
    return res;
  }
  inline Modint pw(unsigned long long b){
    Modint a(*this);
    Modint res;
    res.val = 1;
    while(b){
      if(b&1){
        res *= a;
      }
      b >>= 1;
      a *= a;
    }
    return res;
  }
  inline bool operator==(int a){
    return ord(a)==val;
  }
  inline bool operator!=(int a){
    return ord(a)!=val;
  }
}
;
inline Modint operator+(int a, Modint b){
  return Modint(a)+=b;
}
inline Modint operator-(int a, Modint b){
  return Modint(a)-=b;
}
inline Modint operator*(int a, Modint b){
  return Modint(a)*=b;
}
inline Modint operator/(int a, Modint b){
  return Modint(a)/=b;
}
inline Modint operator+(long long a, Modint b){
  return Modint(a)+=b;
}
inline Modint operator-(long long a, Modint b){
  return Modint(a)-=b;
}
inline Modint operator*(long long a, Modint b){
  return Modint(a)*=b;
}
inline Modint operator/(long long a, Modint b){
  return Modint(a)/=b;
}
inline void rd(int &x){
  int k;
  int m=0;
  x=0;
  for(;;){
    k = getchar_unlocked();
    if(k=='-'){
      m=1;
      break;
    }
    if('0'<=k&&k<='9'){
      x=k-'0';
      break;
    }
  }
  for(;;){
    k = getchar_unlocked();
    if(k<'0'||k>'9'){
      break;
    }
    x=x*10+k-'0';
  }
  if(m){
    x=-x;
  }
}
inline void wt_L(char a){
  putchar_unlocked(a);
}
inline void wt_L(int x){
  int s=0;
  int m=0;
  char f[10];
  if(x<0){
    m=1;
    x=-x;
  }
  while(x){
    f[s++]=x%10;
    x/=10;
  }
  if(!s){
    f[s++]=0;
  }
  if(m){
    putchar_unlocked('-');
  }
  while(s--){
    putchar_unlocked(f[s]+'0');
  }
}
inline void wt_L(Modint x){
  int i;
  i = (int)x;
  wt_L(i);
}
template<class T, class S> inline T pow_L(T a, S b){
  T res = 1;
  res = 1;
  while(b){
    if(b&1){
      res *= a;
    }
    b >>= 1;
    a *= a;
  }
  return res;
}
inline double pow_L(double a, double b){
  return pow(a,b);
}
template<class T> inline T GCD_L(T a,T b){
  T r;
  while(a){
    r=b;
    b=a;
    a=r%a;
  }
  return b;
}
int H;
int W;
int T;
long long rr;
int x[100];
int y[100];
int t[100];
int mp[10][10];
char buf[10][10];
void dfs(int a, int b, int k){
  if(a==H){
    int d, i;
    int aa;
    int bb;
    for(d=(0);d<(10);d++){
      int i;
      for(aa=(0);aa<(H);aa++){
        for(bb=(0);bb<(W);bb++){
          mp[aa][bb] = 0;
        }
      }
      for(i=(0);i<(k);i++){
        aa = x[i];
        bb = y[i];
        if(t[i]==1){
          aa = (aa + d) % H;
        }
        if(t[i]==2){
          bb = (bb + d) % W;
        }
        if(mp[aa][bb]){
          return;
        }
        mp[aa][bb] = 1;
      }
    }
    for(i=(0);i<(k);i++){
      if(t[i]==0){
        buf[x[i]][y[i]] ='.';
      }
      else if(t[i]==1){
        buf[x[i]][y[i]] ='v';
      }
      else{
        buf[x[i]][y[i]] ='>';
      }
    }
    rr++;
  }
  if(b==W){
    dfs(a+1,0,k);
    return;
  }
  x[k] = a;
  y[k] = b;
  t[k] = 0;
  dfs(a,b+1,k+1);
  t[k] = 1;
  dfs(a,b+1,k+1);
  t[k] = 2;
  dfs(a,b+1,k+1);
}
int main(){
  int g1;
  int g2;
  int g;
  Modint res = 1;
  rd(H);
  rd(W);
  rd(T);
  g1 =GCD_L(H, T);
  H /= g1;
  g2 =GCD_L(W, T);
  W /= g2;
  g =GCD_L(H, W);
  res += (pow_L(Modint(2),g)) - 2;
  res += (pow_L(Modint(2),H)) - 1;
  res += (pow_L(Modint(2),W)) - 1;
  (res = pow_L(res,g1));
  (res = pow_L(res,g2));
  wt_L(res);
  wt_L('\n');
  return 0;
}
// cLay varsion 20191123-1

// --- original code ---
// int H, W, T;
// 
// ll rr;
// int x[100], y[100], t[100];
// int mp[10][10];
// char buf[10][10];
// 
// void dfs(int a, int b, int k){
//   if(a==H){
//     int aa, bb;
//     rep(d,10){
//       rep(aa,H) rep(bb,W) mp[aa][bb] = 0;
//       rep(i,k){
//         aa = x[i];
//         bb = y[i];
//         if(t[i]==1) aa = (aa + d) % H;
//         if(t[i]==2) bb = (bb + d) % W;
//         if(mp[aa][bb]) return;
//         mp[aa][bb] = 1;
//       }
//     }
//     rep(i,k) buf[x[i]][y[i]] = if[t[i]==0, '.', t[i]==1, 'v', '>'];
// //    rep(i,H) wt(buf[i]); wt("");
//     rr++;
//   }
//   if(b==W) dfs(a+1,0,k), return;
// 
//   x[k] = a;
//   y[k] = b;
//   t[k] = 0; dfs(a,b+1,k+1);
//   t[k] = 1; dfs(a,b+1,k+1);
//   t[k] = 2; dfs(a,b+1,k+1);
// }
// 
// {
//   int g1, g2, g;
//   Modint res = 1;
//   rd(H,W,T);
// 
//   //dfs(0,0,0);
//   //wt(rr);
// 
//   g1 = gcd(H,T);
//   H /= g1;
//   g2 = gcd(W,T);
//   W /= g2;
// 
//   g = gcd(H,W);
//   //wt(H,W,g);
//   res += (Modint(2) ** g) - 2;
//   res += (Modint(2) ** H) - 1;
//   res += (Modint(2) ** W) - 1;
// 
//   res **= g1;
//   res **= g2;
//   wt(res);
// }


Measured memory_bytes: 256