EDIT: This might be a load of old guff given that IndianaBones had 900 000 entries (though that's still a way off from 10 million) but I'll post it anyway
I would suggest using a ds priority as your data structure though, as it can hold names and a value (number of cups), and be ordered for later purposes.
I know that there are limits to the size of data structures, so if 400 000 entries is the limit you'd need more than 20 to store 10 million names. Which would require a fair bit of effort to sort through and order, as you'd have to order them all and then compare the results before ordering those results.
Using ds priorities:
1)Check that the priority exists
2) Check that the priority has any content
3)Check it against the others values (and that they exist, and have content etc)
4) place the lowest, find the new lowest value for that structure, and then repeat the comparisons
Or using strings:
To save on space / effort (?) you could consider putting multiple names and cups into one string, and have them divided by certain characters denoting the end of the name / end of the cup. If 400 000 entries is the limit for a ds map then that's 20 or so pieces of data per key, with the naming of the key not being relevant anymore. It could just be a number.
That's maybe better than 20 ds maps / priorities with a singular piece of data for each key.....??
My guess at doing this would be:
You'd have to parse the string in each key to get the details, place those details into a ds_priority (priority is the number, value is the name) and order it, and then rewrite the string so it's ordered. This would give you the lowest and highest values.
Store that as two variables for each key and have a third variable for what key it is.
That's one loop through the keys. The string for each key is now ordered, and you know the range of values for each key.
Then you'd have to rearrange those strings so that the one with the lowest starting value is first.
Do a second loop through the keys, and as you're parsing through the string you need to be checking the value against what you have for the other keys.
If they're less you can simply insert the parsed bit of text into the beginning of the relevant key. If they're more, but less than the other values, you insert it at the end. Update the value of the two held variables for that key to reflect any changes to lowest / highest number.
If they're inbetween you'd have to read the whole string from the relevant key until you find where to insert them.
I'm not sure how long a string can be for each entry, so maybe you'd have a limit? If you have to enter the data into a position inbetween the beginning and the end of an already "full" line, then you shift the end of that string into the next key with a repeat of beginning / end / inbetween.
To be honest: As I'm typing this I'm thinking "blimey! that sounds like a lot of work" and it no doubt is. But using a long string might be better than more structures with lesser info, and if you did use 20 + data structures (maybe a ds priority instead of a ds map, since it could hold the name and order them by the value) you'd still have to do 20+ comparisons between them each time to then order the end result.
Either way it seems like it won't be easy, though the ds priority way is probably simpler. I'm just not sure which is best: Relative ease of use (ds priority, but maybe has issues with the amount you'd need) OR using strings which is not so easy but maybe doesn't have issues with the means of storage (as it could all be in one structure)