Problem:
Problem B : Grid

r × c の2次元グリッド上の２つの座標 (a1,a2) と (b1,b2) が与えられる。
あるマス (e,f) から (e+1,f)、(e-1,f)、(e,f+1)、(e,f-1) のどれかのマスに移動するコストを１とする。
また、(e,c-1) と (e,0)、(r-1,f) と (0,f) の間もコスト１で移動することができる。
この時に１つ目の座標から２つ目の座標へ最短コストで移動できる経路の数を求めよ。

Input

入力は以下のフォーマットで与えられる。

r c a1 a2 b1 b2

入力は以下の制約を満たす

1 ≤ r , c ≤ 1,000

0 ≤ a1 , b1 < r

0 ≤ a2 , b2 < c

Output

答えの値を100,000,007で割った余りを出力せよ。

Sample Input 1

4 4 0 0 3 3

Sample Output 1

2

Sample Input 2

4 4 0 0 1 1

Sample Output 2

2

Sample Input 3

2 3 0 0 1 2

Sample Output 3

4

Sample Input 4

500 500 0 0 200 200

Sample Output 4

34807775

Solution in JAVA (judge verdict: Wrong Answer)

import java.util.*;
import java.io.*;
import static java.lang.Math.*;

class Point {
    
    final int y;
    final int x;

    Point( final int y, final int x ) {
	this.y = y;
	this.x = x;
    }

    @Override public boolean equals( final Object o ) {
	if( ! ( o instanceof Point ) ) {
	    return false;
	}
	final Point p = ( Point )o;
	return x == p.x && y == p.y;
    }

    public int hashCode() {
	return x * 1419418249 + y * 1029418721;
    }

    public String toString() {
	return String.format( "(%d, %d)", y, x );
    }
}

class Main {

    static final int[] dx = { -1, 0, 1, 0 };
    static final int[] dy = { 0, 1, 0, -1 };
    
    public static void main( final String[] args ) {

	final Scanner stdin = new Scanner( System.in );

	final int r = stdin.nextInt();
	final int c = stdin.nextInt();
	final int a1 = stdin.nextInt();
	final int a2 = stdin.nextInt();
	final int b1 = stdin.nextInt();
	final int b2 = stdin.nextInt();

	final long[][] map = new long[ c ][ r ];
	map[ a1 ][ a2 ] = 1L;
	final boolean[][] visited = new boolean[ c ][ r ];
	visited[ a1 ][ a2 ] = true;

	final Set<Point> before = new HashSet<Point>();
	final Point start = new Point( a1, a2 );
	before.add( start );
	final Set<Point> after = new HashSet<Point>();

	boolean success = false;
	
	while ( !success ) {
	    for ( final Point p : before ) {
		for ( int i = 0; i < 4; i++ ) {
		    final int nx = p.x + dx[ i ];
		    final int ny = p.y + dy[ i ];
		    success |= exec( ny, nx, after, map, p, b1, b2, visited );
		}
		success |= exec( p.y, 0, after, map, p, b1, b2, visited );
		success |= exec( p.y, r - 1, after, map, p, b1, b2, visited );
		success |= exec( 0, p.x, after, map, p, b1, b2, visited );
		success |= exec( c - 1, p.x, after, map, p, b1, b2, visited );
	    }
	    before.clear();
	    for ( final Point p : after ) {
		visited[ p.y ][ p.x ] = true;
	    }
	    before.addAll( after );
	    after.clear();
	}
	System.out.println( map[ b1 ][ b2 ] );	
    }

    static void printMap( final long[][] a ) {
	for ( final long[] ar :  a ) {
	    for ( final long val : ar ) {
		System.err.print( val + "," );
	    }
	    System.err.println();
	}
    }

    static boolean exec( final int ny, final int nx, final Set<Point> after,
			 final long[][] map, final Point p,
			 final int b1, final int b2, boolean[][] visited ) {

	final int c = map.length;
	final int r = map[ 0 ].length;
	final Point next = new Point( ny, nx );
	
	if( 0 <= nx && nx < r &&
	    0 <= ny && ny < c && !visited[ ny ][ nx ] ) {
	    
	    map[ ny ][ nx ] += map[ p.y ][ p.x ];
	    map[ ny ][ nx ] %= 100000007L;
	    if ( !after.contains( next ) ) {
		after.add( next );
	    }
	}
	return nx == b1 && ny == b2;
    }    
}