The static keyword makes the storage class of the int x static -- which means that it is essentially a global variable that has its access scoped by the function. In particular, the lifetime of x extends past the execution of the function, and the initializer is only executed once.
When fun() returns the reference to x in Code 1, the reference points to the static storage for x. As a result, the assignment to fun() in main sets the static variable x to 3, which is then returned when fun() is called again on the next line. Since the initializer for x is only executed once, the second call to fun() does not reset the value to 10.
The example in Code 2 is not valid. Returning a reference to a local variable is not valid because the storage for the local variable does not exist after the function returns. While it may appear to work in this case, the result of this code is undefined. Since local variables are generally stored on the stack, for this specific sequence of code, the value in the location that was used for x has not been trashed and the value is set by the initializer in fun(). But this is completely implementation dependent and the compiler specification makes no guarantees about this behavior.
In fact, if the code was a bit more complex that value could have been trashed and you might get some random value printed. Or the code could even crash. In any case don't return references or pointers to local variables as that is not valid code.