added M.id argument rather than rownames(M) + allow X argument