lowercase_  							=			[
    ["ab-e1", "ac-e3", "ad-e5", "bc-e4", "bd-e2", "be-e6", "bh-e12", "cd-e2", "ce-e4",
     "de-e1", "df-e8", "dg-e5", "dh-e10", "ef-e3", "eg-e2", "fg-e6", "gh-e6", "hi-e3"],
    ["ab-e1", "ac-e3", "ad-e5", "bc-e4", "bd-e2", "be-e6", "cd-e2", "de-e1", "df-e8",
     "ef-e3", "eg-e2", "fg-e6"],
    ["ab-e1", "ac-e3", "bc-e4", "bd-e2", "de-e1", "df-e8", "dg-e5", "ef-e3", "eg-e2",
     "eh-e12", "fg-e6", "fh-e10", "gh-e6"],
    ["ab-e1", "ac-e3", "bc-e4", "bd-e2", "bh-e12", "cd-e2", "df-e8", "dh-e10"],
    ["ab-e1", "ac-e3", "ad-e5", "bc-e4", "bd-e2", "cd-e2", "ce-e4", "de-e1", "df-e8",
     "dg-e5", "ef-e3", "eg-e2", "fg-e6"]
]







def 					__lowerCAmelCase				(		__SCREAMING_SNAKE_CASE       :					Optional[Any]   ):







    '''simple docstring'''
    __snake_case       :				List[Any] 			=    set()
    for row in edge_array:
        for item in row:
            distinct_edge.add(item[0]   )
    return list(__SCREAMING_SNAKE_CASE   )







def 					__lowerCAmelCase				(		__SCREAMING_SNAKE_CASE       :					int		,							__SCREAMING_SNAKE_CASE       :					Union[str, Any]   ):







    '''simple docstring'''
    __snake_case       :				List[str] 			=    ["""0"""] * len(__SCREAMING_SNAKE_CASE   )
    for i, row in enumerate(__SCREAMING_SNAKE_CASE   ):
        for item in row:
            if distinct_edge in item[0]:
                __snake_case       :				Tuple 			=    """1"""
                break
    return "".join(__SCREAMING_SNAKE_CASE   )







def 					__lowerCAmelCase				(		__SCREAMING_SNAKE_CASE       :					List[str]   ):







    '''simple docstring'''
    __snake_case       :				Optional[Any] 			=    get_distinct_edge(__SCREAMING_SNAKE_CASE   )
    __snake_case       :				str 			=    {}

    for item in distinct_edge:
        __snake_case       :				List[Any] 			=    get_bitcode(__SCREAMING_SNAKE_CASE		,							__SCREAMING_SNAKE_CASE   )
        # print('bit',bit)
        # bt=''.join(bit)
        __snake_case       :				Union[str, Any] 			=    bit.count("""1"""   )
        __snake_case       :				Union[str, Any] 			=    [s, bit]
    # Store [Distinct edge, WT(Bitcode), Bitcode] in descending order
    __snake_case       :				Tuple 			=    [
        [k, v[0], v[1]]
        for k, v in sorted(frequency_table.items()		,							key=lambda __SCREAMING_SNAKE_CASE   : v[1][0]		,							reverse=__SCREAMING_SNAKE_CASE   )
    ]
    return sorted_frequency_table







def 					__lowerCAmelCase				(		__SCREAMING_SNAKE_CASE       :					Dict   ):







    '''simple docstring'''
    __snake_case       :				Tuple 			=    {}
    for _, item in enumerate(__SCREAMING_SNAKE_CASE   ):
        nodes.setdefault(item[2]		,							[]   ).append(item[0]   )
    return nodes







def 					__lowerCAmelCase				(		__SCREAMING_SNAKE_CASE       :					Dict   ):







    '''simple docstring'''
    __snake_case       :				Any 			=    {}
    for key, value in nodes.items():
        __snake_case       :				Any 			=    value
    return cluster







def 					__lowerCAmelCase				(		__SCREAMING_SNAKE_CASE       :					Union[str, Any]   ):







    '''simple docstring'''
    return [i * 1_0_0 / len(__SCREAMING_SNAKE_CASE   ) for i in cluster]







