#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
int op=1,x=0;
char c=getchar();
while(!isdigit(c)){
if(c=='-'){
op=-1;
}
c=getchar();
}
while(isdigit(c)){
x=x*10+c-'0';
c=getchar();
}
return op*x;
}
const int N=1e5+10;
const int M=1e6+10;
int n,m,mo,x[M],y[M],tot,de[N],to[M],fir[N],nex[M],ue[N],si[N];
inline void Ins(int x,int y){
nex[++tot]=fir[x];
fir[x]=tot;
to[tot]=y;
}
int num,top,col;
int dfn[N],low[N],st[N],co[N];
inline void Tarjan(int u){
dfn[u]=low[u]=++num;
st[++top]=u;
for(int i=fir[u];i;i=nex[i]){
int v=to[i];
if(!dfn[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else{
if(!co[v]){
low[u]=min(low[u],dfn[v]);
}
}
}
if(low[u]==dfn[u]){
co[u]=++col;
++si[col];
while(st[top]!=u){
++si[col];
co[st[top]]=col;
--top;
}
--top;
}
}
int t,w,ans,e[N],dis[N];
inline bool rule(int a,int b){
if(x[a]!=x[b]){
return x[a]<x[b];
}
return y[a]<y[b];
}
int nu[M];
inline void Remove(){
for(int i=1;i<=m;++i){
nu[i]=i;
x[i]=co[x[i]];
y[i]=co[y[i]];
}
sort(nu+1,nu+1+m,rule);
}
inline void Build(){
tot=0;
memset(fir,0,sizeof fir);
for(int i=1;i<=m;++i){
int z=nu[i];
if((x[z]!=y[z])&&(x[z]!=x[nu[i-1]]||y[z]!=y[nu[i-1]])){
++de[y[z]];
Ins(x[z],y[z]);
}
}
}
inline void Reset(){
for(int i=1;i<=col;++i){
if(!de[i]){
ue[++w]=i;
dis[i]=si[i];
e[i]=1;
if(dis[ans]<dis[i])
ans=i;
}
}
}
inline void Topo(){
while(t<w){
int u=ue[++t];
for(int i=fir[u];i;i=nex[i]){
int v=to[i];
--de[v];
if(dis[v]<dis[u]+si[v]){
dis[v]=dis[u]+si[v];
e[v]=0;
if(dis[ans]<dis[v])
ans=v;
}
if(dis[v]==dis[u]+si[v]){
e[v]=(e[v]+e[u])%mo;
}
if(!de[v])
ue[++w]=v;
}
}
}
int anss;
inline void Ask(){
for(int i=1;i<=n;++i){
if(dis[i]==dis[ans]){
anss=(anss+e[i])%mo;
}
}
}
int main(){
n=read();
m=read();
mo=read();
for(int i=1;i<=n;++i){
x[i]=read();
y[i]=read();
Ins(x[i],y[i]);
}
for(int i=1;i<=n;++i){
if(!dfn[i]){
Tarjan(i);
}
}
Remove();
Build();
Reset();
Topo();
Ask();
printf("%d\n%d",dis[ans],anss);
return 0;
}