#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int (i)=(0);(i)<(int)(n);++(i))
using ll = long long;
//using P = pair<int, int>;
using namespace std;

// 連結グラフGにおいて，頂点uと，uから出ているすべてのエッジを削除して得られる部分グラフが非連結になるとき，頂点uを関節点（切断点）という

const int MAX = 101010;
vector<int> G[MAX];
int N;
bool visited[MAX];
int prenum[MAX], parent[MAX], lowest[MAX], timer;

void dfs(int current, int prev) {
    prenum[current] = lowest[current] = timer;
    timer++;

    visited[current] = true;

    for (int next : G[current]) {
        if (!visited[next]) {
            parent[next] = current;
            dfs(next, current);
            lowest[current] = min(lowest[current], lowest[next]);
        }
        else if (next != prev) {
            lowest[current] = min(lowest[current], prenum[next]);
        }
    }

    // ノードcurrentの探索が終了した直後の処理
}

void art_points() {
    for (int i = 0; i < N; ++i) visited[i] = false;
    timer = 1;
    dfs(0, -1); // 0 == root

    set<int> ap;
    int np = 0;
    for (int i=1; i<N; ++i) {
        int p = parent[i];
        if (p == 0) np++;
        else if (prenum[p] <= lowest[i]) ap.insert(p);
    }
    if (np > 1) ap.insert(0);
    for (auto tmp : ap) {
        cout << tmp << endl;
    }
}

int main() {
    int m;
    cin >> N >> m;
    rep(i, m) {
        int s, t;
        cin >> s >> t;
        G[s].push_back(t);
        G[t].push_back(s);
    }
    art_points();
    return 0;
}

