#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <cstring>
#include <map>
#include <set>
#define LL long long
#define rg register
#define FILE "party"
using namespace std;
const int N = 100010;
struct Node{int to,next;}E[N*20],Er[N*20];
int n,m,head[N],tot,Head[N],Tot;
int col[N],vis[N],Ans1=-1,Ans2=-1;
int bin[N],Mxc,Mic,Jc,chain;
vector<int>G[N],W[N];
inline int gi(){
rg int x=0,res=1;rg char ch=getchar();
while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)res^=1;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-48,ch=getchar();
return res?x:-x;
}
inline void link(int u,int v){
E[++tot]=(Node){v,head[u]};
head[u]=tot;
Er[++Tot]=(Node){u,Head[v]};
Head[v]=Tot;
}
inline int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
namespace cheat{
inline void xr(int x,int c){
vis[x]=1;G[x].push_back(c);
Mxc=max(c,Mxc);Mic=min(Mic,c);
for(int e=head[x];e;e=E[e].next){
int y=E[e].to;
if(vis[y])G[y].push_back(c+1);
else xr(y,c+1);
}
for(int e=Head[x];e;e=Er[e].next){
int y=Er[e].to;
if(vis[y])G[y].push_back(c-1);
else xr(y,c-1);
}
}
inline int clr(int x,int tp=0){
for(int i=0,j=G[x].size();i<j;++i)
bin[++tp]=G[x][i];
if(!tp)return false;
sort(bin+1,bin+tp+1);
tp=unique(bin+1,bin+tp+1)-bin-1;
if(tp==1)return false;
for(int i=1;i<=tp;++i)
W[x].push_back(bin[i]);
return true;
}
inline int calc(int x,int ans=0){
for(int i=1,j=W[x].size();i<j;++i){
ans=gcd(ans,W[x][i]-W[x][i-1]);
}
return ans;
}
inline int work(int x){
for(int i=3;i<=x;++i)
if(x%i==0)return i;
return x;
}
int mian(){
for(int i=1;i<=n;++i)
if(!vis[i]){
Mxc=Mic=1;
xr(i,1);
chain+=(Mxc-Mic+1);
}
int flg=0,Ans=0;
for(int i=1;i<=n;++i)
if(clr(i))
Ans=gcd(Ans,calc(i)),flg=1;
if(!flg){
if(chain>2)cout<<chain<<‘ ‘<<3<<endl;
else cout<<"-1 -1\n";
}
else{
if(Ans>2)cout<<Ans<<‘ ‘<<work(Ans)<<endl;
else cout<<"-1 -1\n";
}
return 0;
}
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
n=gi();m=gi();
for(int i=1;i<=m;++i){
int u=gi(),v=gi();
link(u,v);
}
return cheat::mian();
fclose(stdin);fclose(stdout);
return 0;
}