def 					__lowerCAmelCase				(		):







    '''simple docstring'''
    print("""\nNodes\n"""   )
    for key, value in nodes.items():
        print(__SCREAMING_SNAKE_CASE		,							__SCREAMING_SNAKE_CASE   )
    print("""\nSupport\n"""   )
    print(__SCREAMING_SNAKE_CASE   )
    print("""\n Cluster \n"""   )
    for key, value in sorted(cluster.items()		,							reverse=__SCREAMING_SNAKE_CASE   ):
        print(__SCREAMING_SNAKE_CASE		,							__SCREAMING_SNAKE_CASE   )
    print("""\n Graph\n"""   )
    for key, value in graph.items():
        print(__SCREAMING_SNAKE_CASE		,							__SCREAMING_SNAKE_CASE   )
    print("""\n Edge List of Frequent subgraphs \n"""   )
    for edge_list in freq_subgraph_edge_list:
        print(__SCREAMING_SNAKE_CASE   )







def 					__lowerCAmelCase				(		__SCREAMING_SNAKE_CASE       :					Any		,							__SCREAMING_SNAKE_CASE       :					Optional[int]		,							__SCREAMING_SNAKE_CASE       :					Union[str, Any]		,							__SCREAMING_SNAKE_CASE       :					int   ):







    '''simple docstring'''
    for i in cluster[ca]:
        __snake_case       :				str 			=    0
        __snake_case       :				List[Any] 			=    ca + 1
        while ca < max(cluster.keys()   ):
            for j in cluster[ca]:
                if int(__SCREAMING_SNAKE_CASE		,							2   ) & int(__SCREAMING_SNAKE_CASE		,							2   ) == int(__SCREAMING_SNAKE_CASE		,							2   ):
                    if tuple(nodes[i]   ) in graph:
                        graph[tuple(nodes[i]   )].append(nodes[j]   )
                    else:
                        __snake_case       :				Tuple 			=    [nodes[j]]
                    count += 1
            if count == 0:
                __snake_case       :				Any 			=    ca + 1
            else:
                break







def 					__lowerCAmelCase				(		__SCREAMING_SNAKE_CASE       :					Optional[int]		,							__SCREAMING_SNAKE_CASE       :					Tuple   ):







    '''simple docstring'''
    __snake_case       :				str 			=    cluster[max(cluster.keys()   )]
    __snake_case       :				List[str] 			=    """Header"""
    __snake_case       :				int 			=    {}
    for i in x:
        if (["Header"],) in graph:
            graph[(["Header"],)].append(x[i]   )
        else:
            __snake_case       :				Dict 			=    [x[i]]
    for i in x:
        __snake_case       :				Dict 			=    [["""Header"""]]
    __snake_case       :				Tuple 			=    1
    while i < max(__SCREAMING_SNAKE_CASE   ) - 1:
        create_edge(__SCREAMING_SNAKE_CASE		,							__SCREAMING_SNAKE_CASE		,							__SCREAMING_SNAKE_CASE		,							__SCREAMING_SNAKE_CASE   )
        __snake_case       :				Optional[Any] 			=    i + 1
    return graph







def 					__lowerCAmelCase				(		__SCREAMING_SNAKE_CASE       :					Tuple		,							__SCREAMING_SNAKE_CASE       :					int		,							__SCREAMING_SNAKE_CASE       :					str		,							__SCREAMING_SNAKE_CASE       :					Tuple=None   ):







    '''simple docstring'''
    __snake_case       :				Optional[int] 			=    (path or []) + [start]
    if start == end:
        paths.append(__SCREAMING_SNAKE_CASE   )
    for node in graph[start]:
        if tuple(__SCREAMING_SNAKE_CASE   ) not in path:
            my_dfs(__SCREAMING_SNAKE_CASE		,							tuple(__SCREAMING_SNAKE_CASE   )		,							__SCREAMING_SNAKE_CASE		,							__SCREAMING_SNAKE_CASE   )







def 					__lowerCAmelCase				(		__SCREAMING_SNAKE_CASE       :					Dict		,							__SCREAMING_SNAKE_CASE       :					Tuple		,							__SCREAMING_SNAKE_CASE       :					List[str]   ):







    '''simple docstring'''
    __snake_case       :				Any 			=    int(s / 1_0_0 * (len(__SCREAMING_SNAKE_CASE   ) - 1)   )
    for i in cluster[k]:
        my_dfs(__SCREAMING_SNAKE_CASE		,							tuple(cluster[k][i]   )		,							(["""Header"""],)   )







