Have you assigned the game object which holds the S2 script to the slot of the S1 script in the inspector?
If so, it appears that the execution order of the scripts is just not working as it needs to be for your setup.
I.e. the S1 script is executed first, it tries to get the rb reference from the S2 instance but S2 hasn’t been able to initialize it yet. But, don’t mess around with the execution order now.
In order to fix this, you can do the following (which i strongly recommend for serious projects):
everything that does not rely on variables of other scripts should be done in Awake(), so grab the reference to the rigidbody in your S2 script in Awake. Afterwards, when Start is called, the variable should hold a ready-to-use reference. In Start you can grab the references to all the other stuff.
Get it using GetComponent and then change the variable inside
like
private ScriptName scriptOjb;
public GameObject object;
scriptObj = object.GetComponent();
scriptObj.Variable u want to change this should works