Optimizing a c# program that creates 2 dictionaries and searches both for a matching value
There are some really obvious optimisations.


Delete all the code relating to b. A dictionary you only insert into is a waste of time, memory, and programmer ability to understand what's going on.
Use g as a dictionary. The way to do that is to change it from a Dictionary&lt;int, BigInteger&gt; into a Dictionary&lt;BigInteger, int&gt;. Then your foreach can be replaced with a simple TryGetValue.
Ditch the cast of j to BigInteger:

int n_int = ((int)Math.Sqrt(247457076132467-1))+1;
... 
n = (BigInteger)n_int


And compare j to n_int. If it doesn't fit in an int, j shouldn't be an int either.
Exploit basic arithmetic properties in loops. E.g. rather than

tm = BigInteger.ModPow(2, i, mod);


you should have

tm = 1,
...
for (int i = 0; i &lt; n_int; i++)
{
    ...
    tm = (tm * 2) % mod;
}



PS In fact, if you'd looked at the Wikipedia page on the algorithm you'd have found pseudocode which handles all this already.