def 					__lowerCAmelCase				(		__SCREAMING_SNAKE_CASE       :					List[Any]   ):







    '''simple docstring'''
    __snake_case       :				List[str] 			=    []
    for edges in paths:
        __snake_case       :				Dict 			=    []
        for j in range(len(__SCREAMING_SNAKE_CASE   ) - 1   ):
            __snake_case       :				Optional[Any] 			=    list(edges[j]   )
            for e in temp:
                __snake_case       :				Union[str, Any] 			=    (e[0], e[1])
                el.append(__SCREAMING_SNAKE_CASE   )
        freq_sub_el.append(__SCREAMING_SNAKE_CASE   )
    return freq_sub_el







def 					__lowerCAmelCase				(		__SCREAMING_SNAKE_CASE       :					List[str]   ):







    '''simple docstring'''
    for i in range(len(__SCREAMING_SNAKE_CASE   )   ):
        for j in range(len(edge_array[i]   )   ):
            __snake_case       :				Dict 			=    edge_array[i][j].split("""-"""   )
            __snake_case       :				Optional[int] 			=    t


if __name__ == "__main__":
     preprocess(edge_array)
     lowercase_  							=			get_frequency_table(edge_array)
     lowercase_  							=			get_nodes(frequency_table)
     lowercase_  							=			get_cluster(nodes)
     lowercase_  							=			get_support(cluster)
     lowercase_  							=			construct_graph(cluster, nodes)
     find_freq_subgraph_given_support(60, cluster, graph)
     lowercase_  							=			[]
     lowercase_  							=			freq_subgraphs_edge_list(paths)
     print_all()




import torch
from torch import autograd







class      SCREAMING_SNAKE_CASE__					(  autograd.Function    ):

       @staticmethod
       def 			snake_case__    (							_lowerCAmelCase					:     Any			,			_lowerCAmelCase					:     torch.tensor			,			_lowerCAmelCase					:     float			,			_lowerCAmelCase					:     bool			):
           __snake_case       :				Optional[int] 			=    inputs.numel()
           __snake_case       :				str 			=    int(0.005 * nb_elems			) + 1
           if sigmoid:
               __snake_case       :				Union[str, Any] 			=    (torch.sigmoid(_lowerCAmelCase			) > threshold).type(inputs.type()			)
           else:
               __snake_case       :				Any 			=    (inputs > threshold).type(inputs.type()			)
           if mask.sum() < nb_min:
               # We limit the pruning so that at least 0.5% (half a percent) of the weights are remaining
               __snake_case       :				Dict 			=    inputs.flatten().kthvalue(max(nb_elems - nb_min			,			1			)			).values
               __snake_case       :				List[str] 			=    (inputs > k_threshold).type(inputs.type()			)
           return mask





       @staticmethod
       def 			snake_case__    (							_lowerCAmelCase					:     str			,			_lowerCAmelCase					:     Tuple			):
           return gradOutput, None, None







class      SCREAMING_SNAKE_CASE__					(  autograd.Function    ):

       @staticmethod
       def 			snake_case__    (							_lowerCAmelCase					:     Optional[int]			,			_lowerCAmelCase					:     torch.tensor			,			_lowerCAmelCase					:     float			):
           __snake_case       :				str 			=    inputs.clone()
           __snake_case			, __snake_case       :				Dict 			=    inputs.flatten().sort(descending=_lowerCAmelCase			)
           __snake_case       :				Optional[Any] 			=    int(threshold * inputs.numel()			)

           # flat_out and mask access the same memory.
           __snake_case       :				Optional[int] 			=    mask.flatten()
           __snake_case       :				Dict 			=    0
           __snake_case       :				Optional[Any] 			=    1
           return mask





       @staticmethod
       def 			snake_case__    (							_lowerCAmelCase					:     Any			,			_lowerCAmelCase					:     Optional[Any]			):
           return gradOutput, None







class      SCREAMING_SNAKE_CASE__					(  __UpperCamelCase    ):

       @staticmethod
       def 			snake_case__    (							_lowerCAmelCase					:     torch.tensor			,			_lowerCAmelCase					:     float			):
           __snake_case       :				List[str] 			=    inputs.clone()
           __snake_case			, __snake_case       :				str 			=    inputs.abs().flatten().sort(descending=_lowerCAmelCase			)
           __snake_case       :				List[Any] 			=    int(threshold * inputs.numel()			)

           # flat_out and mask access the same memory.
           __snake_case       :				List[Any] 			=    mask.flatten()
           __snake_case       :				int 			=    0
           __snake_case       :				Optional[int] 			=    1
           return mask



