#define DEB
#include <map>
#include <set>
#include <iostream>
#include <vector>
#include <string>
#include <cassert>

#define REP(i,m) for(int i=0;i<(m);++i)
#define REPN(i,m,in) for(int i=(in);i<(m);++i)
#define ALL(t) (t).begin(),(t).end()
#define CLR(a) memset((a),0,sizeof(a))
#define pb push_back
#define mp make_pair
#define fr first
#define sc second

using namespace std;


#ifdef DEB
#define dump(x)  cerr << #x << " = " << (x) << endl
#define prl cerr<<"called:"<< __LINE__<<endl
#define dumpR(x) cerr<<"\x1b[31m"<<#x<<" = " <<(x)<<"\x1b[39m"<<endl
#define dumpY(x) cerr<<"\x1b[33m"<<#x<<" = " <<(x)<<"\x1b[39m"<<endl
#define dumpG(x) cerr<<"\x1b[32m"<<#x<<" = " <<(x)<<"\x1b[39m"<<endl
template<class T> void debug(T a,T b){ for(;a!=b;++a) cerr<<*a<<' ';cerr<<endl;}
#else
#define dump(x) ;
#define dumpR(x) ;
#define dumpY(x) ;
#define dumpG(x) ;
#define prl ;
template<class T> void debug(T a,T b){ ;}
#endif

template<class T> bool chmin(T& a,const T& b) {
    if(a>b) {
        a=b;
        return true;
    }
    return false;
}
template<class T> bool chmax(T& a,const T& b) {
    if(a<b){
        a=b;
        return true;
    }
    return false;
}

typedef long long int lint;
typedef pair<lint,lint> pi;

namespace std{
    template<class S,class T>
    ostream &operator <<(ostream& out,const pair<S,T>& a){
        out<<'('<<a.fr<<','<<a.sc<<')';
        return out;
    }
}

//const int INF=5e8;
template<lint mod>
struct Int_{
    unsigned x;
    static unsigned mpow(Int_ a,unsigned long long k){
        Int_ res=1;
        while(k){
            if(k&1) res=res*a;
            a=a*a;
            k>>=1;
        }
        return res.x;
    }
    static unsigned inverse(Int_ a){
        return mpow(a,mod-2);
    }
    Int_(): x(0) { }
    Int_(long long sig) {
        int sigt=sig%mod;
        if(sigt<0) sigt+=mod;
        x=sigt;
    }
    unsigned get() const { return (unsigned)x; }

    Int_ &operator+=(Int_ that) { if((x += that.x) >= mod) x -= mod; return *this; }
    Int_ &operator-=(Int_ that) { if((x += mod - that.x) >= mod) x -= mod; return *this; }
    Int_ &operator*=(Int_ that) { x = (unsigned long long)x * that.x % mod; return *this; }
    Int_ &operator=(Int_ that) { x=that.x; return *this;}
    Int_ &operator/=(Int_ that) { x=(unsigned long long) x * inverse(that.x)%mod; return *this;}
    bool operator==(Int_ that) const { return x==that.x; }
    bool operator!=(Int_ that) const { return x!=that.x; }

    Int_ operator-() const { return Int_(0)-Int_(*this);}
    Int_ operator+(Int_ that) const { return Int_(*this) += that; }
    Int_ operator-(Int_ that) const { return Int_(*this) -= that; }
    Int_ operator*(Int_ that) const { return Int_(*this) *= that; }
    Int_ operator/(Int_ that) const { return Int_(*this) /= that; }
    Int_ inv(){
        return Int_(mpow(x,mod-2));
    }
};

namespace std{
    template<lint mod>
    ostream &operator <<(ostream& out,const Int_<mod>& a){
        out<<a.get();
        return out;
    }
    template<lint mod>
    istream &operator >>(istream& in,Int_<mod>& a){
        in>>a.x;
        return in;
    }
};
lint gcd(lint a,lint b){
    if(a>b) swap(a,b);

    while(a){
        b%=a;
        swap(a,b);
    }
    return b;
}


typedef Int_<1000000007> Int;

Int calc(lint h,lint w) {
    lint g = gcd(h, w);
    Int base = Int::mpow(2, g);

    base += Int::mpow(2, h) - 2;
    base += Int::mpow(2, w) - 2;
    base += 1;
    return base;
}
lint h,w,T;



int main(){
    cin>>h>>w>>T;

    lint gh=gcd(h,T),gw=gcd(w,T);


    Int res=1;
    res*=Int::mpow(calc(h/gh,w/gw), gh*gw);

    cout<<res<<endl;


    return 0;
}





Measured memory_bytes: 256