#include <iostream>
#include <vector>
#include <set>
using namespace std;

static const int NIL = -1;

struct Vertex {
    vector<int> link;
    int parent = NIL;
    int ord;
    int lowlink;
    bool is_visit = false;
};

class ArticulationPoint {
private:
    int n;
    vector<Vertex> graph;
    int timer = 1;

public:
    ArticulationPoint() {}

    ArticulationPoint(int n)
    {
        this->n = n;
        graph.resize(n);
        int edge;
        cin >> edge;
        int s, t;
        for (int e = 0; e < edge; e++)
        {
            cin >> s >> t;
            graph[s].link.push_back(t);
            graph[t].link.push_back(s);
        }
    }

    void dfs(int current)
    {
        graph[current].is_visit = true;
        graph[current].ord = graph[current].lowlink = timer;
        timer++;

        for(int next : graph[current].link)
        {
            if(!graph[next].is_visit)
            {
                graph[next].parent = current;
                dfs(next);
                graph[current].lowlink = min(graph[current].lowlink, graph[next].lowlink); // 3.
            }
            else if(next != graph[current].parent)
            {
                // １回の移動で行くことのできる訪問済みの頂点は，Backedgeを除けば自分の親しかいない
                // つまりこのブロックにくるのはnextがBackedgeを通った訪問済みの頂点のとき
                graph[current].lowlink = min(graph[current].lowlink, graph[next].ord);
            }

        }
    }

    void articulation_point()
    {
        set<int> art_point;
        int root = 0;

        dfs(root);

        int root_child_num = 0;
        for(int u = 0; u < n; u++)
        {
            int p = graph[u].parent;
            if(p == NIL) continue;
            if(p == root)
            {
                root_child_num++;
                if(root_child_num >= 2)
                    art_point.insert(root);
            }
            else if(graph[p].ord <= graph[u].lowlink)
            {
                art_point.insert(p);
            }
        }

        for(int x : art_point)
            cout << x << endl;
    }
};

int main()
{
    int n;
    cin >> n;
    ArticulationPoint articulationPoint(n);
    articulationPoint.articulation_point();
}

#include<bits/stdc++.h>
using namespace std;
#define INF 100010
typedef pair<int,int> P;
vector<int> G[100010];
vector<int> GG[100010];
int V,E,n;
int ord[100010];
int low[100010];
int par[100010];

int lowlink(int x,int p){
  ord[x]=n++,par[x]=p;
  int ans=ord[x];
  for(int i=0;i<G[x].size();i++){
    if(G[x][i]==p)continue;
    if(ord[G[x][i]]!=INF)ans=min(ord[G[x][i]],ans);
    else {
      ans=min(ans,lowlink(G[x][i],x));
      GG[x].push_back(G[x][i]);
    }
  }
  return low[x]=ans;
}

int main(){
  for(int i=0;i<100010;i++)
    low[i]=ord[i]=INF;
  cin>>V>>E;
  P p[100010];
  for(int i=0;i<E;i++){
    int s,t;
    cin>>s>>t;
    G[s].push_back(t);
    G[t].push_back(s);
    if(s>t)swap(s,t);
    p[i]=P(s,t);
  }
  sort(p,p+E);
  lowlink(0,-1);
  for(int i=0;i<V;i++){
    int f=0;
    if(i==0&&GG[0].size()>1)f=1;
    if(i!=0)
      for(int j=0;j<GG[i].size();j++){
	if(GG[i][j]==par[i])continue;
	if(low[GG[i][j]]>=ord[i])f=1;
	//cout<<i<<" "<<G[i][j]<<" "<<low[i]<<" "<<low[G[i][j]]<<" "<<f<<endl;
      }
    //cout<<low[i]<<endl;
    if(f)cout<<i<<endl;
  }
  return 0;
}

