I don't think you can do this with one pass using grep.
A two-pass grep solution
This solution uses find to pass files in current directory to a while-loop, which in turn does the desired grep'ing:
find . -maxdepth 1 -type f -print0 | while IFS= read -r -d $'\0' file; do
grep -q '/mo' "$file" || grep -l '/fo' "$file"
done
A one-pass GNU awk solution
parse.awk
BEGINFILE { f1 = f2 = 0 }
$0 ~ pat1 { f1 = 1 }
$0 ~ pat2 { f2 = 1 }
ENDFILE { if(f1 && !f2) print FILENAME }
Run it like this:
awk -f parse.awk pat1='/fo' pat2='/mo' *
Explanation
GNU awk has the BEGINFILE and ENDFILE feature which are blocks executed at the beginning and end of an input-file. This enables us to flip flags when the patterns are seen.
The above example sets the two flags, f1 and f2, based on if pat1 and pat2 are found in the current input-file. Thus the ENDFILE block knows if both patterns were present in the current input-file, and can perform the appropriate test.