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 C# (judge verdict: Accepted)

using static System.Math;
using System.Linq;
using System.Collections.Generic;
using System;

public class UnionFind
{
    private int[] data;
    public UnionFind(int size)
    {
        data = new int[size];
        for (int i = 0; i < size; i++) data[i] = -1;
    }
    public bool Unite(int x, int y)
    {
        x = Root(x);
        y = Root(y);
        if (x != y)
        {
            if (data[y] < data[x])
            {
                var tmp = y;
                y = x;
                x = tmp;
            }
            data[x] += data[y];
            data[y] = x;
        }
        return x != y;
    }
    public bool IsSameGroup(int x, int y) => Root(x) == Root(y);
    public int Root(int x) => data[x] < 0 ? x : data[x] = Root(data[x]);
    public int getMem(int x) => -data[Root(x)];
}

public class hello
{
    public static int MOD = 1001;
    public static int[] fibo;
    public static void Main()
    {
        fibo = getFibo();
        string line0;
        for (; (line0 = Console.ReadLine()) != null;)
        {
            string[] line = line0.Trim().Split(' ');
            var n = int.Parse(line[0]);
            var d = int.Parse(line[1]);
            getAns(n, d);
        }
    }
    static void getAns(int n, int d)
    {
        var a = new int[n];
        Array.Copy(fibo, a, n);
        Array.Sort(a);
        var uf = new UnionFind(n + 1);
        for (int i = 0; i < n - 1; i++)
            if (Abs(a[i] - a[i + 1]) < d) uf.Unite(i, i + 1);
        var hs = new HashSet<int>();
        for (int i = 0; i < n; i++) hs.Add(uf.Root(i));
        Console.WriteLine(hs.Count());
    }
    static int[] getFibo()
    {
        var pre0 = 1;
        var pre1 = 1;
        var a = new int[1000];
        for (int i = 0; i < 1000; i++)
        {
            a[i] = (pre0 + pre1) % MOD;
            pre0 = pre1;
            pre1 = a[i];
        }
        return a;
    }
}