#include<bits/stdc++.h>
using namespace std;
using Long = long long;
using Edge = pair<int, int>;
using WeightedGraph = vector<vector<Edge>>;
using UnWeightedGraph = vector< vector<int>>;
template< typename G >
struct SCC {
    // G : Unweighted Graph or Weighted Graph
    // g : SCCを求める対象のグラフ
    const G &g;
    // forward : 順向きの辺
    // backward : 逆向きの辺
    UnWeightedGraph forward, backward;
    // comp[i] : 頂点iが属す強連結成分のindex
    // order : 1回目の順向きdfsの帰りがけ順を格納
    // used : 1回目の順向きdfsで通ったかを記憶
    vector< int > comp, order, used;

    SCC(UnWeightedGraph &g) : g(g), forward(g.size()), backward(g.size()), comp(g.size(), -1), used(g.size()) {
        for(int i = 0; i < g.size(); i++) {
            for(auto& e : g[i]) {
                forward[i].emplace_back((int) e);
                backward[(int) e].emplace_back(i);
            }
        }
    }

    SCC(WeightedGraph &g) : g(g), forward(g.size()), backward(g.size()), comp(g.size(), -1), used(g.size()) {
        for(int i = 0; i < g.size(); i++) {
            for(auto& e : g[i]) {
                forward[i].emplace_back((int) e.first);
                backward[(int) e.first].emplace_back(i);
            }
        }
    }

    void dfs(int idx) {
        if(used[idx]) return;
        used[idx] = true;
        for(int to : forward[idx]) 
            dfs(to);
        // 帰りがけを記憶.
        order.push_back(idx);
    }

    void rdfs(int idx, int cnt) {
        if(comp[idx] != -1) return;
        comp[idx] = cnt;
        for(int to : backward[idx]) rdfs(to, cnt);
    }

    int buildDAG(UnWeightedGraph &t) {
        for(int i = 0; i < forward.size(); i++) 
            dfs(i);
        // 帰りがけの遅かった頂点から探索
        reverse(begin(order), end(order));
        int ptr = 0;
        for(int i : order) {
            if(comp[i] == -1) {
                // 強連結ごとに逆向きdfsが停止.
                rdfs(i, ptr);
                ptr++;
            }
        }
        // DAG構築
        t.resize(ptr);
        for(int i = 0; i < g.size(); i++) {
            for(auto &to : g[i]) {
                int x = comp[i], y = comp[to];
                if(x == y) continue;
                t[x].push_back(y);
            }
        }
        return ptr;
    }

    int build() {
        for(int i = 0; i < forward.size(); i++) 
            dfs(i);
        // 帰りがけの遅かった頂点から探索
        reverse(begin(order), end(order));
        int ptr = 0;
        for(int i : order) {
            if(comp[i] == -1) {
                // 強連結ごとに逆向きdfsが停止.
                rdfs(i, ptr);
                ptr++;
            }
        }
        return ptr;
    }
};
// DAG判定.
// UnWeightedGraph用
bool hasCycleDirected(UnWeightedGraph &g) { 
    SCC<UnWeightedGraph> scc(g);
    return (scc.build() != g.size());
}

// WeightedGraph用
bool hasCycleDirected(WeightedGraph &g) { 
    SCC<WeightedGraph> scc(g);
    return (scc.build() != g.size());
}

// 無効グラフ閉路判定
// UnWeightedGraph用
bool hasCycleUnDirected(UnWeightedGraph &g) {
    stack<pair<int,int>> st;
    vector<int> used(g.size(),0);
    for (int i = 0; i < g.size();i++) {
        if (! used[i]) {
            st.emplace(i, -1);
            while (!st.empty()) {
                auto e = st.top();
                st.pop();
                for (auto &next: g[e.first]) {
                    if (next == e.second) continue;
                    if (used[next]) {
                        return true;
                    }
                    used[next] = true;
                    st.emplace(next, i);
                }
            }
        }
    }
    return false;
}

bool hasCycleUnDirected(WeightedGraph &g) {
    stack<pair<int,int>> st;
    vector<int> used(g.size(),0);
    for (int i = 0; i < g.size();i++) {
        if (! used[i]) {
            st.emplace(i, -1);
            while (!st.empty()) {
                auto e = st.top();
                st.pop();
                for (auto &next: g[e.first]) {
                    if (next.first == e.second) continue;
                    if (used[next.first]) {
                        return true;
                    }
                    used[next.first] = true;
                    st.emplace(next.first, i);
                }
            }
        }
    }
    return false;
}

int main(void) {
    int V,E;
    cin >> V >> E;
    UnWeightedGraph g(V);
    for(int i = 0;i < E; i++) {
        int s,t;
        cin >> s >> t;
        g[s].push_back(t);
    }

    cout << hasCycleDirected(g) << endl;
}


Measured memory_bytes: 3192