Problem:
通勤経路

問題

JOIさんが住むカナダのある都市は，南北方向にまっすぐに伸びる w 本の道路と，東西方向にまっすぐに伸びる h 本の道路により，碁盤の目の形に区分けされている．

南北方向の w 本の道路には，西から順に 1, 2, ... , w の番号が付けられている．また，東西方向の h 本の道路には，南から順に 1, 2, ... , h の番号が付けられている．西から i 番目の南北方向の道路と，南から j 番目の東西方向の道路が交わる交差点を (i, j) で表す．

JOIさんは，交差点 (1, 1) の近くに住んでおり，交差点 (w, h) の近くの会社に車で通っている．車は道路に沿ってのみ移動することができる．JOIさんは，通勤時間を短くするため，東または北にのみ向かって移動して通勤している．また，この都市では，交通事故を減らすために，次のような交通規則が設けられている：

交差点を曲がった車は，その直後の交差点で曲がることは出来ない．

すなわち，交差点で曲がったあとに1ブロックだけ進んで再び曲がることは許されない．このとき，JOIさんの通勤経路は何通り考えられるだろうか．

w と h が与えられたとき，JOIさんの通勤経路の個数を 100000 で割った余りを出力するプログラムを作成せよ．

入力

入力は複数のデータセットからなる．各データセットは1行からなり，空白を区切りとして2個の整数 w, h (2 ≤ w ≤ 100， 2 ≤ h ≤ 100) が書かれている．w は南北方向の道路の本数， h は東西方向の道路の本数を表す．

w, h がともに 0 のとき入力の終了を示す.データセットの数は 5 を超えない．

出力

データセットごとに，JOIさんの通勤経路の個数を 100000 で割った余りを1行に出力する．

入出力例

入力例

3 4
15 15
0 0

出力例

5
43688

1つ目の入力例におけるJOIさんの通勤経路 ( 5 通り)

1つ目の入力例において，JOIさんの通勤経路は図のように 5 通り考えられる．したがって，5を出力する．

2つ目の入力例において，JOIさんの通勤経路は 143688 通り考えられる．したがって，143688 を 100000 で割った余りである 43688 を出力する．

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in C# (judge verdict: Accepted)

using System;

public class hello
{
    public const int MOD = 100000;
    public static void Main()
    {
        while (true)
        {
            string[] line = Console.ReadLine().Trim().Split(' ');
            var w = int.Parse(line[0]);
            var h = int.Parse(line[1]);
            if (w == 0 && h == 0) break;
            var dp = new int[w, h, 2, 2];
            for (int i = 0; i < w; i++)
            {
                dp[i, 0, 1, 0] = 1;
                dp[i, 0, 0, 1] = 1;
            }
            for (int i = 0; i < h; i++)
            {
                dp[0, i, 0, 0] = 1;
                dp[0, i, 1, 1] = 1;
            }
            goDP(dp, h, w);
            var ans1 = dp[w - 2, h - 1, 1, 0] + dp[w - 2, h - 1, 1, 1];
            var ans2 = dp[w - 1, h - 2, 0, 0] + dp[w - 1, h - 2, 0, 1];
            var ans = (ans1 + ans2);
            ans %= MOD;
            Console.WriteLine(ans);
        }
    }
    static void goDP(int[,,,] dp, int h, int w)
    {
        for (int i = 1; i < w; i++)
            for (int j = 1; j < h; j++)
            {
                dp[i, j, 0, 0] = dp[i, j - 1, 0, 0] + dp[i, j - 1, 0, 1];
                dp[i, j, 0, 1] = dp[i - 1, j, 1, 0];
                dp[i, j, 1, 0] = dp[i - 1, j, 1, 0] + dp[i - 1, j, 1, 1];
                dp[i, j, 1, 1] = dp[i, j - 1, 0, 0];
                dp[i, j, 0, 0] %= MOD;
                dp[i, j, 0, 1] %= MOD;
                dp[i, j, 1, 0] %= MOD;
                dp[i, j, 1, 1] %= MOD;
            }
    }
}