#include <iostream>
#include <map>

using std::cin;
using std::cout;

class SegTree {
	struct node {
		int c;
		node * left;
		node * right;

		node() : c(0), left(0), right(0) {}

		int count(int ll, int rr, int l, int r) {
			if (this == 0) {
				return 0;
			}
			if (ll < l) {
				ll = l;
			}
			if (rr > r) {
				rr = r;
			}
			if (ll == l && rr == r) {
				return c;
			}
			int mid = r - (r - l) / 2;
			return left->count(ll, rr, l, mid - 1) + right->count(ll, rr, mid, r);
		}
	};

	node root;

public:
	long long maxV;

	SegTree() : root() {}

	void insert(int k) {
		int l = 0, r = maxV;
		node * now = &root;
		while (1) {
			(now->c)++;
			if (l < r) {
				int mid = r - (r - l) / 2;
				if (k < mid) {
					if (now->left == 0) {
						now->left = new node();
					}
					now = now->left;
					r = mid - 1;
				} else {
					if (now->right == 0) {
						now->right = new node();
					}
					now = now->right;
					l = mid;
				}
			} else {
				break;
			}
		}
	}

	void remove(int k) {
		node * now = &root;
		int l = 0, r = maxV;
		while (1) {
			(now->c)--;
			if (l < r) {
				int mid = r - (r - l) / 2;
				if (k < mid) {
					now = now->left;
					r = mid - 1;
				} else {
					now = now->right;
					l = mid;
				}
			} else {
				break;
			}
		}
	}

	int count(int l, int r) {
		if (l > r) {
			return 0;
		}
		return root.count(l, r, 0, maxV);
	}
};

SegTree treei;
SegTree treej;
int maxV;
long long count;

void addi(int k) {
	count += treei.count(k + 1, maxV);
	count += treej.count(0, k - 1);
	treei.insert(k);
}

void addj(int k) {
	count += treei.count(k + 1, maxV);
	count += treej.count(0, k - 1);
	treej.insert(k);
}

void delj(int k) {
	treej.remove(k);
	count -= treei.count(k + 1, maxV);
	count -= treej.count(0, k - 1);
}

long a[100000];

int main() {
	int n;
	long long k;
	cin >> n >> k;
	count = 0;
	maxV = 0;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		if (maxV < a[i]) {
			maxV = a[i];
		}
	}
	treei.maxV = maxV;
	treej.maxV = maxV;
	addi(a[0]);
	for (int i = n - 1; i > 0; i--) {
		addj(a[i]);
	}
	long long ans = 0;
	for (int i = 0, j = 1; i < n - 1; addi(a[++i])) {
		while (count > k && j < n) {
			delj(a[j++]);
		}
		if (j >= n) {
			break;
		}
		ans += n - j;
		if (i + 1 == j) {
			delj(a[j++]);
		}
	}
	cout << ans << "\n";
	return 0;
}


#include <iostream>
#include <algorithm>
#include <map>

using std::cin;
using std::cout;

class SegTree {
	struct node {
		int c;
		node * left;
		node * right;

		node() : c(0), left(0), right(0) {}

		int count(int ll, int rr, int l, int r) {
			if (this == 0) {
				return 0;
			}
			if (ll < l) {
				ll = l;
			}
			if (rr > r) {
				rr = r;
			}
			if (ll == l && rr == r) {
				return c;
			}
			int mid = r - (r - l) / 2;
			return left->count(ll, rr, l, mid - 1) + right->count(ll, rr, mid, r);
		}
	};

	node root;

public:
	long long maxV;

	SegTree() : root() {}

	void insert(int k) {
		int l = 0, r = maxV;
		node * now = &root;
		while (1) {
			(now->c)++;
			if (l < r) {
				int mid = r - (r - l) / 2;
				if (k < mid) {
					if (now->left == 0) {
						now->left = new node();
					}
					now = now->left;
					r = mid - 1;
				} else {
					if (now->right == 0) {
						now->right = new node();
					}
					now = now->right;
					l = mid;
				}
			} else {
				break;
			}
		}
	}

	void remove(int k) {
		node * now = &root;
		int l = 0, r = maxV;
		while (1) {
			(now->c)--;
			if (l < r) {
				int mid = r - (r - l) / 2;
				if (k < mid) {
					now = now->left;
					r = mid - 1;
				} else {
					now = now->right;
					l = mid;
				}
			} else {
				break;
			}
		}
	}

	int count(int l, int r) {
		if (l > r) {
			return 0;
		}
		return root.count(l, r, 0, maxV);
	}
};

SegTree treei;
SegTree treej;
int maxV;
long long count;

void addi(int k) {
	count += treei.count(k + 1, maxV);
	count += treej.count(0, k - 1);
	treei.insert(k);
}

void addj(int k) {
	count += treei.count(k + 1, maxV);
	count += treej.count(0, k - 1);
	treej.insert(k);
}

void delj(int k) {
	treej.remove(k);
	count -= treei.count(k + 1, maxV);
	count -= treej.count(0, k - 1);
}

struct chunk {
	int data;
	int idx;
};

chunk in[100000];
int a[100000];

bool cmpData(const chunk & a, const chunk & b) {
	return a.data < b.data;
}

int main() {
	int n;
	long long k;
	cin >> n >> k;
	count = 0;
	for (int i = 0; i < n; i++) {
		cin >> in[i].data;
		in[i].idx = i;
	}
	std::sort<chunk*>(in, in + n, cmpData);
	maxV = 0;
	a[in[0].idx] = 0;
	for (int i = 1; i < n; i++) {
		if (in[i].data != in[i - 1].data) {
			maxV++;
		}
		a[in[i].idx] = maxV;
	}
	treei.maxV = maxV;
	treej.maxV = maxV;
	for (int i = n - 1; i > 0; i--) {
		count += treej.count(0, a[i] - 1);
		treej.insert(a[i]);
	}
	count += treej.count(0, a[0] - 1);
	treei.insert(a[0]);
	long long ans = 0;
	for (int i = 0, j = 1; i < n - 1; addi(a[++i])) {
		while (count > k && j < n) {
			delj(a[j++]);
		}
		if (j >= n) {
			break;
		}
		ans += n - j;
		if (i + 1 == j) {
			delj(a[j++]);
		}
	}
	cout << ans << "\n";
	return 0;
}


#include <iostream>
#include <algorithm>
#include <map>

#define N 100000

using std::cin;
using std::cout;

int segi[N << 2] = {0};
int segj[N << 2] = {0};
long long c;
int M;

void update(int seg[], int k, int delta) {
	while (k <= M) {
		seg[k] += delta;
		k += ((~k + 1) & k);
	}
}

int count(int seg[], int k) {
	int ret = 0;
	while (k > 0) {
		ret += seg[k];
		k -= ((~k + 1) & k);
	}
	return ret;
}

void add(int seg[], int k) {
	c += segi[M] - count(segi, k);
	c += count(segj, k - 1);
	update(seg, k, 1);
}

void del(int seg[], int k) {
	c -= segi[M] - count(segi, k);
	c -= count(segj, k - 1);
	update(seg, k, -1);
}

struct chunk {
	int data;
	int idx;
};

chunk in[N];
int a[N];

bool cmpData(const chunk & a, const chunk & b) {
	return a.data < b.data;
}

int main() {
	int n;
	long long k;
	cin >> n >> k;
	for (int i = 0; i < n; i++) {
		cin >> in[i].data;
		in[i].idx = i;
	}
	std::sort<chunk*>(in, in + n, cmpData);
	a[in[0].idx] = 1;
	int t = 1;
	for (int i = 1; i < n; i++) {
		if (in[i].data != in[i - 1].data) {
			t += 2;
		}
		a[in[i].idx] = t;
	}
	for (M = 1; M < t; M *= 2) {}
	c = 0;
	for (int i = n - 1; i >= 1; i--) {
		add(segj, a[i]);
	}
	add(segi, a[0]);
	long long ans = 0;
	for (int i = 0, j = 1; i < n - 1; i++) {
		if (j <= i) {
			del(segj, a[j++]);
		}
		add(segi, a[i]);
		while (c > k && j < n) {
			del(segj, a[j++]);
		}
		if (j >= n) {
			break;
		}
		ans += n - j;
	}
	cout << ans << "\n";
	return 0;
}


#include <iostream>
#include <map>

using std::cin;
using std::cout;

class SegTree {
	struct node {
		int c;
		node * left;
		node * right;

		node() : c(0), left(0), right(0) {}

		int count(int ll, int rr, int l, int r) {
			if (this == 0) {
				return 0;
			}
			if (ll < l) {
				ll = l;
			}
			if (rr > r) {
				rr = r;
			}
			if (ll == l && rr == r) {
				return c;
			}
			int mid = r - (r - l) / 2;
			return left->count(ll, rr, l, mid - 1) + right->count(ll, rr, mid, r);
		}
	};

	node root;

public:
	long long maxV;

	SegTree() : root() {}

	void insert(int k) {
		int l = 0, r = maxV;
		node * now = &root;
		while (1) {
			(now->c)++;
			if (l < r) {
				int mid = r - (r - l) / 2;
				if (k < mid) {
					if (now->left == 0) {
						now->left = new node();
					}
					now = now->left;
					r = mid - 1;
				} else {
					if (now->right == 0) {
						now->right = new node();
					}
					now = now->right;
					l = mid;
				}
			} else {
				break;
			}
		}
	}

	void remove(int k) {
		node * now = &root;
		int l = 0, r = maxV;
		while (1) {
			if (l < r) {
				int mid = r - (r - l) / 2;
				if (k < mid) {
					now = now->left;
					r = mid - 1;
				} else {
					now = now->right;
					l = mid;
				}
			} else {
				(now->c)--;
				break;
			}
		}
	}

	int count(int l, int r) {
		if (l > r) {
			return 0;
		}
		return root.count(l, r, 0, maxV);
	}
};

SegTree treei;
SegTree treej;
int maxV;
long long count;

void addi(int k) {
	count += treei.count(k + 1, maxV);
	count += treej.count(0, k - 1);
	treei.insert(k);
}

void addj(int k) {
	count += treei.count(k + 1, maxV);
	count += treej.count(0, k - 1);
	treej.insert(k);
}

void delj(int k) {
	treej.remove(k);
	count -= treei.count(k + 1, maxV);
	count -= treej.count(0, k - 1);
}

long a[100000];

int main() {
	int n;
	long long k;
	cin >> n >> k;
	count = 0;
	maxV = 0;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		if (maxV < a[i]) {
			maxV = a[i];
		}
	}
	treei.maxV = maxV;
	treej.maxV = maxV;
	addi(a[0]);
	for (int i = n - 1; i > 0; i--) {
		addj(a[i]);
	}
	long long ans = 0;
	for (int i = 0, j = 1; i < n - 1; addi(a[++i])) {
		while (count > k && j < n) {
			delj(a[j++]);
		}
		if (j >= n) {
			break;
		}
		ans += n - j;
		if (i + 1 == j) {
			delj(a[j++]);
		}
	}
	cout << ans << "\n";
	return 0;
}


#include <iostream>
#include <map>

using std::cin;
using std::cout;

class SegTree {
	struct node {
		int c;
		node * left;
		node * right;

		node() : c(0), left(0), right(0) {}

		int count(int ll, int rr, int l, int r) {
			if (this == 0) {
				return 0;
			}
			if (ll < l) {
				ll = l;
			}
			if (rr > r) {
				rr = r;
			}
			if (ll == l && rr == r) {
				return c;
			}
			int mid = r - (r - l) / 2;
			return left->count(ll, rr, l, mid - 1) + right->count(ll, rr, mid, r);
		}
	};

	node root;

public:
	long long maxV;

	SegTree() : root() {}

	void insert(int k) {
		int l = 0, r = maxV;
		node * now = &root;
		while (1) {
			(now->c)++;
			if (l < r) {
				int mid = r - (r - l) / 2;
				if (k < mid) {
					if (now->left == 0) {
						now->left = new node();
					}
					now = now->left;
					r = mid - 1;
				} else {
					if (now->right == 0) {
						now->right = new node();
					}
					now = now->right;
					l = mid;
				}
			} else {
				break;
			}
		}
	}

	void remove(int k) {
		node * now = &root;
		int l = 0, r = maxV;
		while (1) {
			(now->c)--;
			if (l < r) {
				int mid = r - (r - l) / 2;
				if (k < mid) {
					now = now->left;
					r = mid - 1;
				} else {
					now = now->right;
					l = mid;
				}
			} else {
				break;
			}
		}
	}

	int count(int l, int r) {
		if (l > r) {
			return 0;
		}
		return root.count(l, r, 0, maxV);
	}
};

SegTree treei;
SegTree treej;
int maxV;
long long count;

void addi(int k) {
	count += treei.count(k + 1, maxV);
	count += treej.count(0, k - 1);
	treei.insert(k);
}

void addj(int k) {
	count += treei.count(k + 1, maxV);
	count += treej.count(0, k - 1);
	treej.insert(k);
}

void delj(int k) {
	treej.remove(k);
	count -= treei.count(k + 1, maxV);
	count -= treej.count(0, k - 1);
}

long a[100000];

int main() {
	int n;
	long long k;
	cin >> n >> k;
	count = 0;
	maxV = 0;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		if (maxV < a[i]) {
			maxV = a[i];
		}
	}
	treei.maxV = maxV;
	treej.maxV = maxV;
	for (int i = n - 1; i > 0; i--) {
		count += treej.count(0, a[i] - 1);
		treej.insert(a[i]);
	}
	count += treej.count(0, a[0] - 1);
	treei.insert(a[0]);
	long long ans = 0;
	for (int i = 0, j = 1; i < n - 1; addi(a[++i])) {
		while (count > k && j < n) {
			delj(a[j++]);
		}
		if (j >= n) {
			break;
		}
		ans += n - j;
		if (i + 1 == j) {
			delj(a[j++]);
		}
	}
	cout << ans << "\n";
	return 0;
}


#include <iostream>
#include <map>

using std::cin;
using std::cout;

class SegTree {
	struct node {
		int c;
		node * left;
		node * right;

		node() : c(0), left(0), right(0) {}

		void insert(int k, int l, int r) {
			c++;
			if (l < r) {
				int mid = r - (r - l) / 2;
				if (k < mid) {
					if (left == 0) {
						left = new node();
					}
					left->insert(k, l, mid - 1);
				} else {
					if (right == 0) {
						right = new node();
					}
					right->insert(k, mid, r);
				}
			}
		}

		bool remove(int k, int l, int r) {
			if (this == 0) {
				return false;
			}
			bool succ;
			if (l < r) {
				int mid = r - (r - l) / 2;
				if (k < mid) {
					succ = left->remove(k, l, mid - 1);
				} else {
					succ = right->remove(k, mid, r);
				}
			} else {
				succ = true;
			}
			if (succ) {
				c--;
			}
			return succ;
		}

