[Tarjin三连发]poj1236 poj2168 poj 2553
http://poj.org/problem?id=1236
http://poj.org/problem?id=2168http://poj.org/problem?id=2553
我想说tarjin不是很好写,我因为写错了targin WA了好几次。这两道题目是裸tarjin(求强联通分量),然后记录到id数组,就是缩点,不必建立新图,直接遍历所有边,然后计算出来出入度,刚开始的时候我卡在了最后,因为会了tarjin之后思路有的,但是通过出入度找到答案还是有点难度,而且有trick,所以一定要考虑全面,不过最重要的是学会算法,我的blog写的并不是很全面,很多时候是给自己看的,不过没关系,相信我的代码能有一定参考吧。。就算没人看也没关系。坚持努力吧。。
2168:
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<string>
#include<bitset>
#include<queue>
#include<vector>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#define rep(i,n,m) for(int i=(n);i<=(m);++i)
#define re1(i,n) rep(i,1,n)
#define re0(i,n) rep(i,0,n)
#define RE(a) ((a)*(a))
#define SIZE(a) (int((a).size()))
#define vv(a) vector<a>
#define vi vv(int)
#define vl vv(ll)
#define vb vv(bool)
//count distance 不能用哦,已经定义了。
using namespace std;
typedef long long ll;
template<class T>
void inline maxi(T &a,T &b){
a=max(a,b);
}
template<class T>
void inline mini(T &a,T &b){
a=min(a,b);
}
void shownum(int n,int m){
rep(i,n,m){
cout<<setw(6)<<i;
}
cout<<endl;
}
template<class T,class P>
void fill(T &a,P v){
int n=SIZE(a)-1;
re0(i,n)
a[i]=v;
}
template<class T>
void show(T &a,int n,int m){
rep(i,n,m){
cout<<setw(6)<<a[i];
}
cout<<endl;
}
template<class T>
void show(T *a[10],int n,int m){
re0(i,n){
re0(j,m)
cout<<a[i]<<' ';
cout<<endl;
}
}
const int maxnum=+1;
const int maxint=2147483647;
vi G,next,dest;
vi timee,id,low;
vi scc_num,out_num;
int n,m,tim;
set<pair<int,int> >sett;
stack<int> ss;
vb instack;
void addd(int a,int b){
next.push_back(G[a]);
G[a]=SIZE(next)-1;
dest.push_back(b);
}
void init(){
G.assign(n+1,-1);
tim=0;
sett.clear();
while(!ss.empty())ss.pop();
timee.assign(n+1,0);
instack.assign(n+1,false);
low.assign(n+1,0);
id.assign(n+1,0);
scc_num.assign(n+1,0);
out_num.assign(n+1,0);
re1(u,m){
int a,b;
scanf("%d%d",&a,&b);
addd(a,b);
}
}
void targin(int s){
ss.push(s);
instack[s]=true;
timee[s]=low[s]=++tim;
for(int i=G[s];i!=-1;i=next[i]){
int v=dest[i];
if(!timee[v]){
targin(v);
mini(low[s],low[v]);
}else if(instack[v])
mini(low[s],timee[v]);
}
if(low[s]==timee[s]){
while(true){
int t = ss.top();
instack[t]=false;
id[t]=s;
scc_num[s]++;
ss.pop();
if(t==s)
break;
}
}
}
void mmain(){
while(~scanf("%d%d",&n,&m)){
init();
re1(u,n){
if(!timee[u])
targin(u);
}
int cc=0,j=0;
re1(u,n){
for(int i=G[u];i!=-1;i=next[i]){
int v=dest[i];
pair<int,int> p = make_pair(id[u],id[v]);
if(p.first!=p.second && sett.find(p) == sett.end()){
sett.insert(p);
out_num[p.first]++;
}
}
}
vb mark(n+1,false);
re1(u,n){
int p = id[u];
if(!mark[p] && out_num[p]==0){
cc++;
j=id[u];
}
mark[p]=true;
}
if(cc==0)
printf("%d\n",n);
else if(cc==1)
printf("%d\n",scc_num[j]);
else
puts("0");
}
}
//#define codeforces CODEFORCES
#define codeforces_input CODEFORCES_FILE
#define MANY_TEST CODEFORCES_MANY_TEST
#define MANY_TESST 3
int main(){
#ifdef codeforces
#ifdef codeforces_input
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
#ifdef MANY_TEST
re1(wwwwwwwwwwwwwwwwwwwww,MANY_TESST)
mmain();
return 0;
#endif
#endif
mmain(); }
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<string>
#include<bitset>
#include<queue>
#include<vector>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#define rep(i,n,m) for(int i=(n);i<=(m);++i)
#define re1(i,n) rep(i,1,n)
#define re0(i,n) rep(i,0,n)
#define RE(a) ((a)*(a))
#define SIZE(a) (int((a).size()))
#define vv(a) vector<a>
#define vi vv(int)
#define vl vv(ll)
#define vb vv(bool)
//count distance 不能用哦,已经定义了。
using namespace std;
typedef long long ll;
template<class T>
void inline maxi(T &a,T &b){
a=max(a,b);
}
template<class T>
void inline mini(T &a,T &b){
a=min(a,b);
}
void shownum(int n,int m){
rep(i,n,m){
cout<<setw(6)<<i;
}
cout<<endl;
}
template<class T,class P>
void fill(T &a,P v){
int n=SIZE(a)-1;
re0(i,n)
a[i]=v;
}
template<class T>
void show(T &a,int n,int m){
rep(i,n,m){
cout<<setw(6)<<a[i];
}
cout<<endl;
}
template<class T>
void show(T *a[10],int n,int m){
re0(i,n){
re0(j,m)
cout<<a[i]<<' ';
cout<<endl;
}
}
const int maxnum=+1;
const int maxint=2147483647;
vi G,next,dest;
vi timee,id,low;
vi scc_num,out_num;
int n,m,tim;
set<pair<int,int> >sett;
stack<int> ss;
vb instack;
void addd(int a,int b){
next.push_back(G[a]);
G[a]=SIZE(next)-1;
dest.push_back(b);
}
void init(){
G.assign(n+1,-1);
tim=0;
sett.clear();
while(!ss.empty())ss.pop();
timee.assign(n+1,0);
instack.assign(n+1,false);
low.assign(n+1,0);
id.assign(n+1,0);
scc_num.assign(n+1,0);
out_num.assign(n+1,0);
re1(u,m){
int a,b;
scanf("%d%d",&a,&b);
addd(a,b);
}
}
void targin(int s){
ss.push(s);
instack[s]=true;
timee[s]=low[s]=++tim;
for(int i=G[s];i!=-1;i=next[i]){
int v=dest[i];
if(!timee[v]){
targin(v);
mini(low[s],low[v]);
}else if(instack[v])
mini(low[s],timee[v]);
}
if(low[s]==timee[s]){
while(true){
int t = ss.top();
instack[t]=false;
id[t]=s;
scc_num[s]++;
ss.pop();
if(t==s)
break;
}
}
}
void mmain(){
while(~scanf("%d%d",&n,&m)){
init();
re1(u,n){
if(!timee[u])
targin(u);
}
int cc=0,j=0;
re1(u,n){
for(int i=G[u];i!=-1;i=next[i]){
int v=dest[i];
pair<int,int> p = make_pair(id[u],id[v]);
if(p.first!=p.second && sett.find(p) == sett.end()){
sett.insert(p);
out_num[p.first]++;
}
}
}
vb mark(n+1,false);
re1(u,n){
int p = id[u];
if(!mark[p] && out_num[p]==0){
cc++;
j=id[u];
}
mark[p]=true;
}
if(cc==0)
printf("%d\n",n);
else if(cc==1)
printf("%d\n",scc_num[j]);
else
puts("0");
}
}
//#define codeforces CODEFORCES
#define codeforces_input CODEFORCES_FILE
#define MANY_TEST CODEFORCES_MANY_TEST
#define MANY_TESST 3
int main(){
#ifdef codeforces
#ifdef codeforces_input
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
#ifdef MANY_TEST
re1(wwwwwwwwwwwwwwwwwwwww,MANY_TESST)
mmain();
return 0;
#endif
#endif
mmain(); }
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<string>
#include<bitset>
#include<queue>
#include<vector>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#define rep(i,n,m) for(int i=(n);i<=(m);++i)
#define re1(i,n) rep(i,1,n)
#define re0(i,n) rep(i,0,n)
#define RE(a) ((a)*(a))
#define SIZE(a) (int((a).size()))
#define vv(a) vector<a>
#define vi vv(int)
#define vl vv(ll)
#define vb vv(bool)
//count distance 不能用哦,已经定义了。
using namespace std;
typedef long long ll;
template<class T>
void inline maxi(T &a,T &b){
a=max(a,b);
}
template<class T>
void inline mini(T &a,T &b){
a=min(a,b);
}
void shownum(int n,int m){
rep(i,n,m){
cout<<setw(6)<<i;
}
cout<<endl;
}
template<class T,class P>
void fill(T &a,P v){
int n=SIZE(a)-1;
re0(i,n)
a[i]=v;
}
template<class T,class P>
void fill(T *a,P v,int n){
re0(i,n-1)
a[i]=v;
}
template<class T>
void show(T &a,int n,int m){
rep(i,n,m){
cout<<setw(6)<<a[i];
}
cout<<endl;
}
template<class T>
void show(T *a[10],int n,int m){
re0(i,n){
re0(j,m)
cout<<a[i]<<' ';
cout<<endl;
}
}
const int maxnum=100+1;
const int maxint=2147483647;
//graph
int G[maxnum];
vi next,dest,dist;
void addd(int a,int b,int v){
next.push_back(G[a]);
G[a]=SIZE(next)-1;
dest.push_back(b);
dist.push_back(v);
}
void initG(){
next.clear();
dest.clear();
dist.clear();
fill(G,-1,maxnum-1);
}
//end graph
//tarjin
int timee[maxnum],id[maxnum],low[maxnum],tim,sccn;
bool instack[maxnum];
stack<int> ss;
void tarjin(int s){
ss.push(s);
instack[s]=true;
timee[s]=low[s]=++tim;
for(int i=G[s];i!=-1;i=next[i]){
int v = dest[i];
if(!timee[v]){
tarjin(v);
mini(low[s],low[v]);
}else if(instack[v])
mini(low[s],timee[v]);
}
if(low[s]==timee[s]){
sccn++;
while(true){
int t = ss.top();
ss.pop();
instack[t]=false;
id[t]=s;
if(t==s)
break;
}
}
}
void initT(){
fill(timee,0,maxnum-1);
fill(id,0,maxnum-1);
fill(low,0,maxnum-1);
fill(instack,false,maxnum-1);
tim=sccn=0;
while(!ss.empty())ss.pop();
}
//end tarjin
int in[maxnum],out[maxnum];
int n;
bool mark[maxnum];
void init(){
initG();
initT();
fill(in,0,maxnum-1);
fill(out,0,maxnum-1);
fill(mark,false,maxnum-1);
re1(u,n){
int t;
while(~scanf("%d",&t)){
if(t==0)
break;
addd(u,t,0);
}
}
}
void mmain(){
while(~scanf("%d",&n)){
init();
re1(u,n)
if(!timee[u])
tarjin(u);
set< pair<int, int> > sett;
re1(u,n){
for(int i = G[u];i != -1;i = next[i]){
int v = dest[i];
pair<int,int> p = make_pair(id[u], id[v]);
if(p.first!=p.second && sett.find(p)==sett.end()){
sett.insert(p);
out[p.first]++;
in[p.second]++;
}
}
}
int ansA=0;
int ansB=0;
/*
shownum(1,n);
show(id,1,n);
show(out,1,n);
show(in,1,n);
*/
//cout<<"#"<<sccn<<endl;
re1(u,n){
int p = id[u];
if(!mark[p]){
if(!in[p]){
ansA++;
}
if(!out[p]){
ansB++;
}
}
mark[p]=true;
}
cout<<ansA<<endl;
if(sccn==1)
cout<<0<<endl;
else
cout<<max(ansA,ansB)<<endl;
}
}
//#define codeforces CODEFORCES
#define codeforces_input CODEFORCES_FILE
#define MANY_TEST CODEFORCES_MANY_TEST
#define MANY_TESST 3
int main(){
#ifdef codeforces
#ifdef codeforces_input
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
#ifdef MANY_TEST
re1(wwwwwwwwwwwwwwwwwwwww,MANY_TESST)
mmain();
return 0;
#endif
#endif
mmain();}
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<string>
#include<bitset>
#include<queue>
#include<vector>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#define rep(i,n,m) for(int i=(n);i<=(m);++i)
#define re1(i,n) rep(i,1,n)
#define re0(i,n) rep(i,0,n)
#define RE(a) ((a)*(a))
#define SIZE(a) (int((a).size()))
#define vv(a) vector<a>
#define vi vv(int)
#define vl vv(ll)
#define vb vv(bool)
//count distance 不能用哦,已经定义了。
using namespace std;
typedef long long ll;
template<class T>
void inline maxi(T &a,T &b){
a=max(a,b);
}
template<class T>
void inline mini(T &a,T &b){
a=min(a,b);
}
void shownum(int n,int m){
rep(i,n,m){
cout<<setw(6)<<i;
}
cout<<endl;
}
template<class T,class P>
void fill(T &a,P v){
int n=SIZE(a)-1;
re0(i,n)
a[i]=v;
}
template<class T,class P>
void fill(T *a,P v,int n){
re0(i,n-1)
a[i]=v;
}
template<class T>
void show(T &a,int n,int m){
rep(i,n,m){
cout<<setw(6)<<a[i];
}
cout<<endl;
}
template<class T>
void show(T *a[10],int n,int m){
re0(i,n){
re0(j,m)
cout<<a[i]<<' ';
cout<<endl;
}
}
const int maxnum=100+1;
const int maxint=2147483647;
//graph
int G[maxnum];
vi next,dest,dist;
void addd(int a,int b,int v){
next.push_back(G[a]);
G[a]=SIZE(next)-1;
dest.push_back(b);
dist.push_back(v);
}
void initG(){
next.clear();
dest.clear();
dist.clear();
fill(G,-1,maxnum-1);
}
//end graph
//tarjin
int timee[maxnum],id[maxnum],low[maxnum],tim,sccn;
bool instack[maxnum];
stack<int> ss;
void tarjin(int s){
ss.push(s);
instack[s]=true;
timee[s]=low[s]=++tim;
for(int i=G[s];i!=-1;i=next[i]){
int v = dest[i];
if(!timee[v]){
tarjin(v);
mini(low[s],low[v]);
}else if(instack[v])
mini(low[s],timee[v]);
}
if(low[s]==timee[s]){
sccn++;
while(true){
int t = ss.top();
ss.pop();
instack[t]=false;
id[t]=s;
if(t==s)
break;
}
}
}
void initT(){
fill(timee,0,maxnum-1);
fill(id,0,maxnum-1);
fill(low,0,maxnum-1);
fill(instack,false,maxnum-1);
tim=sccn=0;
while(!ss.empty())ss.pop();
}
//end tarjin
int in[maxnum],out[maxnum];
int n;
bool mark[maxnum];
void init(){
initG();
initT();
fill(in,0,maxnum-1);
fill(out,0,maxnum-1);
fill(mark,false,maxnum-1);
re1(u,n){
int t;
while(~scanf("%d",&t)){
if(t==0)
break;
addd(u,t,0);
}
}
}
void mmain(){
while(~scanf("%d",&n)){
init();
re1(u,n)
if(!timee[u])
tarjin(u);
set< pair<int, int> > sett;
re1(u,n){
for(int i = G[u];i != -1;i = next[i]){
int v = dest[i];
pair<int,int> p = make_pair(id[u], id[v]);
if(p.first!=p.second && sett.find(p)==sett.end()){
sett.insert(p);
out[p.first]++;
in[p.second]++;
}
}
}
int ansA=0;
int ansB=0;
/*
shownum(1,n);
show(id,1,n);
show(out,1,n);
show(in,1,n);
*/
//cout<<"#"<<sccn<<endl;
re1(u,n){
int p = id[u];
if(!mark[p]){
if(!in[p]){
ansA++;
}
if(!out[p]){
ansB++;
}
}
mark[p]=true;
}
cout<<ansA<<endl;
if(sccn==1)
cout<<0<<endl;
else
cout<<max(ansA,ansB)<<endl;
}
}
//#define codeforces CODEFORCES
#define codeforces_input CODEFORCES_FILE
#define MANY_TEST CODEFORCES_MANY_TEST
#define MANY_TESST 3
int main(){
#ifdef codeforces
#ifdef codeforces_input
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
#ifdef MANY_TEST
re1(wwwwwwwwwwwwwwwwwwwww,MANY_TESST)
mmain();
return 0;
#endif
#endif
mmain();}
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<string>
#include<bitset>
#include<queue>
#include<vector>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#define rep(i,n,m) for(int i=(n);i<=(m);++i)
#define re1(i,n) rep(i,1,n)
#define re0(i,n) rep(i,0,n)
#define RE(a) ((a)*(a))
#define SIZE(a) (int((a).size()))
#define vv(a) vector<a>
#define vi vv(int)
#define vl vv(ll)
#define vb vv(bool)
//count distance 不能用哦,已经定义了。
using namespace std;
typedef long long ll;
template<class T>
void inline maxi(T &a,T &b){
a=max(a,b);
}
template<class T>
void inline mini(T &a,T &b){
a=min(a,b);
}
void shownum(int n,int m){
rep(i,n,m){
cout<<setw(6)<<i;
}
cout<<endl;
}
template<class T,class P>
void fill(T &a,P v){
int n=SIZE(a)-1;
re0(i,n)
a[i]=v;
}
template<class T,class P>
void fill(T *a,P v,int n){
re0(i,n-1)
a[i]=v;
}
template<class T>
void show(T &a,int n,int m){
rep(i,n,m){
cout<<setw(6)<<a[i];
}
cout<<endl;
}
template<class T>
void show(T *a[10],int n,int m){
re0(i,n){
re0(j,m)
cout<<a[i]<<' ';
cout<<endl;
}
}
const int maxnum=5000+1;
const int maxint=2147483647;
//graph
int G[maxnum];
vi next,dest,dist;
void addd(int a,int b,int v){
next.push_back(G[a]);
G[a]=SIZE(next)-1;
dest.push_back(b);
dist.push_back(v);
}
void initG(){
next.clear();
dest.clear();
dist.clear();
fill(G,-1,maxnum-1);
}
//end graph
//tarjin
int timee[maxnum],id[maxnum],low[maxnum],tim,sccn;
bool instack[maxnum];
vi scc[maxnum];
stack<int> ss;
void tarjin(int s){
ss.push(s);
instack[s]=true;
timee[s]=low[s]=++tim;
for(int i=G[s];i!=-1;i=next[i]){
int v = dest[i];
if(!timee[v]){
tarjin(v);
mini(low[s],low[v]);
}else if(instack[v])
mini(low[s],timee[v]);
}
if(low[s]==timee[s]){
sccn++;
while(true){
int t = ss.top();
ss.pop();
instack[t]=false;
id[t]=s;
scc[s].push_back(t);
if(t==s)
break;
}
}
}
void initT(){
re0(u,maxnum-1)
scc[u].clear();
fill(timee,0,maxnum-1);
fill(id,0,maxnum-1);
fill(low,0,maxnum-1);
fill(instack,false,maxnum-1);
tim=sccn=0;
while(!ss.empty())ss.pop();
}
//end tarjin
int in[maxnum],out[maxnum];
int n;
bool mark[maxnum];
void init(){
initG();
initT();
fill(in,0,maxnum-1);
fill(out,0,maxnum-1);
fill(mark,false,maxnum-1);
int m;
scanf("%d",&m);
re1(u,m){
int a,b;
scanf("%d%d",&a,&b);
addd(a,b,0);
}
}
void mmain(){
while(~scanf("%d",&n)){
if(n==0)
break;
init();
re1(u,n)
if(!timee[u])
tarjin(u);
set< pair<int, int> > sett;
re1(u,n){
for(int i = G[u];i != -1;i = next[i]){
int v = dest[i];
pair<int,int> p = make_pair(id[u], id[v]);
if(p.first!=p.second && sett.find(p)==sett.end()){
sett.insert(p);
out[p.first]++;
in[p.second]++;
}
}
}
int ansA=0;
int ansB=0;
/*
shownum(1,n);
show(id,1,n);
show(out,1,n);
show(in,1,n);
*/
//cout<<"#"<<sccn<<endl;
vi ans;
re1(u,n){
int p = id[u];
if(!mark[p]){
if(!out[p]){
re0(u,SIZE(scc[p])-1)
ans.push_back(scc[p][u]);
}
}
mark[p]=true;
}
sort(ans.begin(),ans.end());
re0(u,SIZE(ans)-1)
cout<<ans[u]<<' ';
cout<<endl;
}
}
//#define codeforces CODEFORCES
#define codeforces_input CODEFORCES_FILE
#define MANY_TEST CODEFORCES_MANY_TEST
#define MANY_TESST 3
int main(){
#ifdef codeforces
#ifdef codeforces_input
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
#ifdef MANY_TEST
re1(wwwwwwwwwwwwwwwwwwwww,MANY_TESST)
mmain();
return 0;
#endif
#endif
mmain();
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<string>
#include<bitset>
#include<queue>
#include<vector>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#define rep(i,n,m) for(int i=(n);i<=(m);++i)
#define re1(i,n) rep(i,1,n)
#define re0(i,n) rep(i,0,n)
#define RE(a) ((a)*(a))
#define SIZE(a) (int((a).size()))
#define vv(a) vector<a>
#define vi vv(int)
#define vl vv(ll)
#define vb vv(bool)
//count distance 不能用哦,已经定义了。
using namespace std;
typedef long long ll;
template<class T>
void inline maxi(T &a,T &b){
a=max(a,b);
}
template<class T>
void inline mini(T &a,T &b){
a=min(a,b);
}
void shownum(int n,int m){
rep(i,n,m){
cout<<setw(6)<<i;
}
cout<<endl;
}
template<class T,class P>
void fill(T &a,P v){
int n=SIZE(a)-1;
re0(i,n)
a[i]=v;
}
template<class T,class P>
void fill(T *a,P v,int n){
re0(i,n-1)
a[i]=v;
}
template<class T>
void show(T &a,int n,int m){
rep(i,n,m){
cout<<setw(6)<<a[i];
}
cout<<endl;
}
template<class T>
void show(T *a[10],int n,int m){
re0(i,n){
re0(j,m)
cout<<a[i]<<' ';
cout<<endl;
}
}
const int maxnum=5000+1;
const int maxint=2147483647;
//graph
int G[maxnum];
vi next,dest,dist;
void addd(int a,int b,int v){
next.push_back(G[a]);
G[a]=SIZE(next)-1;
dest.push_back(b);
dist.push_back(v);
}
void initG(){
next.clear();
dest.clear();
dist.clear();
fill(G,-1,maxnum-1);
}
//end graph
//tarjin
int timee[maxnum],id[maxnum],low[maxnum],tim,sccn;
bool instack[maxnum];
vi scc[maxnum];
stack<int> ss;
void tarjin(int s){
ss.push(s);
instack[s]=true;
timee[s]=low[s]=++tim;
for(int i=G[s];i!=-1;i=next[i]){
int v = dest[i];
if(!timee[v]){
tarjin(v);
mini(low[s],low[v]);
}else if(instack[v])
mini(low[s],timee[v]);
}
if(low[s]==timee[s]){
sccn++;
while(true){
int t = ss.top();
ss.pop();
instack[t]=false;
id[t]=s;
scc[s].push_back(t);
if(t==s)
break;
}
}
}
void initT(){
re0(u,maxnum-1)
scc[u].clear();
fill(timee,0,maxnum-1);
fill(id,0,maxnum-1);
fill(low,0,maxnum-1);
fill(instack,false,maxnum-1);
tim=sccn=0;
while(!ss.empty())ss.pop();
}
//end tarjin
int in[maxnum],out[maxnum];
int n;
bool mark[maxnum];
void init(){
initG();
initT();
fill(in,0,maxnum-1);
fill(out,0,maxnum-1);
fill(mark,false,maxnum-1);
int m;
scanf("%d",&m);
re1(u,m){
int a,b;
scanf("%d%d",&a,&b);
addd(a,b,0);
}
}
void mmain(){
while(~scanf("%d",&n)){
if(n==0)
break;
init();
re1(u,n)
if(!timee[u])
tarjin(u);
set< pair<int, int> > sett;
re1(u,n){
for(int i = G[u];i != -1;i = next[i]){
int v = dest[i];
pair<int,int> p = make_pair(id[u], id[v]);
if(p.first!=p.second && sett.find(p)==sett.end()){
sett.insert(p);
out[p.first]++;
in[p.second]++;
}
}
}
int ansA=0;
int ansB=0;
/*
shownum(1,n);
show(id,1,n);
show(out,1,n);
show(in,1,n);
*/
//cout<<"#"<<sccn<<endl;
vi ans;
re1(u,n){
int p = id[u];
if(!mark[p]){
if(!out[p]){
re0(u,SIZE(scc[p])-1)
ans.push_back(scc[p][u]);
}
}
mark[p]=true;
}
sort(ans.begin(),ans.end());
re0(u,SIZE(ans)-1)
cout<<ans[u]<<' ';
cout<<endl;
}
}
//#define codeforces CODEFORCES
#define codeforces_input CODEFORCES_FILE
#define MANY_TEST CODEFORCES_MANY_TEST
#define MANY_TESST 3
int main(){
#ifdef codeforces
#ifdef codeforces_input
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
#ifdef MANY_TEST
re1(wwwwwwwwwwwwwwwwwwwww,MANY_TESST)
mmain();
return 0;
#endif
#endif
mmain();
}