
    ܛ7i%                        d Z ddlmZmZ ddlZddlmZ g dZ ed       ed      ej                  d                      Z
d	 Zej                  d
        Zej                  d        Zej                  d        Z ed       ed       ej                  d      dd                     Z ed       ed       ej                  d      dd                     Zy)z;Functions for computing and verifying matchings in a graph.    )combinationsrepeatN)not_implemented_for)is_matchingis_maximal_matchingis_perfect_matchingmax_weight_matchingmin_weight_matchingmaximal_matching
multigraphdirectedc                     t               }t               }| j                         D ]9  }|\  }}||vs||vs||k7  s|j                  |       |j                  |       ; |S )a  Find a maximal matching in the graph.

    A matching is a subset of edges in which no node occurs more than once.
    A maximal matching cannot add more edges and still be a matching.

    Parameters
    ----------
    G : NetworkX graph
        Undirected graph

    Returns
    -------
    matching : set
        A maximal matching of the graph.

    Examples
    --------
    >>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (2, 4), (3, 5), (4, 5)])
    >>> sorted(nx.maximal_matching(G))
    [(1, 2), (3, 5)]

    Notes
    -----
    The algorithm greedily selects a maximal matching M of the graph G
    (i.e. no superset of M exists). It runs in $O(|E|)$ time.
    )setedgesaddupdateGmatchingnodesedgeuvs         Y/home/rose/Desktop/poly/venv/lib/python3.12/site-packages/networkx/algorithms/matching.pyr   r      s_    < uHEE	 1E>aunaLLLL  O    c                     t               }| j                         D ]@  }|\  }}||f|v s||v r||k(  rt        j                  d|       |j	                  |       B |S )a?  Converts matching dict format to matching set format

    Converts a dictionary representing a matching (as returned by
    :func:`max_weight_matching`) to a set representing a matching (as
    returned by :func:`maximal_matching`).

    In the definition of maximal matching adopted by NetworkX,
    self-loops are not allowed, so the provided dictionary is expected
    to never have any mapping from a key to itself. However, the
    dictionary is expected to have mirrored key/value pairs, for
    example, key ``u`` with value ``v`` and key ``v`` with value ``u``.

    z%Selfloops cannot appear in matchings )r   itemsnxNetworkXErrorr   )r   r   r   r   r   s        r   matching_dict_to_setr    <   sk     EE 1q6U?dem6""%J4&#QRR		$ ! Lr   c                 `   t        |t              rt        |      }t               }|D ]  }t	        |      dk7  rt        j                  d|       |\  }}|| vs|| vrt        j                  d| d      ||k(  r y| j                  ||      s y||v s||v r y|j                  |        y)a  Return True if ``matching`` is a valid matching of ``G``

    A *matching* in a graph is a set of edges in which no two distinct
    edges share a common endpoint. Each node is incident to at most one
    edge in the matching. The edges are said to be independent.

    Parameters
    ----------
    G : NetworkX graph

    matching : dict or set
        A dictionary or set representing a matching. If a dictionary, it
        must have ``matching[u] == v`` and ``matching[v] == u`` for each
        edge ``(u, v)`` in the matching. If a set, it must have elements
        of the form ``(u, v)``, where ``(u, v)`` is an edge in the
        matching.

    Returns
    -------
    bool
        Whether the given set or dictionary represents a valid matching
        in the graph.

    Raises
    ------
    NetworkXError
        If the proposed matching has an edge to a node not in G.
        Or if the matching is not a collection of 2-tuple edges.

    Examples
    --------
    >>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (2, 4), (3, 5), (4, 5)])
    >>> nx.is_maximal_matching(G, {1: 3, 2: 4})  # using dict to represent matching
    True

    >>> nx.is_matching(G, {(1, 3), (2, 4)})  # using set to represent matching
    True

       matching has non-2-tuple edge matching contains edge  with node not in GFT	
