Trouble rotating objects correctly

I made a script that creates forests on my terrain. I want the trees to angle with the terrain to certain extents, but also have their own random rotation. I am having trouble with actually clamping the rotation, and also having my own.

The picture shows the trees placed on terrain which follow it.
q = Quaternion.FromToRotation(Vector3.up, treeHit.normal).eulerAngles;
gets the angle the trees need to be at fine. (315.8, 343.7, 38.8) is an example.

I can not find a function that lets me change the Y axis (so the object turns with that orange circle) without throwing the other rotations out of whack.
I also can not think of a way to clamp the rotations cleanly. I might want the trees to only angle with the terrain to a maximum of 5 degrees. So a range of 0-5 and 355-360.

Regarding the rotation about the local y axis, you can use Transform.Rotate() with the second argument set to ‘Space.Self’ (which is the default value).

q =  Quaternion.FromToRotation(Vector3.up, treeHit.normal).eulerAngles;
tree[treesMade].transform.Rotate(Vector3.up, Random.Range(0,360), Space.World); 
tree[treesMade].transform.Rotate(Vector3.right,q.x, Space.World); 
tree[treesMade].transform.Rotate(Vector3.forward,q.z, Space.World);

Seems to work. Thanks!

I would still love a clean way to clamp the angles - I could use ifs but when making 50,000~ trees I want the script to be as fast as possible. If I come up with a way I’ll edit the post.

Edit: Also solved.

f =  TreeResource.TreeTypes[tt].clampAngle;
q.x = ClampAngle(q.x, f, 360-f);

//Only useful for angles between 0 and 360.  This function clamps it (if 5, 355) between 0-5  355-360
function ClampAngle(angle : float, min : float, max : float) : float{
	//Angle is between 0 and 360.
	//We need to clamp it between 0-5  and 355-360
	if (angle < max  angle >= 180f){
		angle = max;
	}
	if (angle > min  angle  < 180f){
		angle = min;
	}
	return angle;
}