#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <set> #include <vector> #include <map> #include <queue> #include <set> #include <algorithm> #include <limits> using namespace std; typedef long long LL; const int MAXN=100000+1000; const int MAXM=100000*3+1000; const int INF = numeric_limits<int>::max(); const LL LL_INF= numeric_limits<LL>::max(); struct Edge { int to,next; Edge(){} Edge(int _to,int _next):to(_to),next(_next){} }e[MAXM]; int head[MAXN],tot; void init(){ memset(head,-1,sizeof(head)); tot=0; } void AddEdge(int u,int v){ e[tot]=Edge(v,head[u]); head[u]=tot++; e[tot]=Edge(u,head[v]); head[v]=tot++; } int colors[MAXN],c0,c1; int dfs(int u){ if(colors[u]==0)++c0; else ++c1; for(int i=head[u];~i;i=e[i].next){ int to=e[i].to; if(colors[to]==-1){ colors[to]=!colors[u]; if(!dfs(to))return false; } else if(colors[to]==colors[u]){ return false; } } return true; } int has[MAXN],n,m; int main() { int t; scanf("%d",&t); while(t--){ memset(colors,-1,sizeof(colors)); memset(has,0,sizeof(has)); init(); scanf("%d%d",&n,&m); int tot=n; for(int i=0,x,y;i<m;i++){ scanf("%d%d",&x,&y); AddEdge(x,y); if(!has[x]){ has[x]=1; tot--; } if(!has[y]){ has[y]=1; tot--; } } if(n==0){ puts("Poor wyh"); continue; } if(m==0){ if(n==1){ puts("Poor wyh"); } else { printf("%d %d\n",n-1,1); } continue; } int cnt1=0,cnt2=0,ok=0; for(int i=1;i<=n;i++){ if(colors[i]==-1&&has[i]){ c0=c1=0; colors[i]=0; if(!dfs(i))ok=1; if(c0<c1)swap(c0,c1); if(cnt1==0){ cnt1+=c0; cnt2+=c1; } else if(cnt2==0){ cnt2+=c0; cnt1+=c1; } else { cnt1+=c0; cnt2+=c1; } if(cnt1<cnt2)swap(cnt1,cnt2); } } if(ok)puts("Poor wyh"); else { if(cnt1==0||cnt2==0){ puts("Poor wyh"); continue; } if(cnt1<cnt2)swap(cnt1,cnt2); printf("%d %d\n",cnt1+tot,cnt2); } } return 0; }
|