There are a few things wrong with your code:
You are not handling self loops correctly. Your code simply skips over self-loops (i.e. edges of the form a->a) without removing them from the count (M). Also, the values remain uninitialised meaning that when cycle()
accesses the edge the node IDs may not exist (out of bounds access). So for the simple case 2 1 2 2 your program fails.
On my system it causes runtime error for the case
5 4
1 2
2 3
3 4
4 1
The union find implementation is not efficient. In particular, your find function should update the parent of the current element to be equal to the element retrieved from the recursive call, i.e. par[v] = findP(par, par[v]). Also, union does not take into account the rank of the element. Wikipedia has a detailed explanation of the correct operations.
Extra suggestion: Code containing mallocs is usually hard to maintain (and forgetting to use the free command leads to memory leaks). I would suggest using C++ vector
class for maintaining dynamic arrays (which might be only slightly slower).