public MatchTuple match(Tree<String> a, Tree<String> b) {

        if (!a.getRoot().getLabel().equalsIgnoreCase(b.getRoot().getLabel())) {
            return new MatchTuple(0, a.size(), b.size());
        } else {
            int m = a.getRoot().getChildrenSize();
            int n = b.getRoot().getChildrenSize();

            // start initialize match matrix
            Matrix<Integer> matchMatrix = new Matrix<Integer>(m + 1, n + 1);
            for (int i = 0; i <= m; i++) {
                matchMatrix.setElement(i, 0, 0);
            }
            for (int j = 0; j <= n; j++) {
                matchMatrix.setElement(0, j, 0);
            }
            // end initialization match matrix

            // start W matrix
            Matrix<MatchTuple> wMatrix = new Matrix<MatchTuple>(m, n);

            for (int i = 1; i <= m; i++) {
                for (int j = 1; j <= n; j++) {
                    wMatrix.setElement(
                            i,
                            j,
                            match(new Tree<String>(a.getRoot()
                                    .getChildAt(i - 1)), new Tree<String>(b
                                    .getRoot().getChildAt(j - 1))));
                }
            }
            DetectListTuple detectListTuple = detectLists(wMatrix, a, b);
            wMatrix = detectListTuple.matchTuple();
            //compute scores
            for (int i = 1; i <= m; i++) {
                for (int j = 1; j <= n; j++) {
                    matchMatrix.setElement(i, j, Math.max(Math.max(
                            matchMatrix.getElement(i, j - 1),
                            matchMatrix.getElement(i - 1, j)),
                            matchMatrix.getElement(i - 1, j - 1) + wMatrix.getElement(i, j).score()));
                }
            }
            return new MatchTuple(matchMatrix.getElement(m, n)+1, detectListTuple.nodesA(), detectListTuple.nodesB());
        }
    }