isinstancedictr    r   lenr   r   has_edger   r   s         r   r   r   U   s    R (D!'1EEt9>""%CD6#JKK1A:!""%<TFBU#VWW6zz!Q:eT  r   c                    t        |t              rt        |      }t               }t               }|D ]  }t	        |      dk7  rt        j                  d|       |\  }}|| vs|| vrt        j                  d| d      ||k(  r y| j                  ||      s y||v s||v r y|j                  |       |j                  |       |j                  ||f        | j                  D ]  \  }}||f|vs||vs||vs||k7  s y y)ag  Return True if ``matching`` is a maximal matching of ``G``

    A *maximal matching* in a graph is a matching in which adding any
    edge would cause the set to no longer be a valid matching.

    Parameters
    ----------
    G : NetworkX graph

    matching : dict or set
        A dictionary or set representing a matching. If a dictionary, it
        must have ``matching[u] == v`` and ``matching[v] == u`` for each
        edge ``(u, v)`` in the matching. If a set, it must have elements
        of the form ``(u, v)``, where ``(u, v)`` is an edge in the
        matching.

    Returns
    -------
    bool
        Whether the given set or dictionary represents a valid maximal
        matching in the graph.

    Examples
    --------
    >>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (3, 4), (3, 5)])
    >>> nx.is_maximal_matching(G, {(1, 2), (3, 4)})
    True

    r"   r#   r$   r%   FT)r'   r(   r    r   r)   r   r   r*   r   r   r   )r   r   r   r   r   r   r   s          r   r   r      s   > (D!'1EEEEt9>""%CD6#JKK1A:!""%<TFBU#VWW6zz!Q:eT		$		1a& $ 1q6~!5.Q!V	 
 r   c                    t        |t              rt        |      }t               }|D ]  }t	        |      dk7  rt        j                  d|       |\  }}|| vs|| vrt        j                  d| d      ||k(  r y| j                  ||      s y||v s||v r y|j                  |        t	        |      t	        |       k(  S )a  Return True if ``matching`` is a perfect matching for ``G``

    A *perfect matching* in a graph is a matching in which exactly one edge
    is incident upon each vertex.

    Parameters
    ----------
    G : NetworkX graph

    matching : dict or set
        A dictionary or set representing a matching. If a dictionary, it
        must have ``matching[u] == v`` and ``matching[v] == u`` for each
        edge ``(u, v)`` in the matching. If a set, it must have elements
        of the form ``(u, v)``, where ``(u, v)`` is an edge in the
        matching.

    Returns
    -------
    bool
        Whether the given set or dictionary represents a valid perfect
        matching in the graph.

    Examples
    --------
    >>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (2, 4), (3, 5), (4, 5), (4, 6)])
    >>> my_match = {1: 2, 3: 5, 4: 6}
    >>> nx.is_perfect_matching(G, my_match)
    True

    r"   r#   r$   r%   Fr&   r   s         r   r   r      s    @ (D!'1EEt9>""%CD6#JKK1A:!""%<TFBU#VWW6zz!Q:eT  u:Qr   weight)
edge_attrsc                     t        | j                        dk(  rt        | d|      S | j                  |d      }dt        d |D              z   t	        j
                         }fd|D        }|j                  ||       t        |d|      S )	a  Compute a minimum-weight maximum-cardinality matching of `G`.

    The minimum-weight maximum-cardinality matching is the matching
    that has the minimum weight among all maximum-cardinality matchings.

    Use the maximum-weight algorithm with edge weights subtracted
    from the maximum weight of all edges.

    A matching is a subset of edges in which no node occurs more than once.
    The weight of a matching is the sum of the weights of its edges.
    A maximal matching cannot add more edges and still be a matching.
    The cardinality of a matching is the number of matched edges.

    This method replaces the edge weights with 1 plus the maximum edge weight
    minus the original edge weight.

    new_weight = (max_weight + 1) - edge_weight

    then runs :func:`max_weight_matching` with the new weights.
    The max weight matching with these new weights corresponds
    to the min weight matching using the original weights.
    Adding 1 to the max edge weight keeps all edge weights positive
    and as integers if they started as integers.

    Read the documentation of `max_weight_matching` for more information.

    Parameters
    ----------
    G : NetworkX graph
      Undirected graph

    weight: string, optional (default='weight')
       Edge data key corresponding to the edge weight.
       If key not found, uses 1 as weight.

    Returns
    -------
    matching : set
        A minimal weight matching of the graph.

    See Also
    --------
    max_weight_matching
    r   T)maxcardinalityr-      )datadefaultc              3   (   K   | ]
  \  }}}|  y wN ).0_ws      r   	<genexpr>z&min_weight_matching.<locals>.<genexpr>7  s     2'wq!Q's   c              3   6   K   | ]  \  }}}|||z
  f  y wr5   r6   )r7   r   r   r9   
