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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class AOJ
{
    static void Main(string[] args)
    {
        int n = 1001;
        decimal[] fib = new decimal[n + 1];
        fib[0] = 1;
        fib[1] = 2;

        for (int i = 0; i < n - 1; i++)
        {
            fib[i + 2] = (fib[i + 1] + fib[i]) % n;
        }
        string str = "";
        while ((str = Console.ReadLine()) != null)
        {
            string[] tmp = str.Split(' ');
            int v = int.Parse(tmp[0]);
            decimal d = decimal.Parse(tmp[1]);
            if (v == 1)
            {
                Console.WriteLine(1);
                continue;
            }
            UnionFind uf = new UnionFind(v + 1);
            for (int i = 1; i <= v; i++)
            {
                for (int j = i + 1; j <= v; j++)
                {
                    if (Math.Abs(fib[i] - fib[j]) < d)
                    {
                        uf.unite(j, i);
                    }
                }
            }
            HashSet<int> set = new HashSet<int>();
            int ans = 0;
            for (int i = 1; i <= v; i++)
            {
                uf.find(i);
                if (set.Contains(uf.par[i])) continue;
                set.Add(uf.par[i]);
                ans++;
            }
            Console.WriteLine(ans);
        }
    }
}
class UnionFind
{
    public int[] par;
    public UnionFind(int n)
    {
        par = new int[n];
        for (int i = 0; i < n; i++)
        {
            par[i] = i;
        }
    }

    public int find(int x)
    {
        if (x == par[x]) return x;
        else return par[x] = find(par[x]);
    }

    public void unite(int x, int y)
    {
        par[find(x)] = find(y);
    }

    public bool same(int x, int y)
    {
        return find(x) == find(y);
    }
}