You have an incorrect understanding of the meaning of "ref", and you are also mixing up values and variables. These are common mistakes.
Let's go back to basics.
A variable is a storage location which can contain a value.
Let's simplify your program:
int M(int x)
{
x++;
return x;
}
void N()
{
int y = 0;
y = M(y);
}
If N is called, what happens?
Imagine a variable is a drawer that can contain a sheet of paper. We make a drawer and label it y. In y we put a piece of paper that says "0". Now we call M(y). What happens?
We make a new drawer labeled "x" and we make a photocopy of the piece of paper in "y". We put the copy in drawer x. y contains a piece of paper that says 0, and x contains a different piece of paper that also contains 0.
Now in M we increment x. What happens? We make a new piece of paper that says 1, throw away the old one, and put the new one in drawer x.
Now we make a photocopy of the value in x, so we have another piece of paper that says 1. When M returns we put that piece of paper into y and throw away the 0 that is already in there.
Did M modify y? No. M only modified x. N modified y, twice. Once when y was created, and once after M returned.
Notice that we made two copies. First, we made a copy of y on the way in to M and copied it to x, and then we made a copy of x on the way out and copied it to y.
Now suppose we have
void P(ref int b)
{
b++;
}
void Q()
{
int c = 0;
P(ref c);
}
We run Q. What happens? We make a drawer called c and put a piece of paper in it that says "0". What happens when we call P? Something different. This time we make a drawer called b and put a piece of paper in it that says "don't use this drawer! Every time you try to use this drawer, use c instead!" That is, b refers its behaviour to c.
Now P tries to increment b. It tries to get a value out of b, but discovers that b says no, use c. So it looks in c, finds 0, makes a new piece of paper that says 1, replaces the contents of b -- no, wait, we need to replace the contents of c -- with 1, and returns. So c is updated to 1.
Does it make sense why these two things are different? The first is called copy in, copy out because we make a photocopy of y on the way in to M, and a copy of x on the way out. The second is called by reference because b refers its behaviour to c; no values are copied.