max_weights       r   r:   z&min_weight_matching.<locals>.<genexpr>9  s#     ;71aaJN#7s   r-   )r)   r   r	   maxr   Graphadd_weighted_edges_from)r   r-   G_edgesInvGr   r<   s        @r   r
   r
     s    ` 177|q"1T&IIgg61g-GS2'222J88:D;7;E  v 6tDHHr   c                     !"#$%&'()*  G d d       G fdd      t               $$s
t               S d}d} j                  d      D ]P  \  }}}|j                  d      }||k7  r||kD  r|}|xr( t	        t        |            j                  d	      d   d
v }R i (i &i 't        t        $$            %t        t        $t        d                  "t        t        $$             i t        t        $t        |                  #i !i g ) #fd* %&'()f	d %&'(fd}	  !"%&'()*fd}
 !"%&'(fd} "(fd %&'(fd} !"#$(fd}	 &j                          'j                          j                          !D ]	  }d|_         j                          g )dd $D ]&  }|(vs&j                  %|          |dd       ( d}	 )rk|sh)j                         }&%|      dk(  sJ  j                  |      D ]0  }||k(  r
%|   }%|   }||k(  r||fvr *||      }|dk  rdx||f<   ||f<   ||fv r~&j                  |       |d|       ^&j                  |      dk(  r% |	||      }|ur |
|||        |||       d} n&j                  |      &|   dk(  sJ d&|<   ||f'|<   &j                  |      dk(  r%j                  |       *|    k  s||f|<   &j                  |      j                  |       *|    k  s*||f|<   3 )r|sh|rnqd}dx}x}}sd}t        #j                               } j!                         D ]E  }&j                  %|         j                  |      * *|    }|dk(  s||k  s=|}d}|   }G "D ]b  }"|   	&j                  |      dk(  sj                  |      0 *|    }|r|dz  dk(  sJ |dz  }n|dz  }|dk(  s||k  sZ|}d}|   }d !D ]4  }"|   	&j                  |      dk(  s|dk(  s	!|   |k  s,!|   }d}|}6 |dk(  r)sJ d}t#        dt        #j                                     }$D ]L  }&j                  %|         dk(  r#|xx   |z  cc<   (&j                  %|         dk(  s@#|xx   |z  cc<   N !D ]L  }"|   	&j                  |      dk(  r!|xx   |z  cc<   +&j                  |      dk(  s@!|xx   |z  cc<   N |dk(  rn~|dk(  r2|\  }}&%|      dk(  sJ dx||f<   ||f<   )j%                  |       nE|dk(  r2|\  }}dx||f<   ||f<   &%|      dk(  sJ )j%                  |       n|dk(  r	 ||d       (D ]  }((|      |k(  rJ  |snRt        !j'                               D ]4  }|!vr"|   &j                  |      dk(  s#!|   dk(  s, ||d       6 |r |        t)        (      S )a  Compute a maximum-weighted matching of G.

    A matching is a subset of edges in which no node occurs more than once.
    The weight of a matching is the sum of the weights of its edges.
    A maximal matching cannot add more edges and still be a matching.
    The cardinality of a matching is the number of matched edges.

    Parameters
    ----------
    G : NetworkX graph
      Undirected graph

    maxcardinality: bool, optional (default=False)
       If maxcardinality is True, compute the maximum-cardinality matching
       with maximum weight among all maximum-cardinality matchings.

    weight: string, optional (default='weight')
       Edge data key corresponding to the edge weight.
       If key not found, uses 1 as weight.


    Returns
    -------
    matching : set
        A maximal matching of the graph.

     Examples
    --------
    >>> G = nx.Graph()
    >>> edges = [(1, 2, 6), (1, 3, 2), (2, 3, 1), (2, 4, 7), (3, 5, 9), (4, 5, 3)]
    >>> G.add_weighted_edges_from(edges)
    >>> sorted(nx.max_weight_matching(G))
    [(2, 4), (5, 3)]

    Notes
    -----
    If G has edges with weight attributes the edge data are used as
    weight values else the weights are assumed to be 1.

    This function takes time O(number_of_nodes ** 3).

    If all edge weights are integers, the algorithm uses only integer
    computations.  If floating point weights are used, the algorithm
    could return a slightly suboptimal matching due to numeric
    precision errors.

    This method is based on the "blossom" method for finding augmenting
    paths and the "primal-dual" method for finding a matching of maximum
    weight, both methods invented by Jack Edmonds [1]_.

    Bipartite graphs can also be matched using the functions present in
    :mod:`networkx.algorithms.bipartite.matching`.

    References
    ----------
    .. [1] "Efficient Algorithms for Finding Maximum Matching in Graphs",
       Zvi Galil, ACM Computing Surveys, 1986.
    c                       e Zd ZdZy)#max_weight_matching.<locals>.NoNodez-Dummy value which is different from any node.N)__name__
__module____qualname____doc__r6   r   r   NoNoderE     s    ;r   rJ   c                   $    e Zd ZdZg dZ fdZy)$max_weight_matching.<locals>.Blossomz7Representation of a non-trivial blossom or sub-blossom.)childsr   mybestedgesc              3      K   g | j                   }|r@|j                         }t        |      r|j                  |j                          n| |r?y y wr5   )rM   popr'   extend)selfstacktBlossoms      r   leavesz+max_weight_matching.<locals>.Blossom.leaves  sF     "dkkNEIIKa)LL*G s   AAAN)rF   rG   rH   rI   	__slots__rV   )rU   s   r   rU   rL     s    E6		r   rU   r   Tr2   r1   ')intlongNc                 R    |    |   z   d|    |   j                  d      z  z
  S )Nr"   r1   )get)r   r9   r   dualvarr-   s     r   slackz"max_weight_matching.<locals>.slack  s3    qzGAJ&QqT!W[[-C)CCCr   c                 h  	 	|    }
j                  |       
j                  |      J |x
| <   
|<   ||| fx| <   |<   n
d x| <   |<   d x| <   |<   |dk(  r>t        |      r j                  |j                                y j	                  |       y |dk(  r|   } |   d|       y y )Nr1   r"   )r]   r'   rQ   rV   append)r9   rT   r   bbaserU   assignLabelbestedgeblossombase	inblossomlabel	labeledgematequeues        r   rd   z(max_weight_matching.<locals>.assignLabel  s    aLyy|#		!(<<<a58=+,a&0IaL9Q<*..IaL9Q<$((hqk6!W%QXXZ(Q!V q>DT
At, r   c                 6   g }}| ur|    }|   dz  r|   }np|   dk(  sJ |j                  |       d|<   	|   |   
vsJ } n2	|   d   
|      k(  sJ 	|   d   } |    }|   dk(  sJ 	|   d   } |ur|| }} | ur|D ]  }d|<   	 |S )N   r1      r   r"   )ra   )r   r9   pathrc   rb   rJ   rf   rg   rh   ri   rj   s        r   scanBlossomz(max_weight_matching.<locals>.scanBlossom  s    vo!AQx!|"1~8q= =KKNE!H|#"1~T111 |A${1~*>>>>aLOaLQx1}$}aLO!1/ vo2 AE!H  r   c                    |    }|   }|   }        }| |<   d |<   ||<   g x|_         }||fgx|_        }||k7  r`||<   |j                  |       |j                  |          |   dk(  s|   dk(  r|   d   |      k(  sJ |   d   }|   }||k7  r`|j                  |       |j                          |j                          ||k7  rk||<   |j                  |       |j                  |   d   |   d   f       |   dk(  s|   dk(  r|   d   |      k(  sJ |   d   }|   }||k7  rk|   dk(  sJ d|<   |   |<   d|<   |j	                         D ]#  }|      dk(  rj                  |       ||<   % i }	|D ]  }t        |      r^|j                  |j                  }
d |_        nd|j	                         D cg c]"  }j                  |      D ]  }||k7  s	||f $ }
}}n&j                  |      D cg c]  }||k7  s	||f }
}|
D ]O  }|\  }}|   |k(  r||}}|   }||k7  sj                  |      dk(  s4||	vs ||       |	|    k  sK||	|<   Q d |<    t        |	j                               |_        d }d |<   |j                  D ]  } | }||k  s|}|} ||<   y c c}}w c c}w )Nr"   r1   r   )rM   r   ra   reverserV   r'   rN   	neighborsr]   listvalues)rc   r   r9   bbbvbwrb   ro   edgs
bestedgetonblistkijbj
mybestedgekslackmybestslackrU   r   re   rf   blossomdualblossomparentrg   rh   ri   rj   rk   r_   s                     r   
addBlossomz'max_weight_matching.<locals>.addBlossom?  s   t_q\q\IAab4a&!$Bh !M"KKOKK	"&9>b	Q9R=#3tKO7L#L  "a A1B Bh 	BBh !M"KKOKK2q)9R=+;<=9>b	Q9R=#3tKO7L#L  "a A1B Bh RyA~~a }	!AAYq\"a' QIaL  
B"g&>>-^^F%)BN
 )+		(31Q[[^qTUvA^   ,-;;r?F?abAg2q'?FAQ<1$aqAq\!G		"*J.5A;
SUAW3W%&JrN   HRL7 8 Z..01
AAYF!Vk%9
$	 
 !7 Gs   K9K
K#Kc                     	
fd} || |      g}|r9|d   }|D ]  }|j                   |||              n |j                          |r8y y )Nc              3   8  K   | j                   D ]B  }d |<   t        |      r*|r|   dk(  r| #|j                         D ]  }||<   	 >||<   D |sj                  |       dk(  r|    d      }| j                   j	                  |      }|dz  r|t        | j                         z  }d}nd}|    \  }}|dk7  r|dk(  r| j                  |   \  }}	n| j                  |dz
     \  }	}d |<   d |	<    |d|       dx||	f<   |	|f<   ||z  }|dk(  r| j                  |   \  }}n| j                  |dz
     \  }}dx||f<   ||f<   ||z  }|dk7  r| j                   |   }
dx|<   |
<   ||fx|<   |
<   d |
<   ||z  }| j                   |   |k7  r| j                   |   }j                  |      dk(  r||z  };t        |      r)|j                         D ]  }j                  |      s n n|}j                  |      r4|   dk(  sJ |   |k(  sJ d |<   d |      <    |d|   d          ||z  }| j                   |   |k7  rj                  | d        j                  | d        j                  | d        | = | = | = y w)Nr   r"   r1   T)rM   r'   rV   r]   indexr)   r   rP   )rb   endstagesr   
entrychildr~   jstepr9   pqrx   rw   rU   	allowedgerd   re   rf   r   r   rg   rh   ri   rj   s               r   _recursez<max_weight_matching.<locals>.expandBlossom.<locals>._recurse  s    XX#'a a)KNa$7!"A+,IaL ", $%IaL  %))A,!"3 'y|A7
HHNN:.q5QXX&AE E |11fz wwqz1 wwq1u~1#E!H#E!H1a(<@@Iq!f%	1a&(9JAz wwqz1 wwq1u~1<@@Iq!f%	1a&(9JA% 1f* XXa['((a59011v5	!y}#U
hhqkZ/ !Byy}) U
 !"g.!#A$yy| % "-  yy|$Qx1},}(|r111#'a7;d;r?34#Aq)A,q/:JA1 hhqkZ/4 IIaMM!T"LLD!a AAs   EJBJ7A"JA Jr   ra   rP   )rb   r   r   rS   topr   rU   r   rd   re   rf   r   r   rg   rh   ri   rj   s         r   expandBlossomz*max_weight_matching.<locals>.expandBlossom  s]    [	 [	D !X&')CXa23  		 r   c                     	fd} || |      g}|r5|d   }|D ]  }|j                   ||         n |j                          |r4y y )Nc              3     K   |}
|   | k7  r
|   }
|   | k7  rt        |      r||f | j                  j                  |      x}}|dz  r|t        | j                        z  }d}nd}|dk7  r||z  }| j                  |   }|dk(  r| j                  |   \  }}n| j                  |dz
     \  }}t        |      r||f ||z  }| j                  |   }t        |      r||f ||<   ||<   |dk7  r| j                  |d  | j                  d | z   | _        | j                  |d  | j                  d | z   | _        	| j                  d      	| <   	|    |k(  sJ y w)Nr1   r   r   )r'   rM   r   r)   r   )rb   r   rT   r}   r~   r   r9   xrU   rf   r   rj   s           r   r   z=max_weight_matching.<locals>.augmentBlossom.<locals>._recurse  s     A"a'!!$  "a' !W%!fHHNN1%%A1uS]" q&U
HHQKA:771:DAq771q5>DAqa)a&LU
HHQKa)a&LQQ# q&& xx|ahhrl2AHggabkAGGBQK/AG(!5KNq>Q&&&s   E#CE#;A(E#r   r   )
rb   r   r   rS   r   argsrU   rf   r   rj   s
         r   augmentBlossomz+max_weight_matching.<locals>.augmentBlossom  sR    )	'` !Q )CXt_-  		 r   c                 J   | |f|| ffD ]  \  }}	 
