#include <iostream>
#include <vector>
#include <array>
#include <list>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <string>
#include <sstream>
#include <algorithm>
#include <random>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cmath>
#include <cassert>
#include <climits>
#include <bitset>
#include <functional>
#include <iomanip>

#define FOR_LT(i, beg, end) for (int i = beg; i < end; i++)
#define FOR_LE(i, beg, end) for (int i = beg; i <= end; i++)
#define FOR_DW(i, beg, end) for (int i = beg; end <= i; i--)

using namespace std;

static const int64_t kRem = 1000000007;

int64_t gcd(int64_t a, int64_t b) {
	if (a < b) swap(a, b);
	if (a % b == 0) return b;
	return gcd(b, a % b);
}


int64_t pow_rem(int64_t x, int64_t m, int64_t rem)
{
	if (m == 0) {
		return 1;
	}
	if (m == 1) {
		return x;
	}

	if (m & 1) {
		int64_t val = pow_rem(x, m / 2, rem);
		val = val * val;
		val %= rem;
		val *= x;
		val %= rem;
		return val;
	}
	else {
		int64_t val = pow_rem(x, m / 2, rem);
		val = val * val;
		val %= rem;
		return val;
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout << fixed << setprecision(20);

	int64_t h, w, t; cin >> h >> w >> t;

	int64_t hgcd = gcd(h, t);
	int64_t wgcd = gcd(w, t);
	int64_t hn = h / hgcd;
	int64_t wn = w / wgcd;

	int64_t ans = pow_rem(2, hn, kRem);
	ans += pow_rem(2, wn, kRem);
	ans -= 1;
	ans %= kRem;
	int64_t ngcd = gcd(hn, wn);
	if (ngcd != 1) {
		ans += pow_rem(2, ngcd, kRem);
		ans -= 2;
		ans %= kRem;
	}

	int64_t ans2 = 0;
	ans2 = pow_rem(ans, hgcd * wgcd, kRem);
	ans2 %= kRem;
	
	cout << ans2 << endl;

	return 0;
}