		int count(int ll, int rr, int l, int r) {
			if (this == 0) {
				return 0;
			}
			if (ll < l) {
				ll = l;
			}
			if (rr > r) {
				rr = r;
			}
			if (ll == l && rr == r) {
				return c;
			}
			int mid = r - (r - l) / 2;
			return left->count(ll, rr, l, mid - 1) + right->count(ll, rr, mid, r);
		}
	};
	node root;
public:
	SegTree() : root() {}

	void insert(int item) {
		root.insert(item, 0, (1 << 31) - 1);
	}

	void remove(int item) {
		root.remove(item, 0, (1 << 31) - 1);
	}

	int count(int l, int r) {
		if (l > r) {
			return 0;
		}
		return root.count(l, r, 0, (1 << 31) - 1);
	}
};

SegTree tree;
int count = 0;

void add(int k) {
	count += tree.count(k + 1, (1 << 31) - 1);
	tree.insert(k);
}

void del(int k) {
	tree.remove(k);
	count -= tree.count(0, k - 1);
}

long a[100000];

int main() {
	int n, k;
	cin >> n >> k;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	long long ans = 0;
	add(a[0]);
	for (int i = 1, j = 0; i < n; i++) {
		add(a[i]);
		while (count > k) {
			del(a[j++]);
		}
		ans += i - j;
	}
	cout << ans << "\n";
	return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;

int n,m,p,g,tot,i,j,k,ans;
int d[10005],a[10005],b[10005],f[10005];

int gcd(int a,int b){if(!b)return a;return gcd(b,a%b);}
int Power(int a,int b)
{
	int ans=1;
	while(b)
	{
		if(b&1)ans=(long long)ans*a%p;
		a=(long long)a*a%p;
		b>>=1;
	}
	return ans;
}

int main()
{
	scanf("%d%d%d",&n,&m,&p);
	for(i=1;i<=n;++i)scanf("%d",&a[i]);
	for(g=p-1,i=1;i<=m;++i)scanf("%d",&k),g=gcd(k,g);
	for(i=1;i*i<p;++i)
	if((p-1)%i==0)
	{
		d[++tot]=i;
		if((p-1)/i!=i)d[++tot]=(p-1)/i;
	}
	sort(d+1,d+tot+1);
	for(i=1;i<=n;++i)
	for(j=1;j<=tot;++j)
	if(Power(a[i],(long long)g*d[j]%(p-1))==1)
	{
		b[i]=(p-1)/d[j];
		break;
	}
	sort(b+1,b+n+1);
	tot=unique(b+1,b+n+1)-(b+1);
	for(i=tot;i>=1;--i)
	{
		f[i]=(p-1)/b[i];
		for(j=i+1;j<=tot;++j)if(b[j]%b[i]==0)f[i]-=f[j];
		ans+=f[i];
	}
	printf("%d\n",ans);
}


#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;

int n,m,p,g,tot,i,j,k,ans;
int d[100005],a[100005],b[100005],f[100005];
bool use[100005];

int gcd(int a,int b){if(!b)return a;return gcd(b,a%b);}
int Power(int a,int b)
{
	int ans=1;
	while(b)
	{
		if(b&1)ans=(long long)ans*a%p;
		a=(long long)a*a%p;
		b>>=1;
	}
	return ans;
}

int main()
{
	scanf("%d%d%d",&n,&m,&p);
	for(i=1;i<=n;++i)scanf("%d",&a[i]);
	for(g=p-1,i=1;i<=m;++i)scanf("%d",&k),g=gcd(k,g);
	for(i=1;i*i<p;++i)
	if((p-1)%i==0)
	{
		d[++tot]=i;
		if((p-1)/i!=i)d[++tot]=(p-1)/i;
	}
	sort(d+1,d+tot+1);
	for(i=1;i<=tot;++i)
	{
		f[i]=d[i];
		for(j=1;j<i;++j)if(d[i]%d[j]==0)f[i]-=f[j];
	}
	for(i=1;i<=n;++i)
	for(j=1;j<=tot;++j)
	if(Power(a[i],(long long)g*d[j]%(p-1))==1)
	{
		use[j]=true;
		break;
	}
	for(i=1;i<=tot;++i)
	if(use[i])
	for(j=1;j<i;++j)
	if(d[i]%d[j]==0)
	use[j]=true;
	for(i=1;i<=tot;++i)if(use[i])ans+=f[i];
	printf("%d\n",ans);
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<list>
#include<string>
#include<cstring>
#include<complex>
#include<assert.h>

using namespace std;

#define PB push_back
#define MP make_pair
#define F first
#define S second
#define ALL(x) (x).begin(),(x).end()
#define SIZE(x) (int)(x).size()
#define SORT(x) sort((x).begin(),(x).end())
#define CLEAR(tab) memset(tab, 0, sizeof(tab))
#define REP(x, n) for(int x = 0; x < (n); x++)
#define FOR(x, b, e) for(int x = (b); x <= (e); x++)
#define FORD(x, b, e) for(int x = (b); x >= (e); x--)
#define VAR(v, n) __typeof(n) v = (n)
#define FOREACH(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define DEBUG(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)

const int MAX_BUF_SIZE = 16384;
char BUFOR[MAX_BUF_SIZE];
int BUF_SIZE, BUF_POS;
char ZZZ;
int _MINUS;
#define GET(ZZZ){ZZZ='a';if(BUF_POS<BUF_SIZE)ZZZ=BUFOR[BUF_POS++];\
else if(!feof(stdin)){BUF_SIZE=fread(BUFOR,1,MAX_BUF_SIZE,stdin);\
ZZZ=BUFOR[0];BUF_POS=1;}}
#define GI(WW){_MINUS = 1;do{GET(ZZZ);}while(!isdigit(ZZZ)&&ZZZ!='-');if(ZZZ=='-'){_MINUS = -1;GET(ZZZ);}WW=ZZZ-'0';\
while(1){GET(ZZZ);if(!isdigit(ZZZ))break;WW=WW*10+(ZZZ-'0');}WW=WW*_MINUS;}
#define GC(WW){do{GET(ZZZ);}while(!isalpha(ZZZ));WW=ZZZ;}
//FAST IO

typedef long long int LL;
typedef pair<int,int> PII;
typedef vector<int> VI;

const int MXN = 100010;
const int C = 262144;
const int INF = 1000000001;

int rank[MXN];
int n, m, p;
int A[MXN];

VI divs;

int phi[MXN];

int getPhi(int x) {
    if(x == 1)
        return 1;
    if(x < MXN && phi[x])
        return phi[x];

    int tmp = x;
    for(int j = 2; j * j <= x; j++) {
        if(tmp % j == 0) {
            int licz = 0;
            while(tmp % j == 0) {
                licz++;
                tmp /= j;
            }

            if(tmp == 1)
                phi[x] = (LL)(j - 1) * x / j;
            else
                phi[x] = phi[tmp] * phi[x / tmp];
            return phi[x];
        }
    }

    phi[x] = x - 1;
    return phi[x];
}

void calcDivs() {
    int tmp = p - 1;
    for(int i = 1; i * i <= p; i++) {
        if(tmp % i == 0) {
            divs.PB(i);
            if(tmp / i != i)
                divs.PB(tmp / i);
        }
    }
    SORT(divs);
}

int power(int x, int pot) {
    int res = 1;
    int po = x;

    while(pot) {
        if(pot % 2)
            res = ((LL)res * po) % p;
        po = ((LL)po * po) % p;
        pot /= 2;
    }

    return res;
}

int getRank(int x) {
    if(x == 1)
        return -1;
    FOREACH(it, divs)
        if(power(x, *it) == 1)
            return *it;
    assert(0);
}

void test() {
    scanf("%d %d %d", &n, &m, &p);

    phi[1] = 1;
    calcDivs();

    FOR(i, 1, n)
        scanf("%d", &A[i]);

    int g = p - 1;
    FOR(i, 1, m) {
        int b;
        scanf("%d", &b);
        g = __gcd(g, b);
    }

    FOR(i, 1, n)
        rank[i] = getRank(power(A[i], g) );

    int res = 0;
    FOREACH(it, divs)
        FOR(i, 1, n)
            if(rank[i] % *it == 0) {
                res += getPhi(*it);
                break;
            }

    printf("%d\n", res);
}

int main() {
    int te = 1;
    //scanf("%d", &te);
    while(te--)
        test();
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<list>
#include<string>
#include<cstring>
#include<complex>
#include<assert.h>

using namespace std;

#define PB push_back
#define MP make_pair
#define F first
#define S second
#define ALL(x) (x).begin(),(x).end()
#define SIZE(x) (int)(x).size()
#define SORT(x) sort((x).begin(),(x).end())
#define CLEAR(tab) memset(tab, 0, sizeof(tab))
#define REP(x, n) for(int x = 0; x < (n); x++)
#define FOR(x, b, e) for(int x = (b); x <= (e); x++)
#define FORD(x, b, e) for(int x = (b); x >= (e); x--)
#define VAR(v, n) __typeof(n) v = (n)
#define FOREACH(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define DEBUG(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)

const int MAX_BUF_SIZE = 16384;
char BUFOR[MAX_BUF_SIZE];
int BUF_SIZE, BUF_POS;
char ZZZ;
int _MINUS;
#define GET(ZZZ){ZZZ='a';if(BUF_POS<BUF_SIZE)ZZZ=BUFOR[BUF_POS++];\
else if(!feof(stdin)){BUF_SIZE=fread(BUFOR,1,MAX_BUF_SIZE,stdin);\
ZZZ=BUFOR[0];BUF_POS=1;}}
#define GI(WW){_MINUS = 1;do{GET(ZZZ);}while(!isdigit(ZZZ)&&ZZZ!='-');if(ZZZ=='-'){_MINUS = -1;GET(ZZZ);}WW=ZZZ-'0';\
while(1){GET(ZZZ);if(!isdigit(ZZZ))break;WW=WW*10+(ZZZ-'0');}WW=WW*_MINUS;}
#define GC(WW){do{GET(ZZZ);}while(!isalpha(ZZZ));WW=ZZZ;}
//FAST IO

typedef long long int LL;
typedef pair<int,int> PII;
typedef vector<int> VI;

const int MXN = 1000010;
const int C = 262144;
const int INF = 1000000001;

int rank[MXN], phi[MXN], A[MXN];
int n, m, p;
VI divs;

int getPhi(int x) {
    if(x == 1)
        return 1;
    if(x < MXN && phi[x])
        return phi[x];

    int tmp = x;
    for(int j = 2; (LL)j * j <= x; j++) {
        if(tmp % j == 0) {
            int licz = 0;
            while(tmp % j == 0) {
                licz++;
                tmp /= j;
            }

            if(tmp == 1) {
                if(x >= MXN)
                    return (LL)(j - 1) * x / j;
                phi[x] = (LL)(j - 1) * x / j;
            }
            else {
                if(x >= MXN)
                    return getPhi(tmp) * getPhi(x / tmp);
                phi[x] = getPhi(tmp) * getPhi(x / tmp);
            }
            return phi[x];
        }
    }

    if(x >= MXN)
        return x - 1;
    phi[x] = x - 1;
    return phi[x];
}

void calcDivs() {
    int tmp = p - 1;
    for(int i = 1; i * i <= p; i++) {
        if(tmp % i == 0) {
            divs.PB(i);
            if(tmp / i != i)
                divs.PB(tmp / i);
        }
    }
    SORT(divs);
}

int power(int x, int pot) {
    int res = 1;
    int po = x;

    while(pot) {
        if(pot % 2)
            res = ((LL)res * po) % p;
        po = ((LL)po * po) % p;
        pot /= 2;
    }

    return res;
}

int getRank(int x) {
    if(x == 1)
        return -1;
    FOREACH(it, divs)
        if(power(x, *it) == 1)
            return *it;
    cout<<"PIEPRZU"<<endl;
}

void test() {
    scanf("%d %d %d", &n, &m, &p);

    phi[1] = 1;
    calcDivs();

    FOR(i, 1, n)
        scanf("%d", &A[i]);

    int g = p - 1;
    FOR(i, 1, m) {
        int b;
        scanf("%d", &b);
        g = __gcd(g, b);
    }

    FOR(i, 1, n)
        rank[i] = getRank(power(A[i], g) );

    int res = 0;
    FOREACH(it, divs)
        FOR(i, 1, n)
            if(rank[i] % *it == 0) {
                res += getPhi(*it);
                break;
            }

    printf("%d\n", res);
}

int main() {
    int te = 1;
    //scanf("%d", &te);
    while(te--)
        test();
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<list>
#include<string>
#include<cstring>
#include<complex>
#include<assert.h>

using namespace std;

#define PB push_back
#define MP make_pair
#define F first
#define S second
#define ALL(x) (x).begin(),(x).end()
#define SIZE(x) (int)(x).size()
#define SORT(x) sort((x).begin(),(x).end())
#define CLEAR(tab) memset(tab, 0, sizeof(tab))
#define REP(x, n) for(int x = 0; x < (n); x++)
#define FOR(x, b, e) for(int x = (b); x <= (e); x++)
#define FORD(x, b, e) for(int x = (b); x >= (e); x--)
#define VAR(v, n) __typeof(n) v = (n)
#define FOREACH(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define DEBUG(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)

const int MAX_BUF_SIZE = 16384;
char BUFOR[MAX_BUF_SIZE];
int BUF_SIZE, BUF_POS;
char ZZZ;
int _MINUS;
#define GET(ZZZ){ZZZ='a';if(BUF_POS<BUF_SIZE)ZZZ=BUFOR[BUF_POS++];\
else if(!feof(stdin)){BUF_SIZE=fread(BUFOR,1,MAX_BUF_SIZE,stdin);\
ZZZ=BUFOR[0];BUF_POS=1;}}
#define GI(WW){_MINUS = 1;do{GET(ZZZ);}while(!isdigit(ZZZ)&&ZZZ!='-');if(ZZZ=='-'){_MINUS = -1;GET(ZZZ);}WW=ZZZ-'0';\
while(1){GET(ZZZ);if(!isdigit(ZZZ))break;WW=WW*10+(ZZZ-'0');}WW=WW*_MINUS;}
#define GC(WW){do{GET(ZZZ);}while(!isalpha(ZZZ));WW=ZZZ;}
//FAST IO

typedef long long int LL;
typedef pair<int,int> PII;
typedef vector<int> VI;

const int MXN = 100010;
const int C = 262144;
const int INF = 1000000001;

int rank[MXN];
int n, m, p;
int A[MXN];

