using System;
using System.Collections.Generic;
using System.Linq;
public class Node
{
public int id;
public Node next;
public int indegree = 0;
public bool visited = false;
}
public class Test
{
public static void Main()
{
// read number of nodes of the graph
int n = Convert.ToInt32(Console.ReadLine());
Node []nodes = new Node[n];
// initiate nodes
for (int i=0;i<n;i++)
nodes[i]=new Node{id = i};
// reading input and initializing indegrees
for (int i=0;i<n;i++)
{
// Each vertex has outgoing edge, so always there is a "next" neighbour
var next = Convert.ToInt32(Console.ReadLine());
nodes[i].next = nodes[next];
nodes[next].indegree++;
}
// Removing vertices of indegree zero recursively.
// The code runs in O(n), in fact, it visits each edge only once, so it
// is O(|E|), but as every vertex has out degree one, |E|=O(|V|).
for (int i=0;i<n;i++)
{
var current = nodes[i];
while (current != null && current.indegree == 0)
{
current.next.indegree--;
var tmp = current.next;
nodes[current.id] = null;
current = tmp;
}
}
// Find All Cycles and Write Them in Console
var cycles = new List<List<int>>();
var count = 0;
for (int i=0;i<n;i++)
{
if (nodes[i]!=null&& !nodes[i].visited)
{
cycles.Add(new List<int>());
var current = nodes[i];
while (!current.visited)
{
cycles[count].Add(current.id);
nodes[current.id].visited = true;
current = current.next;
}
count++;
}
}
// Print cycles and find largest cycle and its length
if (cycles.Count > 0)
{
Console.WriteLine("All cycles:");
for (int i=0;i<cycles.Count;i++)
Console.WriteLine(String.Join(", ", cycles[i]));
int maxLength = cycles.Max(x=>x.Count);
Console.WriteLine("Maximum cycle length is: " + maxLength);
Console.WriteLine("Largest cycle is: " +
String.Join(", ",cycles.FirstOrDefault( x=>x.Count==maxLength)));
}
else
Console.WriteLine("There is no cycle in the graph");
}
}