def greedy_helper_from_graph(G, node_dict, fib_heap, total_degree, weight=None):
    """
    Greedy peeling algorithm. Peel nodes iteratively based on their current degree.

    Parameters
    ----------
    G: undirected, graph (networkx)
    node_dict: dict, node id as key, tuple (neighbor list, heap node) as value. Here heap node is a
    pointer to the corresponding node in fibheap.
    fibheap: FibonacciHeap, support fast extraction of min degree node and value change.
    total_weight: edge weight sum.
    weight: str that specify the edge attribute name of edge weight; None if the graph is unweighted.

    Returns
    ----------
    H: list, subset of nodes corresponding to densest subgraph.
    max_avg: float, density of H induced subgraph.
    new_loads: dict, new loads for nodes, only used for the flowless algorithm when T>1.
    """
    n = G.number_of_nodes()
    avg_degree = total_degree / n
    H = list(G)
    max_avg = avg_degree
    new_loads = dict()

    for i in range(n - 1):
        # find min node from graph (remove from heap)
        to_remove = fib_heap.extract_min()
        node_to_remove = to_remove.value
        degree_to_remove = to_remove.key
        new_loads[node_to_remove] = degree_to_remove

        # for every neighbor node this min node have
        for neighbor in node_dict[node_to_remove][0]:
            edge_w = 1 if weight is None else G[node_to_remove][neighbor][weight]

            # here the key can be actually increased
            if neighbor != node_to_remove:
                fib_heap.decrease_key(node_dict[neighbor][1], node_dict[neighbor][1].key - edge_w)
                node_dict[neighbor][0].remove(node_to_remove)
            total_degree -= edge_w

        del node_dict[node_to_remove]
        avg_degree = total_degree / (n - i - 1)
        if max_avg < avg_degree:
            max_avg = avg_degree
            H = list(node_dict.keys())

    return H, max_avg, new_loads