def perm_cycles(p, singletons=False, n=None):
    """
    Return the cycle decomposition of ``p``

    INPUT:

    - ``p`` -- the permutation

    - ``singletons`` -- bool (default: ``False``) - return or not the singletons

    - ``n`` - (optional) only use the first ``n`` elements of the permutation ``p``

    EXAMPLES::

        sage: from surface_dynamics.misc.permutation import perm_cycles, perm_init
        sage: perm_cycles([0,2,1])
        [[1, 2]]
        sage: perm_cycles([0,2,1],True)
        [[0], [1, 2]]

        sage: perm_cycles([2,-1,0])
        [[0, 2]]

        sage: perm_cycles([2,0,1,-1,-1], n=3)
        [[0, 2, 1]]

        sage: perm_cycles([-1,3,-1,1], singletons=True)
        [[1, 3]]

        sage: perm_cycles(perm_init('(1,3)', partial=True))
        [[1, 3]]
    """
    if n is None:
        n = len(p)
    seen = [1] * n
    res = []
    for i in range(n):
        if seen[i] and p[i] != -1:
            cycle = []
            j = i
            while seen[j]:
                seen[j] = 0
                cycle.append(j)
                j = p[j]
            if singletons or len(cycle) > 1:
                res.append(cycle)
    return res
