I've updated my code and I think this updated code will give you more intuition. I've replaced the return statement of "ok" function
return (cows < given_cows)
return (cows >= given_cows)
Now if "ok" function returns true value then, for the current mid value we can put more than or equal number of cows than given number of cows. As current mid can be the answer, we store mid as answer and increase the lower bound to mid+1. Why? Because we're trying to find the largest X for which (cows >= given_cows) condition is true. If "ok" returns false value, upper bound needs to be updated to mid-1. But why adding 1 with answer? I'm sorry to say that I can't explain it. I did it because of sample example.