//PL 2019-10-24: laeuft nicht durch, zu gross
import java.util.Vector;
import java.lang.Integer;
import java.lang.Boolean;

public class mathStrucMatrixOP {
	model; 
	
	innerOp = (o) -> (ms) -> new mathStrucMatrixOP<>(o.apply(model,ms.model));

	public mathStrucMatrixOP(m) {
		model =m;
	}
}

public class MatrixOP extends Vector<Vector<Integer>> {
   
	MatrixOP () {
    }

	MatrixOP(vv) {
    	Integer i;
    	i = 0;
	  while(i < vv.size()) {
//	    	Boolean a = this.add(vv.elementAt(i));
		  this.add(vv.elementAt(i));
		  i=i+1;
	  }
    }

	public mul = (m1, m2) -> {
        var ret = new MatrixOP();
        var i = 0;
        while(i < m1.size()) {
            var v1 = m1.elementAt(i);
            var v2 = new Vector<Integer>();
            var j = 0;
            while(j < v1.size()) {
                var erg = 0;
                var k = 0;
                while(k < v1.size()) {
                    erg = erg + v1.elementAt(k)
                             * m2.elementAt(k).elementAt(j);
                    k++; }
//                v2.addElement(new Integer(erg));
                v2.addElement(erg);
                j++; }
            ret.addElement(v2);
            i++; 
         }
        return ret;
    };
}


class mathStrucUseMatrixOP {

    main() {
		Vector<Vector<Integer>> vv = new Vector<Vector<Integer>>();
		Vector<Integer> v1 = new Vector<Integer>();
		v1.addElement(2);
		v1.addElement(2);
		Vector<Integer> v2 = new Vector<Integer>();
		v2.addElement(3);
		v2.addElement(3);
		vv.addElement(v1);
		vv.addElement(v2);

		MatrixOP m1 = new MatrixOP(vv);
	
		Vector<Vector<Integer>> vv1 = new Vector<Vector<Integer>>();
		Vector<Integer> v3 = new Vector<Integer>();
		v3.addElement(2);
		v3.addElement(2);
		Vector<Integer> v4 = new Vector<Integer>();
		v4.addElement(3);
		v4.addElement(3);
		vv1.addElement(v3);
		vv1.addElement(v4);

		MatrixOP m2 = new MatrixOP(vv1);

		var mms;
		mms = new mathStrucMatrixOP<>(m1);
		var mms2;
		mms2 = new mathStrucMatrixOP<>(m2);
		var mms3;
		mms3 = mms.innerOp.apply(m1.mul).apply(mms2);
		return mms3;
    }
}
