#pragma GCC optimize("Ofast", "inline", "-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
using namespace std;
#define FIOBUFSIZ (1<<20|1)
#define NOTONLYDIGIT
struct freader
{
FILE*f;
# ifdef ONLINE_JUDGE
char buf[FIOBUFSIZ],*p1,*p2;
# define fgetc(f) (p1==p2&&(p2=(p1=buf)+fread(buf,1,FIOBUFSIZ,f),p1==p2)?EOF:*p1++)
# endif
# ifdef BOOLTRANS
bool neof;
# define NEOF(c) ((c)!=EOF||(neof=0))
# else
# define NEOF(c) ((c)!=EOF)
# endif
# ifdef NOTONLYDIGIT
# define isdigit(c) ((c)>='0'&&(c)<='9')
# define isnotdigit(c) ((c)<'0'||(c)>'9')
# else
# define isdigit(c) ((c)>='0')
# define isnotdigit(c) ((c)<'0')
# endif
freader(FILE*_f=stdin):f(_f)
{
# ifdef BOOLTRANS
neof=1;
# endif
# ifdef ONLINE_JUDGE
setvbuf(f,NULL,_IONBF,0);
p1=p2=buf;
# endif
}
# ifdef NOTONLYDIGIT
void read(char&x)
{
for(x=fgetc(f);NEOF(x)&&x<=' ';x=fgetc(f));
return;
}
void read(char*s)
{
for(*s=fgetc(f);NEOF(*s)&&*s<=' ';*s=fgetc(f));
for(s++;NEOF(*s=fgetc(f))&&*s>' ';s++);
*s='\0';
return;
}
# endif
template<typename T>void read(T&x)
{
char c(fgetc(f));
# ifdef NEGATIVE
for(;NEOF(c)&&isnotdigit(c)&&c!='-';c=fgetc(f));
if(c=='-')
for(c=fgetc(f),x=0;NEOF(c)&&isdigit(c);c=fgetc(f))
x=(x<<3)+(x<<1)-(c^'0');
else
for(x=0;NEOF(c)&&isdigit(c);c=fgetc(f))
x=(x<<3)+(x<<1)+(c^'0');
# else
for(;NEOF(c)&&isnotdigit(c);c=fgetc(f));
for(x=0;NEOF(c)&&isdigit(c);c=fgetc(f))
x=(x<<3)+(x<<1)+(c^'0');
# endif
return;
}
# if __cplusplus>=201103
template<typename T,typename...Args>void read(T&x,Args&...args){return read(x),read(args...);}
# endif
template<typename T>freader&operator>>(T&x)
{
# ifdef BOOLTRANS
return *this?read(x),*this:*this;
# else
return read(x),*this;
# endif
}
# ifdef BOOLTRANS
operator bool(){return neof;}
# endif
# ifdef ONLINE_JUDGE
# undef fgetc
# endif
# undef NEOF
# undef isdigit
# undef isnotdigit
}fin;
struct fwriter
{
FILE*f;
# ifdef ONLINE_JUDGE
char buf[FIOBUFSIZ],*p1;
# define fputc(c,f) (p1==buf+FIOBUFSIZ?fwrite(buf,1,FIOBUFSIZ,f),*(p1=buf)++=(c):*p1++=(c))
# endif
fwriter(FILE*_f=stdout):f(_f)
{
# ifdef ONLINE_JUDGE
setvbuf(f,NULL,_IONBF,0);
p1=buf;
# endif
}
~fwriter(){flush();}
void flush()
{
# ifdef ONLINE_JUDGE
fwrite(buf,1,p1-buf,f),p1=buf;
# else
fflush(f);
# endif
return;
}
void write(char c)
{
fputc(c,f);
return;
}
void write(char*s)
{
for(;*s;s++)
fputc(*s,f);
return;
}
void write(const char*s)
{
for(;*s;s++)
fputc(*s,f);
return;
}
template<typename T>void write(T x)
{
if(!x)
{
fputc('0',f);
return;
}
if(x<0)
fputc('-',f),x=-x;
char s[41];
int l(0);
while(x)
s[l++]=x%10^'0',x/=10;
while(l--)
fputc(s[l],f);
return;
}
# if __cplusplus>=201103
template<typename T,typename...Args>void write(T x,Args...args){return write(x),write(args...);}
# endif
template<typename T>fwriter&operator<<(T x){return write(x),*this;}
# ifdef ONLINE_JUDGE
# undef fputc
# endif
}fout;
#undef FIOBUFSIZ
const int N=1e5+5;
int T,n,m,d[N],sz;
bool cmp(int x,int y) {return x>y;}
int main() {
fin>>T;
while(T--) {
fin>>n>>m;
if(!m) {
printf("%d 1\n",n;
continue;
}
for(int i=1;i<=n;i++) d[i]=0;
for(int i=1,x,y;i<=m;d[x]++,d[y]++,i++) fin>>x>>y;
sort(d+1,d+n+1,cmp);
for(int i=1;i<=n;i++)
if(d[i]<i-1) {sz=i-1;break;}
int ans=1,ans1=0,ans2=1;
for(int i=sz+1;i<=n;i++)
if(d[i]==sz-1) ans++;
for(int i=1;i<=sz;i++)
if(d[i]==sz) ans2++;
else if(d[i]==sz-1) ans1++;
fout<<ans<<' '<<(ans1?ans1:ans2)<<'\n';
}
}