import java.util.Iterator;

enum Unit {
  Value;
}

interface F0<A> {
  public A _();
}

abstract class F1<A, B> {
  public abstract B _(A a);
}

abstract class F2<A, B, C> {
  public abstract C _(A a, B b);
}

abstract class Maybe<A> {
  public static <A> Maybe<A> unit(A value) {
    return Just.of(value);
  }

  public abstract <B> Maybe<B> map(F1<A, B> f);
  public abstract <B> Maybe<B> flatMap(F1<A, Maybe<B>> f);
  public abstract A getOrElse(F0<A> alt);
  public abstract Maybe<A> orElse(Maybe<A> alt);
  public abstract <B> B fold(F1<A, B> f, F0<B> g);
  public abstract Maybe<A> filter(F1<A, Boolean> pred);
}

class Just<A> extends Maybe<A> {
  private final A value;
  
  private Just(A value) {
    this.value = value;
  }

  public static <A> Maybe<A> of(A value) {
    return new Just<A>(value);
  }

  public <B> Maybe<B> map(F1<A, B> f) {
    return new Just<B>(f._(value));
  }

  public <B> Maybe<B> flatMap(F1<A, Maybe<B>> f) {
    return f._(value);
  }
  
  public A getOrElse(F0<A> alt) {
    return value;
  }

  public Maybe<A> orElse(Maybe<A> alt) {
    return this;
  }

  public <B> B fold(F1<A, B> f, F0<B> g) {
    return f._(value);
  }

  public Maybe<A> filter(F1<A, Boolean> pred) {
    if(pred._(value)) {
      return this;
    } else {
      return Nothing.<A>value();
    }
  }

  @Override
  public String toString() {
    return String.format("Just(%s)", value);
  }
}

class Nothing<A> extends Maybe<A> {
  private Nothing() {
  }  

  public static <A> Maybe<A> value() {
    return new Nothing<A>();
  }

  public <B> Maybe<B> map(F1<A, B> f) {
    return new Nothing<B>();
  }

  public <B> Maybe<B> flatMap(F1<A, Maybe<B>> f) {
    return new Nothing<B>();
  }

  public A getOrElse(F0<A> alt) {
    return alt._();
  }

  public Maybe<A> orElse(Maybe<A> alt) {
    return alt;
  }

  public <B> B fold(F1<A, B> f, F0<B> g) {
    return g._();
  }

  public Maybe<A> filter(F1<A, Boolean> pred) {
    return this;
  }
  
  public String toString() {
    return "Nothing";
  }
}