library SafeMath 
{
    function add(uint256 a, uint256 b) internal pure returns (uint256) 
	{
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
		
        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) 
	{
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) 
	{
        require(b <= a, errorMessage);
        uint256 c = a - b;
		
        return c;
    }

	// Gas Optimization
    function mul(uint256 a, uint256 b) internal pure returns (uint256) 
	{
        if (a == 0) 
		{
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) 
	{
        return div(a, b, "SafeMath: division by zero");
    }

    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) 
	{
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    function mod(uint256 a, uint256 b) internal pure returns (uint256) 
	{
        return mod(a, b, "SafeMath: modulo by zero");
    }

    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) 
	{
        require(b != 0, errorMessage);
        return a % b;
    }
    
    function ceil(uint256 a, uint256 m) internal pure returns (uint256) 
	{
		uint256 c = add(a,m);
		uint256 d = sub(c,1);
		return mul(div(d,m),m);
	}
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) 
    if (a == 0) 

        return 0;
    }

    uint256 c = a * b;
    require(c / a == b, "SafeMath: multiplication overflow");

    return c;
}

// Gas Optimization