VI divs;

int phi[MXN];

int getPhi(int x) {
    if(x == 1)
        return 1;
    if(x < MXN && phi[x])
        return phi[x];

    int tmp = x;
    for(int j = 2; j * j <= x; j++) {
        if(tmp % j == 0) {
            int licz = 0;
            while(tmp % j == 0) {
                licz++;
                tmp /= j;
            }

            if(tmp == 1)
                phi[x] = (LL)(j - 1) * x / j;
            else
                phi[x] = phi[tmp] * phi[x / tmp];
            return phi[x];
        }
    }

    phi[x] = x - 1;
    return phi[x];
}

void calcDivs() {
    int tmp = p - 1;
    for(int i = 1; i * i <= p; i++) {
        if(tmp % i == 0) {
            divs.PB(i);
            if(tmp / i != i)
                divs.PB(tmp / i);
        }
    }
    SORT(divs);
}

int power(int x, int pot) {
    int res = 1;
    int po = x;

    while(pot) {
        if(pot % 2)
            res = ((LL)res * po) % p;
        po = ((LL)po * po) % p;
        pot /= 2;
    }

    return res;
}

int getRank(int x) {
    if(x == 1)
        assert(0);
    FOREACH(it, divs)
        if(power(x, *it) == 1)
            return *it;
    assert(0);
}

void test() {
    scanf("%d %d %d", &n, &m, &p);

    phi[1] = 1;
    calcDivs();

    FOR(i, 1, n)
        scanf("%d", &A[i]);

    int g = p - 1;
    FOR(i, 1, m) {
        int b;
        scanf("%d", &b);
        g = __gcd(g, b);
    }

    FOR(i, 1, n)
        rank[i] = getRank(power(A[i], g) );

    int res = 0;
    FOREACH(it, divs)
        FOR(i, 1, n)
            if(rank[i] % *it == 0) {
                res += getPhi(*it);
                break;
            }

    printf("%d\n", res);
}

int main() {
    int te = 1;
    //scanf("%d", &te);
    while(te--)
        test();
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<list>
#include<string>
#include<cstring>
#include<complex>
#include<assert.h>

using namespace std;

#define PB push_back
#define MP make_pair
#define F first
#define S second
#define ALL(x) (x).begin(),(x).end()
#define SIZE(x) (int)(x).size()
#define SORT(x) sort((x).begin(),(x).end())
#define CLEAR(tab) memset(tab, 0, sizeof(tab))
#define REP(x, n) for(int x = 0; x < (n); x++)
#define FOR(x, b, e) for(int x = (b); x <= (e); x++)
#define FORD(x, b, e) for(int x = (b); x >= (e); x--)
#define VAR(v, n) __typeof(n) v = (n)
#define FOREACH(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define DEBUG(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)

const int MAX_BUF_SIZE = 16384;
char BUFOR[MAX_BUF_SIZE];
int BUF_SIZE, BUF_POS;
char ZZZ;
int _MINUS;
#define GET(ZZZ){ZZZ='a';if(BUF_POS<BUF_SIZE)ZZZ=BUFOR[BUF_POS++];\
else if(!feof(stdin)){BUF_SIZE=fread(BUFOR,1,MAX_BUF_SIZE,stdin);\
ZZZ=BUFOR[0];BUF_POS=1;}}
#define GI(WW){_MINUS = 1;do{GET(ZZZ);}while(!isdigit(ZZZ)&&ZZZ!='-');if(ZZZ=='-'){_MINUS = -1;GET(ZZZ);}WW=ZZZ-'0';\
while(1){GET(ZZZ);if(!isdigit(ZZZ))break;WW=WW*10+(ZZZ-'0');}WW=WW*_MINUS;}
#define GC(WW){do{GET(ZZZ);}while(!isalpha(ZZZ));WW=ZZZ;}
//FAST IO

typedef long long int LL;
typedef pair<int,int> PII;
typedef vector<int> VI;

const int MXN = 100010;
const int C = 262144;
const int INF = 1000000001;

int rank[MXN];
int n, m, p;
int A[MXN];

VI divs;

int phi[MXN];

int getPhi(int x) {
    if(x == 1)
        return 1;
    if(x < MXN && phi[x])
        return phi[x];

    int tmp = x;
    for(int j = 2; j * j <= x; j++) {
        if(tmp % j == 0) {
            int licz = 0;
            while(tmp % j == 0) {
                licz++;
                tmp /= j;
            }

            if(tmp == 1)
                phi[x] = (LL)(j - 1) * x / j;
            else
                phi[x] = phi[tmp] * phi[x / tmp];
            return phi[x];
        }
    }

    phi[x] = x - 1;
    return phi[x];
}

void calcDivs() {
    int tmp = p - 1;
    for(int i = 2; i * i <= p; i++) {
        if(tmp % i == 0) {
            divs.PB(i);
            if(tmp / i != i)
                divs.PB(tmp / i);
        }
    }
    if(tmp > 1)
        divs.PB(tmp);
    divs.PB(1);
    SORT(divs);
}

int power(int x, int pot) {
    int res = 1;
    int po = x;

    while(pot) {
        if(pot % 2)
            res = (LL)res * po % p;
        po = (LL)po * po % p;
        pot /= 2;
    }

    return res;
}

int getRank(int x) {
    FOREACH(it, divs)
        if(power(x, *it) == 1)
            return *it;
    assert(0);
}

void test() {
    scanf("%d %d %d", &n, &m, &p);

    phi[1] = 1;
    calcDivs();

    FOR(i, 1, n)
        scanf("%d", &A[i]);

    int g = p - 1;
    FOR(i, 1, m) {
        int b;
        scanf("%d", &b);
        g = __gcd(g, b);
    }

    FOR(i, 1, n)
        rank[i] = getRank(pow(A[i], g) );

    int res = 0;
    FOREACH(it, divs)
        FOR(i, 1, n)
            if(rank[i] % *it == 0) {
                res += getPhi(*it);
                break;
            }

    printf("%d\n", res);
}

int main() {
    int te = 1;
    //scanf("%d", &te);
    while(te--)
        test();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <iomanip>
#include <algorithm>
#include <map>
#include <set>
#include <string>
#include <vector>

using namespace std;
typedef long long ll;
const int MAXN = 10100;
const int MAXM = 100100;

int N, M;
ll P;
ll a[MAXN];
ll b[MAXM];
ll B;

vector <ll> factors;
vector <int> fcount;
vector <int> lo;

ll gcf (ll x, ll y)
{
	if (y == 0) return x;
	return gcf (y, x % y);
}

ll mpow (ll x, ll y) //x ^ y
{
	ll ans = 1;
	ll cpow = x;
	ll cexp = 1;

	while (cexp <= y)
	{
		if (y & cexp)
			ans = (ans * cpow) % P;
		cpow = (cpow * cpow) % P;
		cexp *= 2;
	}
	return ans;
}

int main()
{
	cin >> N >> M >> P;
	for (int i = 0; i < N; i++)
		cin >> a[i];
	for (int i = 0; i < M; i++)
		cin >> b[i];

	B = b[0];
	for (int i = 1; i < M; i++)
		B = gcf (B, b[i]);
	for (int i = 0; i < N; i++)
		a[i] = mpow (a[i], B);

	factors.clear();
	ll temp = P - 1;
	for (ll i = 2; i * i <= temp; i++)
	{
		if (temp % i == 0)
		{
			factors.push_back (i);
			fcount.push_back (0);
			while (temp % i == 0)
			{
				fcount[fcount.size()-1]++;
				temp /= i;
			}

			lo.push_back (fcount[fcount.size()-1]);
		}
	}
	if (temp > 1)
	{
		factors.push_back (temp);
		fcount.push_back (1);
		lo.push_back (1);
	}

	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < factors.size(); j++)
		{
			ll tval = (P - 1);
			for (int k = 0; k < fcount[j]; k++)
			{
				tval /= factors[j];

				//cout << k << " " << tval << " " << factors[j] << "\n";
				//cout << mpow (a[i], tval) << "\n";

				if (mpow (a[i], tval) > 1)
				{
					lo[j] = min (lo[j], k);
				}
			}
		}
	}

	/*for (int i = 0; i < factors.size(); i++)
	{
		cout << factors[i] << " " << fcount[i] << " " << lo[i] << "\n";
	}
	cout << "\n";
	for (int i = 0; i < N; i++)
		cout << a[i] << " ";
	cout << "\n";*/

	ll ans = P - 1;
	for (int i = 0; i < factors.size(); i++)
		for (int j = 0; j < lo[i]; j++)
			ans /= factors[i];
	cout << ans << "\n";
	return 0;
}


#include <iostream>
#include <cstdio>
#include <iomanip>
#include <algorithm>
#include <map>
#include <set>
#include <string>
#include <vector>

using namespace std;
typedef long long ll;
const int MAXN = 10100;
const int MAXM = 100100;

int N, M;
ll P;
ll a[MAXN];
ll b[MAXM];
ll B;

vector <ll> factors;
vector <int> fcount;

vector <int> lcount[MAXN];
vector <int> tlist;

ll gcf (ll x, ll y)
{
	if (y == 0) return x;
	return gcf (y, x % y);
}

ll mpow (ll x, ll y) //x ^ y
{
	ll ans = 1;
	ll cpow = x;
	ll cexp = 1;

	while (cexp <= y)
	{
		if (y & cexp)
			ans = (ans * cpow) % P;
		cpow = (cpow * cpow) % P;
		cexp *= 2;
	}
	return ans;
}

int main()
{
	cin >> N >> M >> P;
	for (int i = 0; i < N; i++)
		cin >> a[i];
	for (int i = 0; i < M; i++)
		cin >> b[i];

	B = b[0];
	for (int i = 1; i < M; i++)
		B = gcf (B, b[i]);
	for (int i = 0; i < N; i++)
		a[i] = mpow (a[i], B);

	factors.clear();
	ll temp = P - 1;
	for (ll i = 2; i * i <= temp; i++)
	{
		if (temp % i == 0)
		{
			factors.push_back (i);
			fcount.push_back (0);
			while (temp % i == 0)
			{
				fcount[fcount.size()-1]++;
				temp /= i;
			}

		}
	}
	if (temp > 1)
	{
		factors.push_back (temp);
		fcount.push_back (1);
	}

	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < factors.size(); j++)
		{
			ll tval = (P - 1);
			for (int k = 0; k < fcount[j]; k++)
			{
				tval /= factors[j];

				//cout << k << " " << tval << " " << factors[j] << "\n";
				//cout << mpow (a[i], tval) << "\n";

				if (mpow (a[i], tval) > 1)
				{
					lcount[i].push_back (k);
					break;
				}
				if (k == fcount[j] - 1)
					lcount[i].push_back (fcount[j]);
			}
		}
	}

	int tot = 1;
	for (int i = 0; i < factors.size(); i++)
		tot *= fcount[i] + 1;

	ll ans = 0;

	for (int i = 0; i < tot; i++)
	{
		int ttemp = i;
		ll nval = 1;

		tlist.clear();
		for (int j = 0; j < factors.size(); j++)
		{
			tlist.push_back (ttemp % (fcount[j] + 1));
			ttemp /= (fcount[j] + 1);

			if (tlist[j] < fcount[j])
			{
				nval *= factors[j] - 1;
				for (int k = fcount[j] - 1; k > tlist[j]; k--)
					nval *= factors[j];
			}
		}

		for (int j = 0; j < N; j++)
		{
			bool check = true;
			for (int k = 0; k < factors.size(); k++)
				if (lcount[j][k] > tlist[k])
				{
					check = false;
					break;
				}
			if (check)
			{
				ans += nval;
				break;
			}
		}
	}
	cout << ans << "\n";

	/*for (int i = 0; i < factors.size(); i++)
	{
		cout << factors[i] << " " << fcount[i] << " " << lo[i] << "\n";
	}
	cout << "\n";
	for (int i = 0; i < N; i++)
		cout << a[i] << " ";
	cout << "\n";*/

	/*ll ans = P - 1;
	for (int i = 0; i < factors.size(); i++)
		for (int j = 0; j < lo[i]; j++)
			ans /= factors[i];
	cout << ans << "\n";*/
	return 0;
}


