Problem:
Problem H: Fibonacci Sets

Fibonacci number f(i) appear in a variety of puzzles in nature and math, including packing problems, family trees or Pythagorean triangles. They obey the rule f(i) = f(i - 1) + f(i - 2), where we set f(0) = 1 = f(-1).

Let V and d be two certain positive integers and be N ≡ 1001 a constant. Consider a set of V nodes, each node i having a Fibonacci label F[i] = (f(i) mod N) assigned for i = 1,..., V ≤ N. If |F(i) - F(j)| < d, then the nodes i and j are connected.

Given V and d, how many connected subsets of nodes will you obtain?

Figure 1: There are 4 connected subsets for V = 20 and d = 100.

Input

Each data set is defined as one line with two integers as follows:

Line 1: Number of nodes V and the distance d.

Input includes several data sets (i.e., several lines). The number of dat sets is less than or equal to 50.

Constraints

1 ≤ V ≤ 1000

1 ≤ d ≤ 150

Output

Output line contains one integer - the number of connected subsets - for each input line.

Sample Input

5 5
50 1
13 13

Output for the Sample Input

2
50
8

Solution in JAVA (judge verdict: Wrong Answer)

import java.util.*;
import java.io.*;

class Main {

    public static void main(String[] args) {

	Scanner stdin = new Scanner(System.in);

	while ( stdin.hasNextInt() ) {

	    final int V = stdin.nextInt();
	    final int d = stdin.nextInt();
	    solve( V, d );
	}	
    }

    static void solve( final int V, final int d ) {

	final int[] vs = fibs( V );
	final int[] parents = new int[V];
	final int[] rank = new int[V];
	for ( int i = 0; i < V; i++ ) {
	    parents[i] = i;
	}

	for ( int i = 0; i < V; i++ ) {
	    for ( int j = i + 1; j < V; j++ ) {
		if ( Math.abs( vs[i] - vs[j] ) < d ) {
		    unite( i, j, parents, rank );
		}
	    }
	}
	
	for ( int i = 0; i < V; i++ ) {
	    find( i, parents, rank );
	}
	
	Set<Integer> set = new HashSet<Integer>();
	for ( int i = 0; i < V; i++ ) {
	    if ( !set.contains( find( i, parents, rank ) ) ) {
		set.add( i );
	    }
	}
	System.out.println( set.size() );	
    }

    static int find( final int x, final int[] parents, final int[] rank ) {
	if ( parents[x] == x ) {
	    return x;
	} else {
	    parents[x] = find( parents[x], parents, rank );
	    return parents[x];
	}
    }
    
    static void unite( int x, int y, final int[] parents, final int[] rank ) {
	final int xp = find( x, parents, rank );
	final int yp = find( y, parents, rank );

	if ( xp == yp ) {
	    return;
	}

	if ( rank[xp] < rank[yp] ) {
	    parents[xp] = yp;
	} else {
	    parents[yp] = xp;
	    if ( rank[xp] == rank[yp] ) {
		rank[xp]++;
	    }			
	}
    }

    static boolean same( final int x, final int y, final int[] parents, final int[] rank ) {
	return find( x, parents, rank ) == find( y, parents, rank );
    }

    static int[] fibs( final int V ) {

	if ( V == 1 ) {
	    final int[] ar = {2};
	    return ar;
	} else {
	    final int[] vs = new int[V];
	    vs[0] = 2;
	    vs[1] = 3;
	    for ( int i = 2; i < V; i++ ) {
		vs[i] = ( vs[i - 1] + vs[i - 2] ) % 1001;
	    }
	    return vs;
	}
    }
}