Perhaps we can make this clearer by break it down, step by step.
First, we have person, which is nullable.
Next we call ?.address on that. If person was null, then that evaluates to null immediately; otherwise, it gets the value of the address property, which is an Address object.
Then we call ?.city on the result. The result could be null (if person was null), in which case this evaluates to null too; otherwise, it gets the value of the city property.
Then we call ?.name on the result of that. The result could be null (if person was null), in which case this evaluates to null too; otherwise, it gets the value of the name property.
The final part is a straightforward elvis operator, which checks whether the result of all that is null, and if so substitutes a given string.
All well and good.
But what if you instead dropped the subsequent question marks, to give person?.address.city.country.name ?: “Unknown Country”?
The first parts would work as before: person?.address would evaluate to null if person was null, or to an Address object.
It would then try to access the result’s city field, without any further check. But what if the result was null (because person was null)? It wouldn’t have a city field — accessing a field of a null object is of course impossible! So the compiler doesn’t allow this. (And the same would then apply for the remaining . operators.)
At each stage, the preceding expression could have evaluated to null, and so we need to handle that case (with a ?. or ?: or whatever).