#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#define N 1000000
#define inf 1e9
#define W 22
#define BASE 2333
#define sqr(p) ((p) * 1ll * (p))
using namespace std;
typedef long long LL;
inline int lowbit(int x) { return x & (-x); }
inline int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
inline int lcm(int a, int b) { return a / gcd(a, b) * b; }
int b[N + 5], d[N + 5], cnt = 0, bg = 0, p, a[N + 5], n, m;
bool vis[N + 5];
LL dp[2][N + 5];
int fpow(int a, int n) {
	LL tmp = a, ans = 1;
	while (n) {
		if (n & 1) ans = ans * tmp % p;
		tmp = tmp * tmp % p, n >>= 1;
	}
	return ans;
}
int main() {
	// freopen("360D.in", "r", stdin);
	scanf("%d%d%d", &n, &m, &p);
	for (int i = 1; i <= n; i++) scanf("%d", a + i);
	for (int i = 1; i <= m; i++) {
		scanf("%d", b + i);
		bg = gcd(bg, b[i]);
	}
	for (int i = 1; i * 1ll * i < p; i++)
		if ((p - 1) % i == 0) {
			d[++cnt] = i;
			if (i * i != p - 1)
				d[++cnt] = (p - 1) / i;
		}
	bg %= p - 1;
	sort(d + 1, d + 1 + cnt);
	for (int i = 1; i <= n; i++) {
		int f = fpow(a[i], bg);
		for (int j = cnt; j; j--)
			if (fpow(f, (p - 1) / d[j]) == 1) {
				vis[j] = 1;
				break;
			}
	}
	dp[0][1] = 1;
	for (int i = 1; i <= cnt; i++)
		if (vis[i])
			for (int j = cnt; j; j--)
				if (dp[0][j] || dp[1][j]) {
					LL tmp0 = dp[0][j], tmp1 = dp[1][j];
					int x = lower_bound(d + 1, d + 1 + cnt, lcm(d[i], d[j])) - d;
					dp[0][x] += tmp1, dp[1][x] += tmp0;
				}
	LL ans = p - 1;
	for (int i = 1; i <= cnt; i++)
		ans += (p - 1) / d[i] * dp[1][i],
		ans -= (p - 1) / d[i] * dp[0][i];
	printf("%lld\n", ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <cassert>
#include <ctime>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;
typedef pair<int,int> PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define N 10010

template <typename T>
T gcd(T a, T b) {
    if (b == 0) return a;
    return gcd(b, a%b);
}

int n, m, P;
int a[N], o[N];
int w[1000010], L;

int pow (int x, int y) {
    int s = 1, t = x;
    while (y) {
        if (y&1) s = (ll) s*t%P;
        y /= 2;
        t = (ll) t*t%P;
    }
    return s;
}

int main()
{
    scanf("%d%d%d", &n, &m, &P);
    for (int i = 1; i <= n; i ++)
        scanf("%d", a+i);
    int g = P-1;
    for (int i = 1; i <= m; i ++) {
        int b; scanf("%d", &b);
        g = gcd(g, b%(P-1));
    }
    int P1 = P-1;
    for (int i = 1; i*i <= P1; i ++)
        if (P1%i == 0) {
            w[L++] = i;
            if (i*i != P1) w[L++] = P1/i;
        }
    sort(w, w+L);
    for (int i = 1; i <= n; i ++) {
        for (int j = 0; j < L; j ++)
            if (pow(a[i], w[j]) == 1) {
                o[i] = w[j]; break;
            }
    }
    int g2 = P-1;
    for (int i = 1; i <= n; i ++)
        g2 = gcd(g2, (int)((ll)(P1/o[i])*g%P1));
    printf("%d\n", (P-1)/g2);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <cassert>
#include <ctime>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;
typedef pair<int,int> PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define N 10010

template <typename T>
T gcd(T a, T b) {
    if (b == 0) return a;
    return gcd(b, a%b);
}

int n, m, P;
int a[N], o[N];
int w[N], L;

int pow (int x, int y) {
    int s = 1, t = x;
    while (y) {
        if (y&1) s = (ll) s*t%P;
        y /= 2;
        t = (ll) t*t%P;
    }
    return s;
}

int main()
{
    scanf("%d%d%d", &n, &m, &P);
    for (int i = 1; i <= n; i ++)
        scanf("%d", a+i);
    int g = P-1;
    for (int i = 1; i <= m; i ++) {
        int b; scanf("%d", &b);
        g = gcd(g, b);
    }
    int P1 = P-1;
    for (int i = 1; i*i <= P1; i ++)
        if (P1%i == 0) {
            w[L++] = i;
            if (i*i != P1) w[L++] = P1/i;
        }
    sort(w, w+L);
    for (int i = 1; i <= n; i ++) {
        for (int j = 0; j < L; j ++)
            if (pow(a[i], w[j]) == 1) {
                o[i] = w[j]; break;
            }
    }
    int g2 = P-1;
    for (int i = 1; i <= n; i ++)
        g2 = gcd(g2, (int)((ll)(P1/o[i])*g%P1));
    printf("%d\n", (P-1)/g2);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <cassert>
#include <ctime>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;
typedef pair<int,int> PII;

#define fi first
#define se second
#define mp make_pair
#define pb push_back

#define N 10010

template <typename T>
T gcd(T a, T b) {
    if (b == 0) return a;
    return gcd(b, a%b);
}

int n, m, P;
int a[N], o[N];
int w[N], L;
int s[N];

int pow (int x, int y) {
    int s = 1, t = x;
    while (y) {
        if (y&1) s = (ll)s*t%P;
        y /= 2;
        t = (ll)t*t%P;
    }
    return s;
}

int phi (int x) {
    int p = 1;
    for (int i = 2; i*i <= x; i ++)
        if (x % i == 0) {
            p *= (i-1); x /= i;
            while (x % i == 0) x /= i, p *= i;
        }
    if (x != 1) p *= (x-1);
    return p;
}

int c[N], Lc;

int main()
{
    scanf("%d%d%d", &n, &m, &P);
    for (int i = 1; i <= n; i ++)
        scanf("%d", a+i);
    int g = P-1;
    for (int i = 1; i <= m; i ++) {
        int b; scanf("%d", &b);
        g = gcd(g, b%(P-1));
    }
    int P1 = P-1;
    for (int i = 1; i*i <= P1; i ++)
        if (P1%i == 0) {
            w[L++] = i;
            if (i*i != P1) w[L++] = P1/i;
        }
    sort(w, w+L);
    for (int i = 1; i <= n; i ++) {
        for (int j = 0; j < L; j ++)
            if (pow(a[i], w[j]) == 1) {
                o[i] = w[j]; break;
            }
    }
    for (int i = 1; i <= n; i ++)
        c[Lc ++] = gcd(P-1, (int)((ll)(P1/o[i])*g%P1));
    /*
    sort(c, c + Lc);
    for (int i = 0; i < Lc; i ++) if (c[i] != -1)
        for (int j = i+1; j < Lc; j ++)
            if (c[j] != -1 && c[j] % c[i] == 0) c[j] = -1;
    int Lc2 = 0;
    for (int i = 0; i < Lc; i ++)
        if (c[i] != -1)
            c[Lc2 ++] = c[i];
    Lc = Lc2;
    */
    /*
    for (int i = 0; i < Lc; i++)
        printf("%d%c", c[i], i == Lc-1?'\n': ' ');
    */
    for (int i = 0; i < L; i ++)
        s[i] = phi(P1/w[i]);
    int S = 0;
    for (int i = 0; i < L; i ++)
        for (int j = 0; j < Lc; j ++)
            if (w[i] % c[j] == 0) {
                S += s[i]; break;
            }
    printf ("%d\n", S);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
int a[10000],b[100000];
set<int>ord;
vector<int> d;
map<PII,long long> mp;
void divs(int val)
{
    d.push_back(1);
    d.push_back(val);
    for(int i=2;i*i<=val;i++)
    {
        if(val%i==0)
        {
            d.push_back(i);
            d.push_back(val/i);
        }
    }
    sort(d.begin(),d.end());
}
int bgmd(int b,int ex,int mod)
{
    int ans=1;
    while(ex)
    {
        if(ex%2)
            ans=(ans*(b*1LL))%mod;
        b=(b*(b*1LL))%mod;
        ex/=2;
    }
    return ans;
}
int gcd(int a,int b)
{
    int tmp;
    if(a<b)
        swap(a,b);
    while(b)
    {
        tmp=a;
        a=b;
        b=tmp%b;
    }
    return a;
}
int lcm(int a,int b)
{
    int g=gcd(a,b);
    return (a/g)*b;
}
int fans(int pos,const vector<int> &v,int curval,int val)
{
    if(mp.find(PII(pos,curval))!=mp.end())
        return mp[PII(pos,curval)];
    int lc=lcm(curval,v[pos]);
    if(pos+1==v.size())
        return val/lc;
    return (mp[PII(pos,curval)]=(val/lc-fans(pos+1,v,lc,val))+fans(pos+1,v,curval,val));
}
int main()
{
    //freopen("in.txt","r",stdin);
    int n,m,i,j,p,g,val;
    scanf("%d%d%d",&n,&m,&p);
    g=p-1;
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        a[i]%=p;
    }
    for(i=0;i<m;i++)
    {
        scanf("%d",&b[i]);
        g=gcd(g,b[i]%(p-1));
    }
    divs(p-1);
    for(i=0;i<n;i++)
    {
        val=bgmd(a[i],g,p);
        for(j=0;j<d.size();j++)
        {
            if(bgmd(val,d[j],p)==1)
            {
                ord.insert(d[j]);
                break;
            }
        }
    }
    vector<int> v(ord.begin(),ord.end());
    reverse(v.begin(),v.end());
    for(i=0;i<v.size();i++)
    {
        v[i]=(p-1)/v[i];
    }
    cout<<fans(0,v,1,p-1)<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
int a[10000],b[100000];
set<int>ord;
vector<int> d;
map<PII,long long> mp;
void divs(int val)
{
    d.push_back(1);
    d.push_back(val);
    for(int i=2;i*i<=val;i++)
    {
        if(val%i==0)
        {
            d.push_back(i);
            d.push_back(val/i);
        }
    }
    sort(d.begin(),d.end());
}
int bgmd(int b,int ex,int mod)
{
    int ans=1;
    while(ex)
    {
        if(ex%2)
            ans=(ans*(b*1LL))%mod;
        b=(b*(b*1LL))%mod;
        ex/=2;
    }
    return ans;
}
int gcd(int a,int b)
{
    int tmp;
    if(a<b)
        swap(a,b);
    while(b)
    {
        tmp=a;
        a=b;
        b=tmp%b;
    }
    return a;
}
long long lcm(int a,int b)
{
    int g=gcd(a,b);
    return (a/g)*b;
}
long long fans(int pos,const vector<int> &v,int curval,int val)
{
    if(mp.find(PII(pos,curval))!=mp.end())
        return mp[PII(pos,curval)];
    long long ans=val/curval,lc;
    int div=1;
    pos++;
    for(;pos<v.size();pos++)
    {
        lc=lcm(curval,v[pos]);
        if(lc==curval)
            div++;
        else
            ans-=fans(pos,v,lc,val);
    }
    return (mp[PII(pos,curval)]=ans);
}
int main()
{
    //freopen("in.txt","r",stdin);
    int n,m,i,j,p,g,val;
    scanf("%d%d%d",&n,&m,&p);
    g=p-1;
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        a[i]%=p;
    }
    for(i=0;i<m;i++)
    {
        scanf("%d",&b[i]);
        g=gcd(g,b[i]%(p-1));
    }
    divs(p-1);
    for(i=0;i<n;i++)
    {
        val=bgmd(a[i],g,p);
        for(j=0;j<d.size();j++)
        {
            if(bgmd(val,d[j],p)==1)
            {
                ord.insert(d[j]);
                break;
            }
        }
    }
    vector<int> v(ord.begin(),ord.end());
    reverse(v.begin(),v.end());
    for(i=0;i<v.size();i++)
    {
        v[i]=(p-1)/v[i];
    }
    long long ans=0;
    for(i=0;i<v.size();i++)
        ans+=fans(i,v,v[i],p-1);
    cout<<ans<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int a[10000],b[100000];
set<int>ord;
vector<int> d;
void divs(int val)
{
    d.push_back(1);
    d.push_back(val);
    for(int i=2;i*i<=val;i++)
    {
        if(val%i==0)
        {
            d.push_back(i);
            d.push_back(val/i);
        }
    }
    sort(d.begin(),d.end());
}
int bgmd(int b,int ex,int mod)
{
    int ans=1;
    while(ex)
    {
        if(ex%2)
            ans=(ans*(b*1LL))%mod;
        b=(b*(b*1LL))%mod;
        ex/=2;
    }
    return ans;
}
int gcd(int a,int b)
{
    int tmp;
    if(a<b)
        swap(a,b);
    while(b)
    {
        tmp=a;
        a=b;
        b=tmp%b;
    }
    return a;
}
long long lcm(int a,int b)
{
    int g=gcd(a,b);
    return (a/g)*b;
}
long long fans(int pos,const vector<int> &v,int curval,int val)
{
    long long ans=val/curval,lc;
    pos++;
    for(;pos<v.size();pos++)
    {
        lc=lcm(curval,v[pos]);
        if(lc<=val)
            ans-=fans(pos,v,lc,val);
        else
            break;
    }
    return ans;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int n,m,i,j,p,g,val;
    scanf("%d%d%d",&n,&m,&p);
    g=p-1;
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        a[i]%=p;
    }
    for(i=0;i<m;i++)
    {
        scanf("%d",&b[i]);
        g=gcd(g,b[i]%(p-1));
    }
    divs(p-1);
    for(i=0;i<n;i++)
    {
        val=bgmd(a[i],g,p);
        for(j=0;j<d.size();j++)
        {
            if(bgmd(val,d[j],p)==1)
            {
                ord.insert(d[j]);
                break;
            }
        }
    }
    vector<int> v(ord.begin(),ord.end());
    reverse(v.begin(),v.end());
    for(i=0;i<v.size();i++)
    {
        v[i]=(p-1)/v[i];
    }
    long long ans=0;
    for(i=0;i<v.size();i++)
        ans+=fans(i,v,v[i],p-1);
    cout<<ans<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
int a[10000],b[100000];
set<int>ord;
vector<int> d;
void divs(int val)
{
    d.push_back(1);
    d.push_back(val);
    for(int i=2;i*i<=val;i++)
    {
        if(val%i==0)
        {
            d.push_back(i);
            d.push_back(val/i);
        }
    }
    sort(d.begin(),d.end());
}
int bgmd(int b,int ex,int mod)
{
    int ans=1;
    while(ex)
    {
        if(ex%2)
            ans=(ans*(b*1LL))%mod;
        b=(b*(b*1LL))%mod;
        ex/=2;
    }
    return ans;
}
int gcd(int a,int b)
{
    int tmp;
    if(a<b)
        swap(a,b);
    while(b)
    {
        tmp=a;
        a=b;
        b=tmp%b;
    }
    return a;
}
long long lcm(int a,int b)
{
    int g=gcd(a,b);
    return (a/g)*b;
}
long long fans(int pos,const vector<int> &v,int curval,int val)
{
    long long ans=val/curval,lc;
    pos++;
    for(;pos<v.size();pos++)
    {
        lc=lcm(curval,v[pos]);
        if(lc<=val)
            ans-=fans(pos,v,lc,val);
        else
            break;
    }
    return ans;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int n,m,i,j,p,g,val;
    scanf("%d%d%d",&n,&m,&p);
    g=p-1;
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        a[i]%=p;
    }
    for(i=0;i<m;i++)
    {
        scanf("%d",&b[i]);
        g=gcd(g,b[i]%(p-1));
    }
    divs(p-1);
    for(i=0;i<n;i++)
    {
        val=bgmd(a[i],g,p);
        for(j=0;j<d.size();j++)
        {
            if(bgmd(val,d[j],p)==1)
            {
                ord.insert(d[j]);
                break;
            }
        }
    }
    vector<int> v(ord.begin(),ord.end());
    reverse(v.begin(),v.end());
    for(i=0;i<v.size();i++)
    {
        v[i]=(p-1)/v[i];
    }
    if(n==10000)
        assert(false);
    long long ans=0;
    for(i=0;i<v.size();i++)
        ans+=fans(i,v,v[i],p-1);
    cout<<ans<<endl;
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <assert.h>

template<class T>inline void readin(T &res) {
	static char ch;T flag = 1;
	while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;
	res=ch-48;
	while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;
	res*=flag;
}
template<class T>inline T abs(T a) {return a>=0?a:-a;}
template<class T>inline T max(T a,T b) {return a>=b?a:b;}
template<class T>inline T min(T a,T b) {return a<=b?a:b;}

int P, PHIP;

int gcd(int a,int b) {return !b? a: gcd(b,a%b);}
int mpow(int a,int b,int mod) {
	static int res;
	for( res = 1; b; b >>= 1, a = 1ll * a * a % mod )
		if(b & 1) res = 1ll * res * a % mod;
	return res;
}

int list[31623], tot;//31623 * 31623 = 1000014129
void find() {
	for( int i = 1; i * i <= PHIP; i++ ) if(PHIP % i == 0) {
		list[++tot] = i;
		list[++tot] = PHIP / i;
	}
}

int n, m, B, a[10010], f[10010];
int main() {
	readin(n);readin(m);readin(P);

	PHIP = P - 1;find();
	std::sort(list+1,list+tot+1);

	for( int i = 1; i <= n; i++ ) readin(a[i]);
	B = PHIP;
	for( int i = 1, x; i <= m; i++ ) readin(x), B = gcd(B, x);
	for( int i = 1, j; i <= n; i++ ) {
		//if a % P == 0 then 0 belong to the set
		a[i] = mpow(a[i], B, P);
		for( j = 1; j <= tot; j++ )
			if(mpow(a[i], list[j], P) == 1)
				{a[i] = PHIP / list[j];break;}
	}

	std::sort(a+1, a+n+1);
	n = std::unique(a+1, a+n+1) - a - 1;
	int ans = 0;
	for( int i = n, j; i >= 1; i-- ) {
		f[i] = PHIP / a[i];
		for( j = i + 1; j <= n; j++ )
			if(a[j] % a[i] == 0)
				f[i] -= f[j];
		ans += f[i];
	}
	printf("%d\n",ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <assert.h>

template<class T>inline void readin(T &res) {
	static char ch;T flag = 1;
	while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;
	res=ch-48;
	while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;
	res*=flag;
}
template<class T>inline T abs(T a) {return a>=0?a:-a;}
template<class T>inline T max(T a,T b) {return a>=b?a:b;}
template<class T>inline T min(T a,T b) {return a<=b?a:b;}

int P, PHIP;

int gcd(int a,int b) {return !b? a: gcd(b,a%b);}
int mpow(int a,int b,int mod) {
	static int res;
	for( res = 1; b; b >>= 1, a = 1ll * a * a % mod )
		if(b & 1) res = 1ll * res * a % mod;
	return res;
}

int list[31623], tot;//31623 * 31623 = 1000014129
void find() {
	for( int i = 2; i * i <= PHIP; i++ ) if(PHIP % i == 0) {
		list[++tot] = i;
		list[++tot] = PHIP / i;
	}
	std::sort(list+1,list+tot+1);
}

int n, m, B, a[10010], f[10010];
int main() {
	readin(n);readin(m);readin(P);

	PHIP = P - 1;find();

	for( int i = 1; i <= n; i++ ) readin(a[i]);
	B = PHIP;
	for( int i = 1, x; i <= m; i++ ) readin(x), B = gcd(B, x);
	for( int i = 1, j; i <= n; i++ ) {
		//if a % P == 0 then 0 belong to the set
		a[i] = mpow(a[i], B, P);
		for( j = 1; j <= tot; j++ )
			if(mpow(a[i], list[j], P) == 1)
				{a[i] = PHIP / list[j];break;}
	}

	std::sort(a+1, a+n+1);
	n = std::unique(a+1, a+n+1) - a - 1;
	int ans = 0;
	for( int i = n, j; i >= 1; i-- ) {
		f[i] = PHIP / a[i];
		for( j = i + 1; j <= n; j++ )
			if(a[j] % a[i] == 0)
				f[i] -= f[j];
		ans += f[i];
	}
	printf("%d\n",ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <assert.h>

template<class T>inline void readin(T &res) {
	static char ch;T flag = 1;
	while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;
	res=ch-48;
	while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;
	res*=flag;
}
template<class T>inline T abs(T a) {return a>=0?a:-a;}
template<class T>inline T max(T a,T b) {return a>=b?a:b;}
template<class T>inline T min(T a,T b) {return a<=b?a:b;}

int P, PHIP, g;

int gcd(int a,int b) {return !b? a: gcd(b,a%b);}
int mpow(int a,int b,int mod) {
	static int res;
	for( res = 1; b; b >>= 1, a = 1ll * a * a % mod )
		if(b & 1) res = 1ll * res * a % mod;
	return res;
}

#include <cmath>
#include <map>
std::map<int,int> mp;
int ind(int a,int b,int mod) {
	int S = (int)(sqrt(mod) + 0.5);
	mp.clear();
	for( int i = 0, v = b; i <= S; i++, v = 1ll * v * a % mod )
		mp[v] = i;
	for( int i = S, base = mpow(a,S,mod), v = base; i <= mod + S; i += S, v = 1ll * v * base % mod )
		if(mp.count(v)) return i-mp[v];
	return -1;
}

int list[10], tot;//2*3*5*7*11*13*17*19*23*29 = 340510170
void find() {
	int tmp = PHIP;
	for( int i = 2; i * i <= tmp; i++ ) if(tmp % i == 0) {
		list[++tot] = PHIP / i;
		while(tmp % i == 0) tmp /= i;
	}
	if(tmp != 1) list[++tot] = PHIP / tmp;
}

#include <vector>
std::vector<std::pair<int,int> > q;
int n, m, B, a[10010], b[100010];
int main() {
	readin(n);readin(m);readin(P);

	PHIP = P - 1;find();g = 2;
	for( int i; ; g++ ) {
		for( i = 1; i <= tot; i++ ) if(mpow(g,list[i],P) == 1) goto hell;
		break;hell:;
	}

	for( int i = 1; i <= n; i++ ) readin(a[i]);
	B = PHIP;
	for( int i = 1, x; i <= m; i++ ) readin(x), B = gcd(B, x);
	for( int i = 1; i <= n; i++ ) {
		//if a % P == 0 then 0 belong to the set
		q.push_back(std::make_pair(gcd(1ll * ind(g,a[i],P) * B % PHIP,PHIP),0));
	}

	std::sort(q.begin(),q.end());
	int ans = 0, siz = std::unique(q.begin(),q.end())-q.begin();
	for( int i = siz - 1, j; i >= 0; i-- ) {
		q[i].second = PHIP / q[i].first;
		for( j = i + 1; j < siz; j++ )
			if(q[j].first % q[i].first == 0)
				q[i].second -= q[j].second;
		ans += q[i].second;
	}
	printf("%d\n",ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <climits>
#include <map>
#include <queue>
using namespace std;

inline int read() {
	int x = 0, f = 1; char ch = getchar();
	for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = -1;
	for (; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return x * f;
}

const int maxn = 10005, maxm = 100005;
int n, m, p, T, phip, ans, a[maxn];
bool vis[maxn];

long long _pow(long long x, long long y) {
	long long ret = 1;
	while(y) {
		if (y & 1) ret = ret * x % p;
		y >>= 1, x = x * x % p;
	}
	return ret % p;
}

int gcd(int a, int b) {
	if (a < b) swap(a, b);
	while(b) b ^= a ^= b ^= a %= b;
	return a;
}

int cur[maxn], tot = 0, phi[maxn];

int main() {
	n = read(), m = read(), p = read(); phip = p - 1;
	for (int i = 1; i <= n; i++) a[i] = read();
	for (int i = 1; i <= m; i++) T = gcd(read(), T);
	for (int i = 1; i * i <= phip; i++) if (phip % i == 0) {
		cur[++tot] = i;
		if (i * i != phip) cur[++tot] = phip / i;
	}
	sort(cur + 1, cur + 1 + tot);
	for (int i = 1; i <= n; i++) {
		int t = _pow(a[i], T);
		for (int j = 1; j <= tot; j++) if (_pow(t, cur[j]) == 1) {vis[tot - j + 1] = true; break;}
	}
	for (int i = 1; i <= tot; i++) if (vis[i])
		for (int j = i + 1; j <= tot; j++) if (cur[j] % cur[i] == 0) vis[j] = 1;
	for (int i = 1; i <= tot; i++) {
		phi[i] = cur[i];
		for (int j = 1; j < i; j++) if (cur[i] % cur[j] == 0) phi[i] -= phi[j];
		if (vis[tot - i + 1]) ans += phi[i];
	}
	printf("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
#include <cctype>
#include <cassert>
#include <ctime>
#include <vector>

#define REP(i, a, b) for (int i = (a), _end_ = (b); i != _end_; ++i)
#define FOR(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

using namespace std;

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 1e4, max_num = 1e5;

int fpm(LL b, int e, const int &m)
{
	LL t = 1;
	for ( ; e; e >>= 1, (b *= b) %= m) if (e & 1) (t *= b) %= m;
	return t;
}

int gcd(int x, int y)
{
	while (y) y ^= x ^= y ^= x %= y;
	return x;
}

int n, m, p;
int a[maxn + 5];

int ans = 0;

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	scanf("%d%d%d", &n, &m, &p);
	vector<int> all;
	for (int i = 1; i * i <= p - 1; ++i)
		if (!((p - 1) % i))
		{
			all.pb(i);
			if (i * i != p - 1) all.pb((p - 1) / i);
		}
	sort(ALL(all));
	REP(i, 0, n)
		scanf("%d", a + i);
	int yyt = p - 1;
	REP(i, 0, m)
	{
		static int x;
		scanf("%d", &x);
		yyt = gcd(yyt, x);
	}
	REP(i, 0, n)
		REP(j, 0, SZ(all))
			if (fpm(a[i], (LL)all[j] * yyt % (p - 1), p) == 1)
			{
				a[i] = (p - 1) / all[j];
				break;
			}
	static int dp[max_num + 5];
	reverse(ALL(all));
	REP(i, 0, SZ(all))
	{
		bool flag = 0;
		REP(j, 0, n) if (!(all[i] % a[j])) { flag = 1; break; }
		if (!flag) continue;
		dp[i] = (p - 1) / all[i];
		REP(j, 0, i)
			if (!(all[j] % all[i])) dp[i] -= dp[j];
		ans += dp[i];
	}
	printf("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
#include <cctype>
#include <cassert>
#include <ctime>
#include <vector>

#define REP(i, a, b) for (int i = (a), _end_ = (b); i != _end_; ++i)
#define FOR(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

using namespace std;

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 1e4, max_num = 1e5;

int fpm(LL b, LL e, const int &m)
{
	LL t = 1;
	for ( ; e; e >>= 1, (b *= b) %= m) if (e & 1) (t *= b) %= m;
	return t;
}

int gcd(int x, int y)
{
	while (y) y ^= x ^= y ^= x %= y;
	return x;
}

int n, m, p;
int a[maxn + 5];

int ans = 0;

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	scanf("%d%d%d", &n, &m, &p);
	vector<int> all;
	for (int i = 1; i * i <= p - 1; ++i)
		if (!((p - 1) % i))
		{
			all.pb(i);
			if (i * i != p - 1) all.pb((p - 1) / i);
		}
	sort(ALL(all));
	REP(i, 0, n)
		scanf("%d", a + i);
	int yyt = p - 1;
	REP(i, 0, n)
	{
		static int x;
		scanf("%d", &x);
		yyt = gcd(yyt, x);
	}
	REP(i, 0, n)
		REP(j, 0, SZ(all))
			if (fpm(a[i], (LL)all[j] * yyt, p) == 1)
			{
				a[i] = (p - 1) / all[j];
				break;
			}
	sort(a, a + n), n = unique(a, a + n) - a, reverse(a, a + n);
	static int dp[max_num + 5];
	REP(i, 0, n)
	{
		dp[i] = (p - 1) / a[i];
		REP(j, 0, i)
			if (!(a[j] % a[i])) dp[i] -= dp[j];
		ans += dp[i];
	}
	printf("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
#include <cctype>
#include <cassert>
#include <ctime>
#include <vector>

#define REP(i, a, b) for (int i = (a), _end_ = (b); i != _end_; ++i)
#define FOR(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

using namespace std;

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 1e4, max_num = 1e5;

int fpm(LL b, int e, const int &m)
{
	LL t = 1;
	for ( ; e; e >>= 1, (b *= b) %= m) if (e & 1) (t *= b) %= m;
	return t;
}

int gcd(int x, int y)
{
	while (y) y ^= x ^= y ^= x %= y;
	return x;
}

int n, m, p;
int a[maxn + 5];

int ans = 0;

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	scanf("%d%d%d", &n, &m, &p);
	vector<int> all;
	for (int i = 1; i * i <= p - 1; ++i)
		if (!((p - 1) % i))
		{
			all.pb(i);
			if (i * i != p - 1) all.pb((p - 1) / i);
		}
	sort(ALL(all));
	REP(i, 0, n)
	{
		scanf("%d", a + i);
		REP(i, 0, SZ(all))
			if (fpm(a[i], all[i], p) == 1)
			{
				a[i] = (p - 1) / all[i];
				break;
			}
	}
	int yyt = 0;
	REP(i, 0, n)
	{
		static int x;
		scanf("%d", &x);
		yyt = gcd(yyt, x);
	}
	yyt = gcd(yyt, p - 1);
	REP(i, 0, n)
		a[i] = gcd((LL)a[i] * yyt % (p - 1), p - 1);
	sort(a, a + n), n = unique(a, a + n) - a, reverse(a, a + n);
	static int dp[max_num + 5];
	REP(i, 0, n)
	{
		dp[i] = (p - 1) / a[i];
		REP(j, 0, i)
			if (!(a[j] % a[i])) dp[i] -= dp[j];
		ans += dp[i];
	}
	printf("%d\n", ans);
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
#include <cctype>
#include <cassert>
#include <ctime>
#include <vector>

#define REP(i, a, b) for (int i = (a), _end_ = (b); i != _end_; ++i)
#define FOR(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

using namespace std;

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 1e4, max_num = 1e5;

int fpm(LL b, LL e, const int &m)
{
	LL t = 1;
	for ( ; e; e >>= 1, (b *= b) %= m) if (e & 1) (t *= b) %= m;
	return t;
}

int gcd(int x, int y)
{
	while (y) y ^= x ^= y ^= x %= y;
	return x;
}

int n, m, p;
int a[maxn + 5];

int ans = 0;

int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	scanf("%d%d%d", &n, &m, &p);
	vector<int> all;
	for (int i = 1; i * i <= p - 1; ++i)
		if (!((p - 1) % i))
		{
			all.pb(i);
			if (i * i != p - 1) all.pb((p - 1) / i);
		}
	sort(ALL(all));
	REP(i, 0, n)
		scanf("%d", a + i);
	int yyt = p - 1;
	REP(i, 0, m)
	{
		static int x;
		scanf("%d", &x);
		yyt = gcd(yyt, x);
	}
	REP(i, 0, n)
		REP(j, 0, SZ(all))
			if (fpm(a[i], (LL)all[j] * yyt, p) == 1)
			{
				a[i] = (p - 1) / all[j];
				break;
			}
	sort(a, a + n), n = unique(a, a + n) - a, reverse(a, a + n);
	static int dp[max_num + 5];
	REP(i, 0, n)
	{
		dp[i] = (p - 1) / a[i];
		REP(j, 0, i)
			if (!(a[j] % a[i])) dp[i] -= dp[j];
		ans += dp[i];
	}
	printf("%d\n", ans);
	return 0;
}


#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
#define MP(a, b) make_pair(a, b)
#define FOREACH(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)

const int maxn = 10000 + 50, maxm = 100000 + 50;
int n, m, p, a[maxn], b[maxm];

const int MAX_P = 33000;
int minp[MAX_P], prime[10000], pnum;
void initPrimes() {
    pnum = 0;
    minp[1] = 0;
    for (int i = 2; i <= MAX_P; i++)
        minp[i] = i;
    for (LL i = 2; i <= MAX_P; i++)
    if (minp[i] == i) {
        prime[pnum++] = i;
        for (LL j = i * i; j <= MAX_P; j += i)
        if (minp[j] == j)
            minp[j] = i;
    }
}

void decompose(int n, int *factor, int *exp, int &fnum) {
    fnum = 0;
    for (int i = 0; (LL) prime[i] * prime[i] <= n; i++)
    if (n % prime[i] == 0) {
        factor[fnum] = prime[i];
        exp[fnum] = 0;
        while (n % prime[i] == 0) {
            n /= prime[i];
            exp[fnum]++;
        }
        fnum++;
    }
    if (n > 1) {
        factor[fnum] = n;
        exp[fnum++] = 1;
    }
}

int fastpow(LL a, LL p, int m) {
    LL ret = 1;
    while (p) {
        if (p & 1) ret = ret * a % m;
        if (p >>= 1) a = a * a % m;
    }
    return (int) ret;
}

LL gcd(LL a, LL b) {
    return b ? gcd(b, a % b) : a;
}

LL lcm(LL a, LL b) {
    return a / gcd(a, b) * b;
}

int getOrder(int a, int p) {
    static int pFactor[100], pExp[100], pFnum;
    decompose(p - 1, pFactor, pExp, pFnum);
    int cur = p - 1;
    for (int i = 0; i < pFnum; i++) {
        for (int j = 0; j < pExp[i]; j++) {
            if (fastpow(a, cur / pFactor[i], p) == 1)
                cur /= pFactor[i];
        }
    }
    return cur;
}

map<LL, LL> dp[2];
int main() {
    initPrimes();
    scanf("%d %d %d", &n, &m, &p);
    for (int i = 1; i <= n; i++)
        scanf("%d", a + i);
    for (int j = 1; j <= m; j++)
        scanf("%d", b + j);

    int B = p - 1;
    for (int j = 1; j <= m; j++)
        B = gcd(B, b[j]);

    for (int i = 1; i <= n; i++) {
        int order = getOrder(a[i], p);
        a[i] = gcd((LL) (p - 1) / order * B, p - 1);
        // !!
        if (a[i] == 0) a[i] = p - 1;
    }

    int pre = 0, cur = 1;
    dp[cur].clear();
    for (int i = 1; i <= n; i++) {
        swap(pre, cur);
        dp[cur].clear();
        dp[cur][a[i]] = 1;
        FOREACH(e, dp[pre]) {
            //printf("%d %lld\n", e->first, e->second);
            dp[cur][e->first] += e->second;
            dp[cur][lcm(e->first, a[i])] -= e->second;
        }
        //puts("----------");
    }

    LL res = 0;
    FOREACH(e, dp[cur]) {
        //printf("%d %lld\n", e->first, e->second);
        LL add = (p - 1) / e->first;
        res += add * (e->second);
    }

    printf("%d\n", (int) res);

    return 0;
}


#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
#define MP(a, b) make_pair(a, b)
#define FOREACH(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)

const int maxn = 10000 + 50, maxm = 100000 + 50;
int n, m, p, a[maxn], b[maxm];

const int MAX_P = 33000;
int minp[MAX_P], prime[10000], pnum;
void initPrimes() {
    pnum = 0;
    minp[1] = 0;
    for (int i = 2; i <= MAX_P; i++)
        minp[i] = i;
    for (LL i = 2; i <= MAX_P; i++)
    if (minp[i] == i) {
        prime[pnum++] = i;
        for (LL j = i * i; j <= MAX_P; j += i)
        if (minp[j] == j)
            minp[j] = i;
    }
}

void decompose(int n, int *factor, int *exp, int &fnum) {
    fnum = 0;
    for (int i = 0; (LL) prime[i] * prime[i] <= n; i++)
    if (n % prime[i] == 0) {
        factor[fnum] = prime[i];
        exp[fnum] = 0;
        while (n % prime[i] == 0) {
            n /= prime[i];
            exp[fnum]++;
        }
        fnum++;
    }
    if (n > 1) {
        factor[fnum] = n;
        exp[fnum++] = 1;
    }
}

int fastpow(LL a, LL p, int m) {
    LL ret = 1;
    while (p) {
        if (p & 1) ret = ret * a % m;
        if (p >>= 1) a = a * a % m;
    }
    return (int) ret;
}

int gcd(int a, int b) {
    return b ? gcd(b, a % b) : a;
}

int lcm(int a, int b) {
    return a / gcd(a, b) * b;
}

int getOrder(int a, int p) {
    static int pFactor[100], pExp[100], pFnum;
    decompose(p - 1, pFactor, pExp, pFnum);
    int cur = p - 1;
    for (int i = 0; i < pFnum; i++) {
        for (int j = 0; j < pExp[i]; j++) {
            if (fastpow(a, cur / pFactor[i], p) == 1)
                cur /= pFactor[i];
        }
    }
    return cur;
}

map<int, LL> dp[2];
int main() {
    initPrimes();
    scanf("%d %d %d", &n, &m, &p);
    for (int i = 1; i <= n; i++)
        scanf("%d", a + i);
    for (int j = 1; j <= m; j++)
        scanf("%d", b + j);

    int B = p - 1;
    for (int j = 1; j <= m; j++)
        B = gcd(B, b[j]);

    for (int i = 1; i <= n; i++) {
        int order = getOrder(a[i], p);
        a[i] = gcd((p - 1) / order * B, p - 1);
        // !!
        if (a[i] == 0) a[i] = p - 1;
    }

    int pre = 0, cur = 1;
    dp[cur].clear();
    for (int i = 1; i <= n; i++) {
        swap(pre, cur);
        dp[cur].clear();
        dp[cur][a[i]] = 1;
        FOREACH(e, dp[pre]) {
            //printf("%d %lld\n", e->first, e->second);
            dp[cur][e->first] += e->second;
            dp[cur][lcm(e->first, a[i])] -= e->second;
        }
        //puts("----------");
    }

    LL res = 0;
    FOREACH(e, dp[cur]) {
        //printf("%d %lld\n", e->first, e->second);
        LL add = (p - 1 / e->first);
        res += add * (e->second);
    }

    printf("%d\n", (int) res);

    return 0;
}


#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
#define MP(a, b) make_pair(a, b)
#define FOREACH(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)

const int maxn = 10000 + 50, maxm = 100000 + 50;
int n, m, p, a[maxn], b[maxm];

const int MAX_P = 33000;
int minp[MAX_P], prime[10000], pnum;
void initPrimes() {
    pnum = 0;
    minp[1] = 0;
    for (int i = 2; i <= MAX_P; i++)
        minp[i] = i;
    for (LL i = 2; i <= MAX_P; i++)
    if (minp[i] == i) {
        prime[pnum++] = i;
        for (LL j = i * i; j <= MAX_P; j += i)
        if (minp[j] == j)
            minp[j] = i;
    }
}

void decompose(int n, int *factor, int *exp, int &fnum) {
    fnum = 0;
    for (int i = 0; (LL) prime[i] * prime[i] <= n; i++)
    if (n % prime[i] == 0) {
        factor[fnum] = prime[i];
        exp[fnum] = 0;
        while (n % prime[i] == 0) {
            n /= prime[i];
            exp[fnum]++;
        }
        fnum++;
    }
    if (n > 1) {
        factor[fnum] = n;
        exp[fnum++] = 1;
    }
}

int fastpow(LL a, LL p, int m) {
    LL ret = 1;
    while (p) {
        if (p & 1) ret = ret * a % m;
        if (p >>= 1) a = a * a % m;
    }
    return (int) ret;
}

int gcd(int a, int b) {
    return b ? gcd(b, a % b) : a;
}

int lcm(int a, int b) {
    return a / gcd(a, b) * b;
}

int getOrder(int a, int p) {
    static int pFactor[100], pExp[100], pFnum;
    decompose(p - 1, pFactor, pExp, pFnum);
    int cur = p - 1;
    for (int i = 0; i < pFnum; i++) {
        for (int j = 0; j < pExp[i]; j++) {
            if (fastpow(a, cur / pFactor[i], p) == 1)
                cur /= pFactor[i];
        }
    }
    return cur;
}

map<int, LL> dp[2];
int main() {
    initPrimes();
    scanf("%d %d %d", &n, &m, &p);
    for (int i = 1; i <= n; i++)
        scanf("%d", a + i);
    for (int j = 1; j <= m; j++)
        scanf("%d", b + j);

    int B = p - 1;
    for (int j = 1; j <= m; j++)
        B = gcd(B, b[j]);

    for (int i = 1; i <= n; i++) {
        int order = getOrder(a[i], p);
        a[i] = gcd((p - 1) / order * B, p - 1);
        // !!
        if (a[i] == 0) a[i] = p - 1;
    }

    int pre = 0, cur = 1;
    dp[cur].clear();
    for (int i = 1; i <= n; i++) {
        swap(pre, cur);
        dp[cur].clear();
        dp[cur][a[i]] = 1;
        FOREACH(e, dp[pre]) {
            //printf("%d %lld\n", e->first, e->second);
            dp[cur][e->first] += e->second;
            dp[cur][lcm(e->first, a[i])] -= e->second;
        }
        //puts("----------");
    }

    LL res = 0;
    FOREACH(e, dp[cur]) {
        //printf("%d %lld\n", e->first, e->second);
        LL add = (p - 1) / e->first;
        res += add * (e->second);
    }

    printf("%d\n", (int) res);

    return 0;
}


#include <bits/stdc++.h>
#define int long long
using namespace std;

int n, m, p, tmp, k = 0, A[10010], I[10010], S[10010], B[10010], V[10010], t = 0, x;

int powmod(int x, int y, int p)
{
	int ans = 1;
	while(y) {if(y & 1) ans = ans * x % p; x = x * x % p, y >>= 1;}
	return ans;
}

int gcd(int x, int y) {return !x ? y : gcd(y % x, x);}

#undef int
int main()
#define int long long
{
	scanf("%lld%lld%lld", &n, &m, &p);
	for(int i = 1; i <= n; i++) scanf("%lld", &A[i]);
	for(int i = 1; i <= m; i++) scanf("%lld", &x), k = gcd(k, x);
	k = gcd(k, p - 1);
	for(int i = 1; i * i <= p - 1; i++) if((p - 1) % i == 0) S[++t] = i, S[++t] = (p - 1) / i;
	sort(S + 1, S + t + 1);
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= t; j++)
			if(powmod(A[i], S[j], p) == 1) {
				if(j == t) return printf("%lld\n", (p - 1) / k), 0;
				I[i] = gcd((p - 1) / S[j] * k, p - 1);
				break;
			}
	sort(I + 1, I + n + 1);
	int o = unique(I + 1, I + n + 1) - I - 1, ans = 0;
	for(int i = 1; i <= o; i++)
		for(int j = 1; j <= t; j++)
			if(S[j] % I[i] == 0) B[j] = 1;
	for(int i = t; i >= 1; i--) {
		V[i] = (p - 1) / S[i];
		for(int j = t; j > i; j--)
			if(S[j] % S[i] == 0) V[i] -= V[j];
		if(B[i]) ans += V[i];
	}
	return printf("%lld\n", ans), 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
int n,m,tx=0;
LL p,a[100001],d[100001],f[2000][2000];
bool v[100001];
LL gcd(LL x,LL y) {
    if (y==0) return x;
    return gcd(y,x%y);
}
LL lcm(LL x,LL y) {
    return x*y/gcd(x,y);
}
LL mul(LL x,LL y) {
    if (y==0) return 1;
    LL now=mul(x,y/2);
    now=now*now%p;
    if (y%2) return now*x%p;
    return now;
}
bool check(LL x) {
    for (int i=1;i<=tx;i++) if (mul(x,d[i])==1) return 0;
    return 1;
}
LL getans(LL x) {
    LL ans=1e15;
    for (int i=1;i<=tx;i++) if (mul(x,d[i])==1) ans=min(ans,d[i]);
    return (p-1)/ans;
}
int find(LL x) {
    int l=1,r=tx;
    while (l<=r) {
        int mid=(l+r)/2;
        if (d[mid]==x) return mid;
        if (d[mid]<x) l=mid+1;
        else r=mid-1;
    }
}
int main() {
    scanf("%d%d%lld",&n,&m,&p);
    int kx=sqrt(p);
    for (int i=1;i<=kx;i++)
        if ((p-1)%i==0) {
            d[++tx]=i;
            if (i*i==p-1) continue;
            d[++tx]=(p-1)/i;
        }
    sort(d+1,d+tx+1);
    for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
    int g=p-1;
    for (int i=1;i<=m;i++) {
        int x;
        scanf("%d",&x);
        g=gcd(g,x);
    }
    for (int i=1;i<=n;i++) a[i]=mul(a[i],g);
    for (int i=1;i<=n;i++) a[i]=getans(a[i]);
    for (int i=1;i<=n;i++) v[find(a[i])]=1;
    for (int i=1;i<=tx;i++) {
        for (int j=1;j<=tx;j++) f[i][j]=f[i-1][j];
        if (!v[i]) continue;
        f[i][i]++;
        for (int j=1;j<=tx;j++) {
            LL now=lcm(d[i],d[j]);
            int k=find(now);
            f[i][k]-=f[i-1][j];
        }
    }
    LL ans=0;
    for (int i=1;i<=tx;i++) ans+=(p-1)/d[i]*f[tx][i];
    printf("%lld\n",ans);
    return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>

#include<iostream>
#include<algorithm>
using namespace std;

const int _N=10010;

int n,m,p,s[_N],d[_N],f[_N];

inline int power(long long d,long long t)
{
    static long long re;
    re=1;
    while(t)
    {
        if(t&1)
            re=re*d%p;
        d=d*d%p,t>>=1;
    }
    return re;
}

int main()
{
    static int T;
    T=1;
    for(int Case=1;Case<=T;Case++)
    {
        static int b;
        scanf("%d%d%d",&n,&m,&p),b=p-1,f[0]=d[0]=0;
        for(int i=1;i<=n;i++)
            scanf("%d",s+i);
        for(int i=m;i;i--)
            scanf("%d",&m),b=__gcd(b,m);
        for(int i=1;i*i<p;i++)
            if((p-1)%i==0)
            {
                d[++d[0]]=i;
                if(i*i!=p-1)
                    d[++d[0]]=(p-1)/i;
            }
        sort(d+1,d+d[0]+1);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=d[0];j++)
                if(power(s[i],(long long)b*d[j])==1)
                {
                    s[i]=(p-1)/d[j];
                    break;
                }
        sort(s+1,s+n+1),m=unique(s+1,s+n+1)-s-1;
        for(int i=m;i;i--)
        {
            f[i]=(p-1)/s[i];
            for(int j=m;j>i;j--)
                if(s[j]%s[i]==0)
                    f[i]-=f[j];
            f[0]+=f[i];
        }
        printf("%d\n",f[0]);
    }
    return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>

#include<iostream>
#include<algorithm>
using namespace std;

const int _N=10010;

int n,m,p,s[_N],d[_N],f[_N];

inline int power(long long d,long long t)
{
    static long long re;
    re=1;
    while(t)
    {
        if(t&1)
            re=re*d%p;
        d=d*d%p,t>>=1;
    }
    return re;
}

int main()
{
    static int T;
    T=1;
    for(int Case=1;Case<=T;Case++)
    {
        static int b;
        scanf("%d%d%d",&n,&m,&p),b=p-1,f[0]=d[0]=0;
        for(int i=1;i<=n;i++)
            scanf("%d",s+i);
        for(int i=m;i;i--)
            scanf("%d",&m),b=__gcd(b,m);
        for(int i=1;i*i<p;i++)
            if((p-1)%i==0)
            {
                d[++d[0]]=i;
                if(i*i!=p-1)
                    d[++d[0]]=(p-1)/i;
            }
        sort(d+1,d+d[0]+1);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=d[0];j++)
                if(power(s[i],(long long)b*d[j])==1)
                {
                    s[i]=d[j];
                    break;
                }
        sort(s+1,s+n+1),m=unique(s+1,s+n+1)-s-1;
        for(int i=1;i<=m;i++)
        {
            f[i]=s[i];
            for(int j=1;j<i;j++)
                if(s[i]%s[j]==0)
                    f[i]-=f[j];
            f[0]+=f[i];
        }
        printf("%d\n",f[0]);
    }
    return 0;
}


/* Team: moscow04 */

#include <iostream>
#include <iomanip>
#include <sstream>
#include <ext/hash_map>

#include <vector>
#include <deque>
#include <queue>
#include <string>
#include <set>
#include <map>

#include <algorithm>
#include <functional>
#include <numeric>
#include <limits>
#include <iterator>

#include <complex>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <climits>
#include <cassert>

using namespace std;

#define DEBUG

#define all(a) (a).begin(), (a).end()
#define sz(a) ((int)((a).size()))
#define pb push_back
#define MP make_pair
#define mp MP

#ifdef DEBUG
    #define debug(x) cerr << #x << ": " << (x) << endl;
#else
    #define debug(x) ;
#endif

typedef pair<int, int> pii;
typedef long long ll;

template <typename T> T sqr (T x) {return x * x;}
template <typename T> T abs (T x) {return x > 0 ? x : -x;}

template <typename T>
ostream & operator << (ostream & out, vector<T> const & a) {
    out << "[";
    for (int i = 0; i < sz(a); ++i) {
        if (i != 0) {
            out << ", ";
        }
        out << a[i];
    }
    out << "]";
    return out;
}

template <typename T1, typename T2>
ostream & operator << (ostream & out, pair<T1, T2> const & p) {
    out << "(" << p.first << ", " << p.second << ")";
    return out;
}

void showTime () {
#ifdef DEBUG
    static double prev;
    static bool first = true;

    double curr = (double)clock() / CLOCKS_PER_SEC;

    cerr.setf(ios::fixed);
    cerr.precision(3);
    cerr << "<";
    if (!first) {
        cerr << curr - prev << "sec, ";
    }
    cerr << curr << "sec>\n";

    first = false;
    prev = curr;
#endif
}

int n, m, p;
const int N = 1e4 + 10;
const int M = 1e5 + 10;
int a[N], b[M];

const int L = 10;
const int K = 30;

ll g;

ll gcd (ll a, ll b) {
    if (!b) {
        return a;
    }

    return gcd(b, a % b);
}

vector<int> factors;

int mPow (int x, int n) {
    ll r = 1, c = x;
    while (n > 0) {
        if (n % 2 == 1) {
            r = (r * c) % p;
        }
        c = (c * c) % p;
        n /= 2;
    }

    return r;
}

bool check (int x) {
    for (int i = 0; i < (int)factors.size(); ++i) {
        if (mPow(x, factors[i]) == 1) {
            return false;
        }
    }

    return true;
}

void factor (int x) {
    int y = x;
    for (int i = 2; i * i <= y; ++i) {
        if (x % i == 0) {
            factors.push_back(i);
            x /= i;
            while (x % i == 0) {
                x /= i;
            }
        }

    }

    if (x != 1) {
        factors.push_back(x);
    }
}

int findPrimitiveRoot () {
    for (int i = 1; ; ++i) {
        if (check(i)) {
            return i;
        }
    }
}

typedef __gnu_cxx::hash_map<int, int> Map;
Map c;

void precalc () {
    factor(p - 1);

    g = findPrimitiveRoot();

    ll q = mPow(g, (1 << L)), e = 1;
    for (int i = 0; i < (1 << (K - L)); ++i) {
        c[e] = i;

        e = (e * q) % p;
    }
}

inline int exists (int x) {
    Map::iterator it = c.find(x);
    if (it == c.end()) {
        return -1;
    }
    else {
        return it->second;
    }
}

ll f (ll x) {
    int g1 = mPow(g, p - 2);

    for (int i = 0; i < (1 << L); ++i) {
        int e = exists(x);
        if (e != -1) {
            return e * (1 << (K - L)) + i;
        }
        x = (x * g1) % p;
    }
}

void read () {
    cin >> n >> m >> p;
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    for (int i = 0; i < m; ++i) {
        cin >> b[i];
    }
}

void gen () {
    n = 1e4, m = 1e5;
    p = 1e9 + 7;
    for (int i = 0; i < n; ++i) {
        a[i] = rand() % (p - 1) + 1;
    }

    for (int i = 0; i < m; ++i) {
        b[i] = rand() % (int)1e9 + 1;
    }
}

int main () {
//    gen();
    read();

    precalc();
    ll e1 = 0;
//    showTime();
    for (int i = 0; i < n; ++i) {
        e1 = gcd(e1, f(a[i]));
    }
//    showTime();

    ll e2 = 0;
    for (int j = 0; j < m; ++j) {
        e2 = gcd(b[j], e2);
    }
    ll e = gcd(p - 1, e1 * e2);

    cout << (p - 1) / e << "\n";
//    showTime();
    return 0;
}


/* Team: moscow04 */

#include <iostream>
#include <iomanip>
#include <sstream>
#include <ext/hash_map>

#include <vector>
#include <deque>
#include <queue>
#include <string>
#include <set>
#include <map>

#include <algorithm>
#include <functional>
#include <numeric>
#include <limits>
#include <iterator>

#include <complex>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <climits>
#include <cassert>

using namespace std;

#define DEBUG

#define all(a) (a).begin(), (a).end()
#define sz(a) ((int)((a).size()))
#define pb push_back
#define MP make_pair
#define mp MP

#ifdef DEBUG
    #define debug(x) cerr << #x << ": " << (x) << endl;
#else
    #define debug(x) ;
#endif

typedef pair<int, int> pii;
typedef long long ll;

template <typename T> T sqr (T x) {return x * x;}
template <typename T> T abs (T x) {return x > 0 ? x : -x;}

template <typename T>
ostream & operator << (ostream & out, vector<T> const & a) {
    out << "[";
    for (int i = 0; i < sz(a); ++i) {
        if (i != 0) {
            out << ", ";
        }
        out << a[i];
    }
    out << "]";
    return out;
}

template <typename T1, typename T2>
ostream & operator << (ostream & out, pair<T1, T2> const & p) {
    out << "(" << p.first << ", " << p.second << ")";
    return out;
}

void showTime () {
#ifdef DEBUG
    static double prev;
    static bool first = true;

    double curr = (double)clock() / CLOCKS_PER_SEC;

    cerr.setf(ios::fixed);
    cerr.precision(3);
    cerr << "<";
    if (!first) {
        cerr << curr - prev << "sec, ";
    }
    cerr << curr << "sec>\n";

    first = false;
    prev = curr;
#endif
}

int n, m, p;
const int N = 1e4 + 10;
const int M = 1e5 + 10;
int a[N], b[M];

const int L = 9;
const int K = 30;

ll g;

ll gcd (ll a, ll b) {
    if (!b) {
        return a;
    }

    return gcd(b, a % b);
}

vector<int> factors;

int mPow (int x, int n) {
    ll r = 1, c = x;
    while (n > 0) {
        if (n % 2 == 1) {
            r = (r * c) % p;
        }
        c = (c * c) % p;
        n /= 2;
    }

    return r;
}

bool check (int x) {
    for (int i = 0; i < (int)factors.size(); ++i) {
        if (mPow(x, (p - 1) / factors[i]) == 1) {
            return false;
        }
    }

    return true;
}

void factor (int x) {
    int y = x;
    for (int i = 2; i * i <= y; ++i) {
        if (x % i == 0) {
            factors.push_back(i);
            x /= i;
            while (x % i == 0) {
                x /= i;
            }
        }

    }

    if (x != 1) {
        factors.push_back(x);
    }
}

int findPrimitiveRoot () {
    for (int i = 1; ; ++i) {
        if (check(i)) {
            return i;
        }
    }
}

typedef __gnu_cxx::hash_map<int, int> Map;
Map c;

void precalc () {
    factor(p - 1);

    g = findPrimitiveRoot();

    ll q = mPow(g, (1 << L)), e = 1;
    for (ll i = 0; (i << L) < p + (1 << L); ++i) {
        c[e] = i;

        e = (e * q) % p;
    }
}

inline int exists (int x) {
    Map::iterator it = c.find(x);
    if (it == c.end()) {
        return -1;
    }
    else {
        return it->second;
    }
}

ll f (ll x) {
    int g1 = mPow(g, p - 2);

    for (int i = 0; i < (1 << L); ++i) {
        ll e = exists(x);
        if (e != -1) {
            return e * (1 << L) + i;
        }
        x = (x * g1) % p;
    }
}

void read () {
    cin >> n >> m >> p;
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    for (int i = 0; i < m; ++i) {
        cin >> b[i];
    }
}

void gen () {
    n = 1e4, m = 1e5;
    p = 1e9 + 7;
    for (int i = 0; i < n; ++i) {
        a[i] = rand() % (p - 1) + 1;
    }

    for (int i = 0; i < m; ++i) {
        b[i] = rand() % (int)1e9 + 1;
    }
}

const int DC = 1e4;
int dp[2][DC][2];

void add (int & x, int y) {
    x += y;
    if (x >= p - 1) {
        x -= (p - 1);
    }
}

int sub (int x, int y) {
    return (x - y + (p - 1)) % (p - 1);
}

int cnt (vector<int> a, int n) {
    vector<int> divisors;
    for (int i = 1; i * i <= n; ++i) {
        if (n % i == 0) {
            divisors.push_back(i);
            if (i * i != n) {
                divisors.push_back(n / i);
            }
        }
    }

    sort(all(divisors));
//   debug(divisors);
//   debug(a);

    int k = divisors.size();
    __gnu_cxx::hash_map<int, int> num;
    for (int i = 0; i < k; ++i) {
        num[divisors[i]] = i;
    }
    memset(dp[0], 0, sizeof(dp[0]));

    for (int i = 0; i < (int)a.size(); ++i) {
        for (int j = 0; j < k; ++j) {
            dp[1][j][0] = dp[1][j][1] = 0;
        }
        dp[1][num[a[i]]][0] = 1;

        for (int j = 0; j < k; ++j) {
            int e = num[divisors[j] * (a[i] / gcd(a[i], divisors[j]))];
            add(dp[1][e][0], dp[0][j][1]);
            add(dp[1][e][1], dp[0][j][0]);
        }

        for (int j = 0; j < k; ++j) {
            add(dp[0][j][0], dp[1][j][0]);
            add(dp[0][j][1], dp[1][j][1]);
        }
    }

    ll res = 0;
    // debug(divisors);
    for (int i = 0; i < k; ++i) {
        // cerr << i << " " << dp[0][i][0] << " " << dp[0][i][1] << "\n";
        res += ((sub(dp[0][i][0], dp[0][i][1])) * ((ll)(p - 1) / divisors[i])) % (p - 1);
    }

    res %= p - 1;

    return res == 0 ? (p - 1) : res;
}

int main () {
//    gen();
    read();

    precalc();

    ll q = 0;
    for (int j = 0; j < m; ++j) {
        q = gcd(b[j], q);
    }
    q = gcd(q, p - 1);

//    debug(q);
    vector<int> t(n);
    for (int i = 0; i < n; ++i) {
//        debug(a[i]);
        ll w = f(a[i]);
//        debug(w);
        t[i] = gcd(q * w, p - 1);
    }

    cout << cnt(t, p - 1) << "\n";

//    showTime();
    /*
    e1 %= (p - 1);
    e2 %= (p - 1);
    ll e = gcd(p - 1, e1 * e2);

    cout << (p - 1) / e << "\n";
    */
//    showTime();
    return 0;
}


/* Team: moscow04 */

#include <iostream>
#include <iomanip>
#include <sstream>
#include <ext/hash_map>

#include <vector>
#include <deque>
#include <queue>
#include <string>
#include <set>
#include <map>

#include <algorithm>
#include <functional>
#include <numeric>
#include <limits>
#include <iterator>

#include <complex>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <climits>
#include <cassert>

using namespace std;

#define DEBUG

#define all(a) (a).begin(), (a).end()
#define sz(a) ((int)((a).size()))
#define pb push_back
#define MP make_pair
#define mp MP

#ifdef DEBUG
    #define debug(x) cerr << #x << ": " << (x) << endl;
#else
    #define debug(x) ;
#endif

typedef pair<int, int> pii;
typedef long long ll;

template <typename T> T sqr (T x) {return x * x;}
template <typename T> T abs (T x) {return x > 0 ? x : -x;}

template <typename T>
ostream & operator << (ostream & out, vector<T> const & a) {
    out << "[";
    for (int i = 0; i < sz(a); ++i) {
        if (i != 0) {
            out << ", ";
        }
        out << a[i];
    }
    out << "]";
    return out;
}

template <typename T1, typename T2>
ostream & operator << (ostream & out, pair<T1, T2> const & p) {
    out << "(" << p.first << ", " << p.second << ")";
    return out;
}

void showTime () {
#ifdef DEBUG
    static double prev;
    static bool first = true;

    double curr = (double)clock() / CLOCKS_PER_SEC;

    cerr.setf(ios::fixed);
    cerr.precision(3);
    cerr << "<";
    if (!first) {
        cerr << curr - prev << "sec, ";
    }
    cerr << curr << "sec>\n";

    first = false;
    prev = curr;
#endif
}

int n, m, p;
const int N = 1e4 + 10;
const int M = 1e5 + 10;
int a[N], b[M];

const int L = 10;
const int K = 30;

ll g;

ll gcd (ll a, ll b) {
    if (!b) {
        return a;
    }

    return gcd(b, a % b);
}

vector<int> factors;

int mPow (int x, int n) {
    ll r = 1, c = x;
    while (n > 0) {
        if (n % 2 == 1) {
            r = (r * c) % p;
        }
        c = (c * c) % p;
        n /= 2;
    }

    return r;
}

bool check (int x) {
    for (int i = 0; i < (int)factors.size(); ++i) {
        if (mPow(x, factors[i]) == 1) {
            return false;
        }
    }

    return true;
}

void factor (int x) {
    int y = x;
    for (int i = 2; i * i <= y; ++i) {
        if (x % i == 0) {
            factors.push_back(i);
            x /= i;
            while (x % i == 0) {
                x /= i;
            }
        }

    }

    if (x != 1) {
        factors.push_back(x);
    }
}

int findPrimitiveRoot () {
    for (int i = 1; ; ++i) {
        if (check(i)) {
            return i;
        }
    }
}

typedef __gnu_cxx::hash_map<int, int> Map;
Map c;

void precalc () {
    factor(p - 1);

    g = findPrimitiveRoot();

    ll q = mPow(g, K), e = 1;
    for (int i = 0; i < (1 << (K - L)); ++i) {
        c[e] = i;

        e = (e * q) % p;
    }
}

inline int exists (int x) {
    Map::iterator it = c.find(x);
    if (it == c.end()) {
        return -1;
    }
    else {
        return it->second;
    }
}

ll f (ll x) {
    int g1 = mPow(g, p - 2);

    for (int i = 0; i < (1 << L); ++i) {
        int e = exists(x);
        if (e != -1) {
            return e * (1 << (K - L)) + i;
        }
        x = (x * g1) % p;
    }
}

void read () {
    cin >> n >> m >> p;
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    for (int i = 0; i < m; ++i) {
        cin >> b[i];
    }
}

void gen () {
    n = 1e4, m = 1e5;
    p = 1e9 + 7;
    for (int i = 0; i < n; ++i) {
        a[i] = rand() % (p - 1) + 1;
    }

    for (int i = 0; i < m; ++i) {
        b[i] = rand() % (int)1e9 + 1;
    }
}

int main () {
//    gen();
    read();

    precalc();
    ll e1 = 0;
//    showTime();
    for (int i = 0; i < n; ++i) {
        e1 = gcd(e1, f(a[i]));
    }
//    showTime();

    ll e2 = 0;
    for (int j = 0; j < m; ++j) {
        e2 = gcd(b[j], e2);
    }
    ll e = gcd(p - 1, e1 * e2);

    cout << (p - 1) / e << "\n";
//    showTime();
    return 0;
}


/* Team: moscow04 */

#include <iostream>
#include <iomanip>
#include <sstream>
#include <ext/hash_map>

#include <vector>
#include <deque>
#include <queue>
#include <string>
#include <set>
#include <map>

#include <algorithm>
#include <functional>
#include <numeric>
#include <limits>
#include <iterator>

#include <complex>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <climits>
#include <cassert>

using namespace std;

#define DEBUG

#define all(a) (a).begin(), (a).end()
#define sz(a) ((int)((a).size()))
#define pb push_back
#define MP make_pair
#define mp MP

#ifdef DEBUG
    #define debug(x) cerr << #x << ": " << (x) << endl;
#else
    #define debug(x) ;
#endif

typedef pair<int, int> pii;
typedef long long ll;

template <typename T> T sqr (T x) {return x * x;}
template <typename T> T abs (T x) {return x > 0 ? x : -x;}

template <typename T>
ostream & operator << (ostream & out, vector<T> const & a) {
    out << "[";
    for (int i = 0; i < sz(a); ++i) {
        if (i != 0) {
            out << ", ";
        }
        out << a[i];
    }
    out << "]";
    return out;
}

template <typename T1, typename T2>
ostream & operator << (ostream & out, pair<T1, T2> const & p) {
    out << "(" << p.first << ", " << p.second << ")";
    return out;
}

void showTime () {
#ifdef DEBUG
    static double prev;
    static bool first = true;

    double curr = (double)clock() / CLOCKS_PER_SEC;

    cerr.setf(ios::fixed);
    cerr.precision(3);
    cerr << "<";
    if (!first) {
        cerr << curr - prev << "sec, ";
    }
    cerr << curr << "sec>\n";

    first = false;
    prev = curr;
#endif
}

int n, m, p;
const int N = 1e4 + 10;
const int M = 1e5 + 10;
int a[N], b[M];

const int L = 9;
const int K = 30;

ll g;

ll gcd (ll a, ll b) {
    if (!b) {
        return a;
    }

    return gcd(b, a % b);
}

vector<int> factors;

int mPow (int x, int n) {
    ll r = 1, c = x;
    while (n > 0) {
        if (n % 2 == 1) {
            r = (r * c) % p;
        }
        c = (c * c) % p;
        n /= 2;
    }

    return r;
}

bool check (int x) {
    for (int i = 0; i < (int)factors.size(); ++i) {
        if (mPow(x, (p - 1) / factors[i]) == 1) {
            return false;
        }
    }

    return true;
}

void factor (int x) {
    int y = x;
    for (int i = 2; i * i <= y; ++i) {
        if (x % i == 0) {
            factors.push_back(i);
            x /= i;
            while (x % i == 0) {
                x /= i;
            }
        }

    }

    if (x != 1) {
        factors.push_back(x);
    }
}

int findPrimitiveRoot () {
    for (int i = 1; ; ++i) {
        if (check(i)) {
            return i;
        }
    }
}

typedef __gnu_cxx::hash_map<int, int> Map;
Map c;

void precalc () {
    factor(p - 1);

    g = findPrimitiveRoot();

    ll q = mPow(g, (1 << L)), e = 1;
    for (ll i = 0; (i << L) < p + (1 << L); ++i) {
        c[e] = i;

        e = (e * q) % p;
    }
}

inline int exists (int x) {
    Map::iterator it = c.find(x);
    if (it == c.end()) {
        return -1;
    }
    else {
        return it->second;
    }
}

ll f (ll x) {
    int g1 = mPow(g, p - 2);

    for (int i = 0; i < (1 << L); ++i) {
        ll e = exists(x);
        if (e != -1) {
            return e * (1 << L) + i;
        }
        x = (x * g1) % p;
    }
}

void read () {
    cin >> n >> m >> p;
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    for (int i = 0; i < m; ++i) {
        cin >> b[i];
    }
}

void gen () {
    n = 1e4, m = 1e5;
    p = 1e9 + 7;
    for (int i = 0; i < n; ++i) {
        a[i] = rand() % (p - 1) + 1;
    }

    for (int i = 0; i < m; ++i) {
        b[i] = rand() % (int)1e9 + 1;
    }
}

const int DC = 1e4;
int dp[2][DC][2];

void add (int & x, int y) {
    x += y;
    if (x >= p - 1) {
        x -= (p - 1);
    }
}

int sub (int x, int y) {
    return (x - y + (p - 1)) % (p - 1);
}

int cnt (vector<int> a, int n) {
    vector<int> divisors;
    for (int i = 1; i * i <= n; ++i) {
        if (n % i == 0) {
            divisors.push_back(i);
            if (i * i != n) {
                divisors.push_back(n / i);
            }
        }
    }

    sort(all(divisors));
//   debug(divisors);
//   debug(a);

    int k = divisors.size();
    __gnu_cxx::hash_map<int, int> num;
    for (int i = 0; i < k; ++i) {
        num[divisors[i]] = i;
    }
    memset(dp[0], 0, sizeof(dp[0]));

    for (int i = 0; i < (int)a.size(); ++i) {
        for (int j = 0; j < k; ++j) {
            dp[1][j][0] = dp[1][j][1] = 0;
        }
        dp[1][num[a[i]]][0] = 1;

        for (int j = 0; j < k; ++j) {
            int e = num[divisors[j] * (a[i] / gcd(a[i], divisors[j]))];
            add(dp[1][e][0], dp[0][j][1]);
            add(dp[1][e][1], dp[0][j][0]);
        }

        for (int j = 0; j < k; ++j) {
            add(dp[0][j][0], dp[1][j][0]);
            add(dp[0][j][1], dp[1][j][1]);
        }
    }

    ll res = 0;
    // debug(divisors);
    for (int i = 0; i < k; ++i) {
        // cerr << i << " " << dp[0][i][0] << " " << dp[0][i][1] << "\n";
        res += ((sub(dp[0][i][0], dp[0][i][1])) * ((p - 1) / divisors[i])) % (p - 1);
    }

    res %= p - 1;

    return res == 0 ? (p - 1) : res;
}

int main () {
//    gen();
    read();

    precalc();

    ll q = 0;
    for (int j = 0; j < m; ++j) {
        q = gcd(b[j], q);
    }
    q = gcd(q, p - 1);

//    debug(q);
    vector<int> t(n);
    for (int i = 0; i < n; ++i) {
//        debug(a[i]);
        ll w = f(a[i]);
//        debug(w);
        t[i] = gcd(q * w, p - 1);
    }

    cout << cnt(t, p - 1) << "\n";

//    showTime();
    /*
    e1 %= (p - 1);
    e2 %= (p - 1);
    ll e = gcd(p - 1, e1 * e2);

    cout << (p - 1) / e << "\n";
    */
//    showTime();
    return 0;
}


/* Team: moscow04 */

#include <iostream>
#include <iomanip>
#include <sstream>
#include <ext/hash_map>

#include <vector>
#include <deque>
#include <queue>
#include <string>
#include <set>
#include <map>

#include <algorithm>
#include <functional>
#include <numeric>
#include <limits>
#include <iterator>

#include <complex>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <climits>
#include <cassert>

using namespace std;

#define DEBUG

#define all(a) (a).begin(), (a).end()
#define sz(a) ((int)((a).size()))
#define pb push_back
#define MP make_pair
#define mp MP

#ifdef DEBUG
    #define debug(x) cerr << #x << ": " << (x) << endl;
#else
    #define debug(x) ;
#endif

typedef pair<int, int> pii;
typedef long long ll;

template <typename T> T sqr (T x) {return x * x;}
template <typename T> T abs (T x) {return x > 0 ? x : -x;}

template <typename T>
ostream & operator << (ostream & out, vector<T> const & a) {
    out << "[";
    for (int i = 0; i < sz(a); ++i) {
        if (i != 0) {
            out << ", ";
        }
        out << a[i];
    }
    out << "]";
    return out;
}

template <typename T1, typename T2>
ostream & operator << (ostream & out, pair<T1, T2> const & p) {
    out << "(" << p.first << ", " << p.second << ")";
    return out;
}

void showTime () {
#ifdef DEBUG
    static double prev;
    static bool first = true;

    double curr = (double)clock() / CLOCKS_PER_SEC;

    cerr.setf(ios::fixed);
    cerr.precision(3);
    cerr << "<";
    if (!first) {
        cerr << curr - prev << "sec, ";
    }
    cerr << curr << "sec>\n";

    first = false;
    prev = curr;
#endif
}

int n, m, p;
const int N = 1e4 + 10;
const int M = 1e5 + 10;
int a[N], b[M];

const int L = 9;
const int K = 30;

ll g;

ll gcd (ll a, ll b) {
    if (!b) {
        return a;
    }

    return gcd(b, a % b);
}

vector<int> factors;

int mPow (int x, int n) {
    ll r = 1, c = x;
    while (n > 0) {
        if (n % 2 == 1) {
            r = (r * c) % p;
        }
        c = (c * c) % p;
        n /= 2;
    }

    return r;
}

bool check (int x) {
    for (int i = 0; i < (int)factors.size(); ++i) {
        if (mPow(x, (p - 1) / factors[i]) == 1) {
            return false;
        }
    }

    return true;
}

void factor (int x) {
    int y = x;
    for (int i = 2; i * i <= y; ++i) {
        if (x % i == 0) {
            factors.push_back(i);
            x /= i;
            while (x % i == 0) {
                x /= i;
            }
        }

    }

    if (x != 1) {
        factors.push_back(x);
    }
}

int findPrimitiveRoot () {
    for (int i = 1; ; ++i) {
        if (check(i)) {
            return i;
        }
    }
}

typedef map<int, int> Map;
Map c;

void precalc () {
    factor(p - 1);

    g = findPrimitiveRoot();

    ll q = mPow(g, (1 << L)), e = 1;
    for (ll i = 0; (i << L) < p + (1 << L); ++i) {
        c[e] = i;

        e = (e * q) % p;
    }
}

inline int exists (int x) {
    Map::iterator it = c.find(x);
    if (it == c.end()) {
        return -1;
    }
    else {
        return it->second;
    }
}

ll f (ll x) {
    int g1 = mPow(g, p - 2);

    for (int i = 0; i < (1 << L); ++i) {
        ll e = exists(x);
        if (e != -1) {
            return e * (1 << L) + i;
        }
        x = (x * g1) % p;
    }
}

void read () {
    cin >> n >> m >> p;
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    for (int i = 0; i < m; ++i) {
        cin >> b[i];
    }
}

void gen () {
    n = 1e4, m = 1e5;
    p = 1e9 + 7;
    for (int i = 0; i < n; ++i) {
        a[i] = rand() % (p - 1) + 1;
    }

    for (int i = 0; i < m; ++i) {
        b[i] = rand() % (int)1e9 + 1;
    }
}

int main () {
//    gen();
    read();

    precalc();
    ll e1 = 0;
    showTime();
    for (int i = 0; i < n; ++i) {
        e1 = gcd(e1, f(a[i]));
    }
//    showTime();

    ll e2 = 0;
    for (int j = 0; j < m; ++j) {
        e2 = gcd(b[j], e2);
    }
    e1 %= (p - 1);
    e2 %= (p - 1);
    ll e = gcd(p - 1, e1 * e2);

    cout << (p - 1) / e << "\n";
//    showTime();
    return 0;
}