def precond_grad_scan(ql, qr, Grad):
    """
    return preconditioned gradient using SCaling-And-Normalization (SCAN) preconditioner
    Suppose Grad has shape (M, N)
    ql: shape (2, M), defines a matrix has the same form as that for input feature normalization
    qr: shape (1, N), defines a diagonal matrix for output feature scaling
    Grad: (matrix) gradient
    """
    preG = ql[0:1].t() * Grad
    preG = preG + ql[1:].t().mm(Grad[-1:])  # Ql*Grad
    preG = preG * (qr * qr)  # Ql*Grad*Qr^T*Qr
    add_last_row = ql[1:].mm(preG)  # use it to modify the last row
    preG = ql[0:1].t() * preG
    preG[-1:] = preG[-1:] + add_last_row

    return preG