// Path: src/edu/stanford/nlp/semparse/open/dataset/entity/TargetEntity.java
// public interface TargetEntity {
//   public boolean match(String predictedEntity);
//   public boolean matchAny(Collection<String> predictedEntities);
// }


import java.util.*;
import edu.stanford.nlp.semparse.open.dataset.entity.TargetEntity;
package edu.stanford.nlp.semparse.open.util;



public class BipartiteMatcher {

  private final int SOURCE = 1;
  private final int SINK = -1;
  
  private final Map<Object, Integer> fromMap;
  private final Map<Object, Integer> toMap;
  private final Map<Integer, List<Integer>> edges;

  public BipartiteMatcher() {
    this.fromMap = new HashMap<>();
    this.toMap = new HashMap<>();
    this.edges = new HashMap<>();
  }

// Path: src/edu/stanford/nlp/semparse/open/dataset/entity/TargetEntity.java
// public interface TargetEntity {
//   public boolean match(String predictedEntity);
//   public boolean matchAny(Collection<String> predictedEntities);
// }


// Path: src/edu/stanford/nlp/semparse/open/util/BipartiteMatcher.java
import java.util.*;
import edu.stanford.nlp.semparse.open.dataset.entity.TargetEntity;

package edu.stanford.nlp.semparse.open.util;



public class BipartiteMatcher {

  private final int SOURCE = 1;
  private final int SINK = -1;
  
  private final Map<Object, Integer> fromMap;
  private final Map<Object, Integer> toMap;
  private final Map<Integer, List<Integer>> edges;

  public BipartiteMatcher() {
    this.fromMap = new HashMap<>();
    this.toMap = new HashMap<>();
    this.edges = new HashMap<>();
  }

  public BipartiteMatcher(List<TargetEntity> targetEntities, List<String> predictedEntities) {