ACcode:
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=2e4+1e3;
inline int read(){
int res=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) res=(res<<3)+(res<<1)+(c^48);
return res*f;
}
int n,m,ans;
vector<int> g[N];
bool cut[N];
int dfn[N],low[N],dfncnt;
int st[N],top;
bool inst[N];
void tarjan(int u,int anc){
dfn[u]=low[u]=++dfncnt;
int child=0;
for(auto v:g[u]){
if(!dfn[v]){
tarjan(v,anc),low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]&&u!=anc) cut[u]=true;//如果儿子的low值大于等于dfn,则代表其为儿子与其他非子树点相连的唯一途径
if(u==anc) child++;
}
else low[u]=min(low[u],dfn[v]);
}
if(child>=2&&u==anc) cut[u]=true;//对根的处理
}
int main(){
n=read(),m=read();
for(int i=1,u,v;i<=m;i++){
u=read(),v=read();
g[u].pb(v);g[v].pb(u);
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i,i);
for(int i=1;i<=n;i++)
if(cut[i]) ans++;
printf("%d\n",ans);
for(int i=1;i<=n;i++)
if(cut[i]) printf("%d ",i);
return 0;
}
over~