func (g LabeledUndirected) Size() int {
	m2 := 0
	for fr, to := range g.LabeledAdjacencyList {
		m2 += len(to)
		for _, to := range to {
			if to.To == NI(fr) {
				m2++
			}
		}
	}
	return m2 / 2
}
Size returns the number of edges in g.

See also ArcSize and HasLoop.
package graph
func (g LabeledUndirected) Bipartite(n NI) (b bool, c1, c2 Bits, oc []NI) {
	b = true
	var open bool
	var df func(n NI, c1, c2 *Bits)
	df = func(n NI, c1, c2 *Bits) {
		c1.SetBit(n, 1)
		for _, nb := range g.LabeledAdjacencyList[n] {
			if c1.Bit(nb.To) == 1 {
				b = false
				oc = []NI{nb.To, n}
				open = true
				return
			}
			if c2.Bit(nb.To) == 1 {
				continue
			}
			df(nb.To, c2, c1)
			if b {
				continue
			}
			switch {
			case !open:
			case n == oc[0]:
				open = false
			default:
				oc = append(oc, n)
			}
			return
		}
	}
	df(n, &c1, &c2)
	if b {
		return b, c1, c2, nil
	}
	return b, Bits{}, Bits{}, oc
}
func (g LabeledUndirected) BronKerbosch1(emit func([]NI) bool) {
	a := g.LabeledAdjacencyList
	var f func(R, P, X *Bits) bool
	f = func(R, P, X *Bits) bool {
		switch {
		case !P.Zero():
			var r2, p2, x2 Bits
			pf := func(n NI) bool {
				r2.Set(*R)
				r2.SetBit(n, 1)
				p2.Clear()
				x2.Clear()
				for _, to := range a[n] {
					if P.Bit(to.To) == 1 {
						p2.SetBit(to.To, 1)
					}
					if X.Bit(to.To) == 1 {
						x2.SetBit(to.To, 1)
					}
				}
				if !f(&r2, &p2, &x2) {
					return false
				}
				P.SetBit(n, 0)
				X.SetBit(n, 1)
				return true
			}
			if !P.Iterate(pf) {
				return false
			}
		case X.Zero():
			return emit(R.Slice())
		}
		return true
	}
	var R, P, X Bits
	P.SetAll(len(a))
	f(&R, &P, &X)
}
func (g LabeledUndirected) BKPivotMaxDegree(P, X *Bits) (p NI) {
	a := g.LabeledAdjacencyList
	maxDeg := -1
	P.Iterate(func(n NI) bool {  
		if d := len(a[n]); d > maxDeg {
			p = n
			maxDeg = d
		}
		return true
	})
	X.Iterate(func(n NI) bool {  
		if d := len(a[n]); d > maxDeg {
			p = n
			maxDeg = d
		}
		return true
	})
	return
}
func (g LabeledUndirected) BKPivotMinP(P, X *Bits) NI {
	return P.From(0)
}
func (g LabeledUndirected) BronKerbosch2(pivot func(P, X *Bits) NI, emit func([]NI) bool) {
	a := g.LabeledAdjacencyList
	var f func(R, P, X *Bits) bool
	f = func(R, P, X *Bits) bool {
		switch {
		case !P.Zero():
			var r2, p2, x2, pnu Bits
			pnu.Set(*P)
			for _, to := range a[pivot(P, X)] {
				pnu.SetBit(to.To, 0)
			}
			pf := func(n NI) bool {
				r2.Set(*R)
				r2.SetBit(n, 1)
				p2.Clear()
				x2.Clear()
				for _, to := range a[n] {
					if P.Bit(to.To) == 1 {
						p2.SetBit(to.To, 1)
					}
					if X.Bit(to.To) == 1 {
						x2.SetBit(to.To, 1)
					}
				}
				if !f(&r2, &p2, &x2) {
					return false
				}
				P.SetBit(n, 0)
				X.SetBit(n, 1)
				return true
			}
			if !pnu.Iterate(pf) {
				return false
			}
		case X.Zero():
			return emit(R.Slice())
		}
		return true
	}
	var R, P, X Bits
	P.SetAll(len(a))
	f(&R, &P, &X)
}
func (g LabeledUndirected) BronKerbosch3(pivot func(P, X *Bits) NI, emit func([]NI) bool) {
	a := g.LabeledAdjacencyList
	var f func(R, P, X *Bits) bool
	f = func(R, P, X *Bits) bool {
		switch {
		case !P.Zero():
			var r2, p2, x2, pnu Bits
			pnu.Set(*P)
			for _, to := range a[pivot(P, X)] {
				pnu.SetBit(to.To, 0)
			}
			pf := func(n NI) bool {
				r2.Set(*R)
				r2.SetBit(n, 1)
				p2.Clear()
				x2.Clear()
				for _, to := range a[n] {
					if P.Bit(to.To) == 1 {
						p2.SetBit(to.To, 1)
					}
					if X.Bit(to.To) == 1 {
						x2.SetBit(to.To, 1)
					}
				}
				if !f(&r2, &p2, &x2) {
					return false
				}
				P.SetBit(n, 0)
				X.SetBit(n, 1)
				return true
			}
			if !pnu.Iterate(pf) {
				return false
			}
		case X.Zero():
			return emit(R.Slice())
		}
		return true
	}
	var R, P, X Bits
	P.SetAll(len(a))
	_, ord, _ := g.Degeneracy()
	var p2, x2 Bits
	for _, n := range ord {
		R.SetBit(n, 1)
		p2.Clear()
		x2.Clear()
		for _, to := range a[n] {
			if P.Bit(to.To) == 1 {
				p2.SetBit(to.To, 1)
			}
			if X.Bit(to.To) == 1 {
				x2.SetBit(to.To, 1)
			}
		}
		if !f(&R, &p2, &x2) {
			return
		}
		R.SetBit(n, 0)
		P.SetBit(n, 0)
		X.SetBit(n, 1)
	}
}
func (g LabeledUndirected) ConnectedComponentBits() func() (order int, bits Bits) {
	a := g.LabeledAdjacencyList
	var vg Bits   
	var vc *Bits  
	var nc int
	var df func(NI)
	df = func(n NI) {
		vg.SetBit(n, 1)
		vc.SetBit(n, 1)
		nc++
		for _, nb := range a[n] {
			if vg.Bit(nb.To) == 0 {
				df(nb.To)
			}
		}
		return
	}
	var n NI
	return func() (o int, bits Bits) {
		for ; n < NI(len(a)); n++ {
			if vg.Bit(n) == 0 {
				vc = &bits
				nc = 0
				df(n)
				return nc, bits
			}
		}
		return
	}
}
func (g LabeledUndirected) ConnectedComponentLists() func() []NI {
	a := g.LabeledAdjacencyList
	var vg Bits  
	var m []NI   
	var df func(NI)
	df = func(n NI) {
		vg.SetBit(n, 1)
		m = append(m, n)
		for _, nb := range a[n] {
			if vg.Bit(nb.To) == 0 {
				df(nb.To)
			}
		}
		return
	}
	var n NI
	return func() []NI {
		for ; n < NI(len(a)); n++ {
			if vg.Bit(n) == 0 {
				m = nil
				df(n)
				return m
			}
		}
		return nil
	}
}
func (g LabeledUndirected) ConnectedComponentReps() (reps []NI, orders []int) {
	a := g.LabeledAdjacencyList
	var c Bits
	var o int
	var df func(NI)
	df = func(n NI) {
		c.SetBit(n, 1)
		o++
		for _, nb := range a[n] {
			if c.Bit(nb.To) == 0 {
				df(nb.To)
			}
		}
		return
	}
	for n := range a {
		if c.Bit(NI(n)) == 0 {
			reps = append(reps, NI(n))
			o = 0
			df(NI(n))
			orders = append(orders, o)
		}
	}
	return
}
func (g LabeledUndirected) Copy() (c LabeledUndirected, ma int) {
	l, s := g.LabeledAdjacencyList.Copy()
	return LabeledUndirected{l}, s
}
func (g LabeledUndirected) Degeneracy() (k int, ordering []NI, cores []int) {
	a := g.LabeledAdjacencyList
	ordering = make([]NI, len(a))
	var L Bits
	d := make([]int, len(a))
	var D [][]NI
	for v, nb := range a {
		dv := len(nb)
		d[v] = dv
		for len(D) <= dv {
			D = append(D, nil)
		}
		D[dv] = append(D[dv], NI(v))
	}
	for ox := range a {
		i := 0
		for len(D[i]) == 0 {
			i++
		}
		if i > k {
			for len(cores) <= i {
				cores = append(cores, 0)
			}
			cores[k] = ox
			k = i
		}
		Di := D[i]
		last := len(Di) - 1
		v := Di[last]
		ordering[ox] = v
		L.SetBit(v, 1)
		D[i] = Di[:last]
		for _, nb := range a[v] {
			if L.Bit(nb.To) == 1 {
				continue
			}
			dn := d[nb.To]  
			Ddn := D[dn]    
			for wx, w := range Ddn {
				if w == nb.To {
					last := len(Ddn) - 1
					Ddn[wx], Ddn[last] = Ddn[last], Ddn[wx]
					D[dn] = Ddn[:last]
				}
			}
			dn--  
			d[nb.To] = dn
			D[dn] = append(D[dn], nb.To)
		}
	}
	cores[k] = len(ordering)
	return
}
func (g LabeledUndirected) Degree(n NI) int {
	to := g.LabeledAdjacencyList[n]
	d := len(to)  
	for _, to := range to {
		if to.To == n {
			d++  
		}
	}
	return d
}
func (g LabeledUndirected) FromList(root NI) (f FromList, cycle NI) {
	p := make([]PathEnd, len(g.LabeledAdjacencyList))
	for i := range p {
		p[i].From = -1
	}
	ml := 0
	var df func(NI, NI) bool
	df = func(fr, n NI) bool {
		l := p[n].Len + 1
		for _, to := range g.LabeledAdjacencyList[n] {
			if to.To == fr {
				continue
			}
			if p[to.To].Len > 0 {
				cycle = to.To
				return false
			}
			p[to.To] = PathEnd{From: n, Len: l}
			if l > ml {
				ml = l
			}
			if !df(n, to.To) {
				return false
			}
		}
		return true
	}
	p[root].Len = 1
	if !df(-1, root) {
		return
	}
	return FromList{Paths: p, MaxLen: ml}, -1
}
func (g LabeledUndirected) IsConnected() bool {
	a := g.LabeledAdjacencyList
	if len(a) == 0 {
		return true
	}
	var b Bits
	b.SetAll(len(a))
	var df func(NI)
	df = func(n NI) {
		b.SetBit(n, 0)
		for _, to := range a[n] {
			if b.Bit(to.To) == 1 {
				df(to.To)
			}
		}
	}
	df(0)
	return b.Zero()
}
func (g LabeledUndirected) IsTree(root NI) (isTree, allTree bool) {
	a := g.LabeledAdjacencyList
	var v Bits
	v.SetAll(len(a))
	var df func(NI, NI) bool
	df = func(fr, n NI) bool {
		if v.Bit(n) == 0 {
			return false
		}
		v.SetBit(n, 0)
		for _, to := range a[n] {
			if to.To != fr && !df(n, to.To) {
				return false
			}
		}
		return true
	}
	v.SetBit(root, 0)
	for _, to := range a[root] {
		if !df(root, to.To) {
			return false, false
		}
	}
	return true, v.Zero()
}