import java.util.*; class G35 { public static interface Copyable<T>{ T copy(); } public static class Pair< T extends Comparable<? super T> & Copyable<T>, S extends Comparable<? super S> & Copyable<S> > implements Comparable<Pair<T,S>>, Copyable<Pair<T,S>> { public T left; public S right; public Pair( T left, S right ){ this.left = left; this.right = right; } public int compareTo( Pair<T,S> pair ){ int lct = left.compareTo(pair.left); if( lct == 0 ){ return right.compareTo(pair.right); } else { return lct; } } public Pair<T,S> copy(){ return new Pair<T,S>(left.copy(), right.copy()); } public String toString(){ return "(" + left.toString() + " , " + right.toString() + ")"; } public boolean equals(Object o){ if( o!=null && o instanceof Pair ){ Pair<?,?> p = (Pair<?,?>) o; // avoids warning for unchecked cast return left.equals(p.left) && right.equals(p.right); } else return false; } } public static void main( String[] args ){ class A implements Comparable<A>, Copyable<A> { int x; A( int x ){ this.x = x; } public int compareTo( A a ){ return x - a.x; } public A copy(){ return new A(x); } public String toString(){ return "x="+x; } public boolean equals( Object o ){ if( o!=null && o instanceof A ){ return x == ((A)o).x; } else return false; } }; class B extends A { B( int x ){ super(x); } public B copy(){ return new B(x); } // covariant return }; Pair<A,A> paa = new Pair<A,A>(new A(3), new A(5)); //Pair<A,B> pab = new Pair<A,B>(new A(3), new B(5)); } }