|   }|   dk(  sJ |   	|   vs|   d   	|      k(  sJ t        |      r	 ||       ||<   |   U|   d   }
|   }|   dk(  sJ |   \  }}	|   |k(  sJ t        |      r	 ||       ||<    y )Nr1   r   r"   )r'   )r   r9   r   r~   bsrT   btrU   r   rf   rg   rh   ri   rj   s          r   augmentMatchingz,max_weight_matching.<locals>.augmentMatchingS  s	   VaV$DAq q\RyA~%~!"-+b/2MbM!$[_(==  b'*"2q)QR=(bM!$q\RyA~%~ }1"2!+++b'*"2q)Q3 	 %r   c                  ,   r%t        dt        j                                      } nd} t        j                               | z   dk\  sJ t              dk(  st        j                               dk\  sJ j	                  d      D ]  \  }}}|j                  d      }||k(  r |   |   z   d|z  z
  }|g}|g}|d       |j                  |d             |d       |d       |j                  |d             |d       |j                          |j                          t        ||      D ]  \  }}	||	k7  r n|d|   z  z  } |dk\  sJ j                  |      |k(  sj                  |      |k(  s|   |k(  r|   |k(  sJ |dk(  rJ  D ]  }
|
v r|
   | z   dk(  rJ  D ]T  }|   dkD  st        |j                        dz  dk(  sJ |j                  dd d   D ]  \  }}|   |k(  r	|   |k(  rJ  V y )Nr   TrX   r1   r"   r   )	r>   minru   r)   r   r]   ra   rr   zip)vdualoffsetr}   r~   dwtr   	iblossoms	jblossomsbir   r   rb   r   r   r   r^   gnodesrj   r0   r-   s               r   verifyOptimumz*max_weight_matching.<locals>.verifyOptimumt  sl    a#gnn&6"7!78KK7>>#${2a777;1$K,>,>,@(AQ(FFF wwDw)GAq!vq!BAv
WQZ'!b&0AII	".:  y}!=>  	".:	".:  y}!=>  	".:i3B8QR(( 4 6M6xx{a488A;!#3Aw!|Q144Avv) *, AI'!*{":a"???  A1~!177|a'1,,,GGADqDMDAq7a<DGqL88 * r   r"   r   g       @   rm   F)rt   r   r   r]   strtypesplitr(   r   r   clearrN   rP   rs   r   ru   r   r>   ra   keysr    )+r   r0   r-   	maxweight
allintegerr}   r~   r   r   rp   r   r   r   r   rb   r   	augmentedr9   rw   rx   r   rc   	deltatypedelta	deltaedgedeltablossomrU   rJ   r   rd   r   re   rf   r   r   r^   r   rg   rh   ri   rj   rk   r_   s+   ```                       @@@@@@@@@@@@@@@@@r   r	   r	   >  sd   X< < 8 !WFu IJ777%1aUU616b9nITSb]%8%8%=a%@O%S
	 & D E I S()I
 VVD\23M s66*+K H 3vvi012G
 K
 I ED
- -2   J\! \!~o oh=B B)9 )9Z  	 	A AM 
 	 a A599Yq\#:#BAq$' 
 	 	IIKYq\*a/// QAAv "1B"1BRx 1vY.!&q!!Q;DHHIq!f-	1a&0A1v* 99R=0 (1a0"YYr]a/ $/q!#4D#61 !+4A 6 !01 5,-	 %"YYq\1
 $)9>1>'(E!H,-q6IaL2!+ $<<+3vxPR|@T7T,-q6HRL1- $<<?2fuhqk?R6R+,a&HQKi ( 	x  I/33E3I "	GNN,- WWY99Yq\*2x||A7Rx{+A B!e) !$%	$,QK	  #!!$,		!) Q3"HQK0F! &
q000"aK"SL B!e) !$%	$,QK	 #$ !!!$,		!)"bKNU,B'NE !I#$L ! B &%~	As7>>#345 99Yq\*a/AJ%'JYYy|,1AJ%'J  ! #+yy|q(#A%/1*#A%/ ! A~a"AYq\*a///8<<	1a&!Iq!f$5Qa"A8<<	1a&!Iq!f$5Yq\*a///QalE2Q Z AQ=A%%%   k&&()A#Q'EIIaLA,=+a.TUBUa&	 *c p %%r   r=   )Fr-   )rI   	itertoolsr   r   networkxr   networkx.utilsr   __all___dispatchabler   r    r   r   r   r
   r	   r6   r   r   <module>r      s   A *  . \"Z $  ! #$N2 9 9x : :z 0  0 f \"Z X&4I ' ! #4In \"Z X&{& ' ! #{&r   