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

class Solution {
    int n;
    vector<vector<int>> adjList;
    bool directed = true;
public:
         bool dfs(int v, 
         vector<vector<int>>& adjList,
         vector<bool>& discovered,
         vector<bool>& processed,
         vector<int>& parent)
		{     
		    bool ans = false;
		    discovered[v] = true;
		
		    for(auto x : adjList[v])
		    {
		        if(!discovered[x])
		        {
		            parent[x] = v;  
		            ans |= dfs(x, adjList, discovered, processed, parent);
		        }
		        else if((!processed[x] && parent[v]!=x) || directed)
		        {
		            if(parent[x]!=v)
		            {
		                return true;
		            }
		        }
		    }
		
		    processed[v] = true;
		    return ans;
		}

    bool validTree(int n, vector<vector<int>>& edges) {
        this->n = n;
        adjList.resize(n);
        vector<bool> discovered(n, false);
        vector<bool> processed(n, false);
        vector<int> parent(n, -1);

	    for(auto& x : edges)
        {
            adjList[x[0]].emplace_back(x[1]);
        }
       
		bool ans = false;
        for(int i = 0; i < n; ++i)
        {
            if(!discovered[i])
            {
                ans |= (dfs(i, adjList, discovered, processed, parent));
            	if(ans)
            		return ans;
            }
        }

        return ans;
    }

};


int main() {
	int n = 4;
	vector<vector<int>> edges(n);
	edges[0] = {0,2};
	edges[1] = {3,0};
	edges[2] = {3,1};
	edges[3] = {1,2};
	Solution s;
	cout<<s.validTree(n,edges)<<endl;
	
	return 0;
}
