class_docstr: The Prufer correspondence is an algorithm that describes the
  bijection between labeled trees and the Prufer code. A Prufer
  code of a labeled tree is unique up to isomorphism and has
  a length of n - 2.
  
  Prufer sequences were first used by Heinz Prufer to give a
  proof of Cayley's formula.
  
  References
  ==========
  
  .. [1] https://mathworld.wolfram.com/LabeledTree.html
class_docstr_tok: ["The","Prufer","correspondence","is","an","algorithm","that","describes","the","bijection","between","labeled","trees","and","the","Prufer","code",".","A","Prufer","code","of","a","labeled","tree","is","unique","up","to","isomorphism","and","has","a","length","of","n","-","2",".","Prufer","sequences","were","first","used","by","Heinz","Prufer","to","give","a","proof","of","Cayley","'s","formula",".","References","==========","..","[","1","]","https",":","\/\/mathworld.wolfram.com\/LabeledTree.html"]
docstr: Return a list of edges and the number of nodes from the given runs
  that connect nodes in an integer-labelled tree.
  
  All node numbers will be shifted so that the minimum node is 0. It is
  not a problem if edges are repeated in the runs; only unique edges are
  returned. There is no assumption made about what the range of the node
  labels should be, but all nodes from the smallest through the largest
  must be present.
  
  Examples
  ========
  
  >>> from sympy.combinatorics.prufer import Prufer
  >>> Prufer.edges([1, 2, 3], [2, 4, 5]) # a T
  ([[0, 1], [1, 2], [1, 3], [3, 4]], 5)
  
  Duplicate edges are removed:
  
  >>> Prufer.edges([0, 1, 2, 3], [1, 4, 5], [1, 4, 6]) # a K
  ([[0, 1], [1, 2], [1, 4], [2, 3], [4, 5], [4, 6]], 7)
docstr_tok: ["Return","a","list","of","edges","and","the","number","of","nodes","from","the","given","runs","that","connect","nodes","in","an","integer-labelled","tree",".","All","node","numbers","will","be","shifted","so","that","the","minimum","node","is","0",".","It","is","not","a","problem","if","edges","are","repeated","in","the","runs",";","only","unique","edges","are","returned",".","There","is","no","assumption","made","about","what","the","range","of","the","node","labels","should","be",",","but","all","nodes","from","the","smallest","through","the","largest","must","be","present",".","Examples","========",">",">",">","from","sympy.combinatorics.prufer","import","Prufer",">",">",">","Prufer.edges","(","[","1",",","2",",","3","]",",","[","2",",","4",",","5","]",")","#","a","T","(","[","[","0",",","1","]",",","[","1",",","2","]",",","[","1",",","3","]",",","[","3",",","4","]","]",",","5",")","Duplicate","edges","are","removed",":",">",">",">","Prufer.edges","(","[","0",",","1",",","2",",","3","]",",","[","1",",","4",",","5","]",",","[","1",",","4",",","6","]",")","#","a","K","(","[","[","0",",","1","]",",","[","1",",","2","]",",","[","1",",","4","]",",","[","2",",","3","]",",","[","4",",","5","]",",","[","4",",","6","]","]",",","7",")"]
code: def edges(*runs):
      """Return a list of edges and the number of nodes from the given runs
      that connect nodes in an integer-labelled tree.
  
      All node numbers will be shifted so that the minimum node is 0. It is
      not a problem if edges are repeated in the runs; only unique edges are
      returned. There is no assumption made about what the range of the node
      labels should be, but all nodes from the smallest through the largest
      must be present.
  
      Examples
      ========
  
      >>> from sympy.combinatorics.prufer import Prufer
      >>> Prufer.edges([1, 2, 3], [2, 4, 5]) # a T
      ([[0, 1], [1, 2], [1, 3], [3, 4]], 5)
  
      Duplicate edges are removed:
  
      >>> Prufer.edges([0, 1, 2, 3], [1, 4, 5], [1, 4, 6]) # a K
      ([[0, 1], [1, 2], [1, 4], [2, 3], [4, 5], [4, 6]], 7)
  
      """
      e = set()
      nmin = runs[0][0]
      for r in runs:
          for i in range(len(r) - 1):
              a, b = r[i : i + 2]
              if b < a:
                  a, b = b, a
              e.add((a, b))
      rv = []
      got = set()
      nmin = nmax = None
      for ei in e:
          for i in ei:
              got.add(i)
          nmin = min(ei[0], nmin) if nmin is not None else ei[0]
          nmax = max(ei[1], nmax) if nmax is not None else ei[1]
          rv.append(list(ei))
      missing = set(range(nmin, nmax + 1)) - got
      if missing:
          missing = [i + nmin for i in missing]
          if len(missing) == 1:
              msg = "Node %s is missing." % missing.pop()
          else:
              msg = "Nodes %s are missing." % sorted(missing)
          raise ValueError(msg)
      if nmin != 0:
          for i, ei in enumerate(rv):
              rv[i] = [n - nmin for n in ei]
          nmax -= nmin
      return sorted(rv), nmax + 1
  
imports: from sympy.core import Basic
  from sympy.core.containers import Tuple
  from sympy.tensor.array import Array
  from sympy.core.sympify import _sympify
  from sympy.utilities.iterables import flatten, iterable
  from sympy.utilities.misc import as_int
  from collections import defaultdict
label_desc: Use image node_id 8 for calling the Prufer obj's underlying member method code with example usage: obj.edges() and returns: sorted,  unknown