import sys

# Standard Competitive Programming practice for graph limits
sys.setrecursionlimit(2000)

def solve():
    lines = sys.stdin.read().strip().split('\n')
    if not lines: 
        return

    adj = {}
    left_nodes = []

    parsing_edges = False
    for line in lines:
        line = line.strip()
        if not line: continue
        if line.startswith("Edges:"):
            parsing_edges = True
            continue
        
        # Build adjacency list from custom formatting
        if parsing_edges:
            parts = line.replace('→', '->').split('->')
            if len(parts) == 2:
                u = parts[0].strip()
                vs = [v.strip() for v in parts[1].split(',')]
                adj[u] = vs
                if u not in left_nodes:
                    left_nodes.append(u)

    match = {}       # map: right_node -> left_node
    visited = set()  # prevent cycles during path augmentation

    # DFS function to find augmenting paths (Kuhn's Algorithm)
    def dfs(u):
        for v in adj.get(u, []):
            if v in visited:
                continue
            visited.add(v)
            # If the right node is unmatched, OR if its current match can be re-matched
            if v not in match or dfs(match[v]):
                match[v] = u
                return True
        return False

    # Execute Iterative Improvement
    matches = 0
    for u in left_nodes:
        visited.clear()
        if dfs(u):
            matches += 1

    print(f"Maximum Matching Size = {matches}")
    print("Matching:")
    
    # Process sorting to align exactly with sample output expectation
    result_pairs = [(u, v) for v, u in match.items()]
    result_pairs.sort()
    for u, v in result_pairs:
        print(f"{u} - {v}")

if __name__ == "__main__":
    solve()

"""
=== SAMPLE INPUT ===
Left Set (Applicants): A1, A2, A3
Right Set (Jobs): J1, J2, J3
Edges:
A1 → J1, J2
A2 → J1
A3 → J2, J3

=== SAMPLE OUTPUT ===
Maximum Matching Size = 3
Matching:
A1 - J2
A2 - J1
A3 - J3
"""