def approx_min_num_components(nodes, negative_edges):
    import utool as ut
    num = 0
    g_neg = nx.Graph()
    g_neg.add_nodes_from(nodes)
    g_neg.add_edges_from(negative_edges)
    if nx.__version__.startswith('2'):
        deg0_nodes = [n for n, d in g_neg.degree() if d == 0]
    else:
        deg0_nodes = [n for n, d in g_neg.degree_iter() if d == 0]
    for u, v in ut.itertwo(deg0_nodes):
        nx_contracted_nodes(g_neg, v, u, inplace=True)
    unused = list(g_neg.nodes())
    g_pos = nx.complement(g_neg)
    if False:
        from networkx.algorithms.approximation import clique
        maxiset, cliques = clique.clique_removal(g_pos)
        num = len(cliques)
        return num
    while len(unused) > 0:
        num += 1
        idx1 = 0
        n1 = unused[idx1]
        unused.remove(n1)
        neigbs = list(g_pos.neighbors(n1))
        neigbs = ut.isect(neigbs, unused)
        while len(neigbs) > 0:
            idx2 = 0
            n2 = neigbs[idx2]
            unused.remove(n2)
            g_neg = nx.contracted_nodes(g_neg, n1, n2)
            g_pos = nx.complement(g_neg)
            neigbs = list(g_pos.neighbors(n1))
            neigbs = ut.isect(neigbs, unused)
    print('num = %r' % (num,))
    return num