Problem:
Problem H: いけるかな？

あるところに，日本各地をまわりながら商売をする社長がいた．
彼はある日，不思議な切符を手に入れた．
その切符を使うと，なんと目的地までの距離によらず電車の運賃が無料になるという．
ただし，
現在の駅から隣接する駅へ移動するのを1ステップと数えたときに，
移動するステップ数がちょうど切符に書かれた数と等しくならないと
追加料金を取られてしまう．
ある区間をただちに折り返すような移動は禁止されているが，
既に訪れた駅や区間を複数回通ること自体は許される．
たとえば，駅1・駅2・駅1と移動することはできないが，
駅1・駅2・駅3・駅1・駅2のような移動は問題ない．
また，最終的に目的地に到着するならば，出発地や目的地も何度でも通ってよい．

社長はさっそくこの切符を次の目的地に行くために使ってみようと考えた．
しかし路線図は入り組んでいるため，簡単には経路が定まらない．
あなたの仕事は，社長に代わって目的地に無料で到達できるかどうかを
判定するプログラムを書くことである．

駅は 1 から N までの番号が振られており，
出発地の駅は 1，目的地の駅は N と決まっている．
路線図は2つの駅を結ぶ区間の列によって与えられる．
区間はどちらの方向にも通行することができる．
同じ駅同士を結ぶような区間は存在しないことと，
ある駅の対を結ぶ区間はたかだか1つであることが保証されている．

Input

入力は複数のデータセットからなる．

それぞれのデータセットは次のような形式で与えられる．

N M Z

s1 d1

s2 d2

...

sM dM

N は駅の総数，M は区間の総数であり，
Z は切符に書かれたステップ数である．
si と
di (1 ≤ i ≤ M)
は駅の番号を表す整数であり，
それぞれ駅 si
と駅 di
の間に区間が存在することを表現している．

N, M, Z
は正の整数であり，次の条件を満たす：
2 ≤ N ≤ 50,
1 ≤ M ≤ 50,
0 < Z < 231．

最後のデータセットの後ろに， “0 0 0” と書かれた1行がある．

データセットの数は30を越えない．

Output

それぞれのデータセットに対し，
チケットに書かれているステップ数ちょうどで
目的地に到達できるならば “yes”，
到達できないならば “no”
のみを含む1行の文字列を出力せよ．

Sample Input

2 1 1
1 2
2 1 2
1 2
3 1 2
1 2
8 8 5778
1 2
2 3
2 4
3 5
5 6
6 7
7 8
4 8
8 8 5777
1 2
2 3
2 4
3 5
5 6
6 7
7 8
4 8
0 0 0

Output for the Sample Input

yes
no
no
yes
no

Solution in C++ (judge verdict: Accepted)

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;

typedef pair<int,int> P;

struct matrix{
	vector< vector<int> > m;
	matrix(){}
	matrix(int h, int w){
		m = vector< vector<int> >(h, vector<int>(w));
		for(int y=0 ; y < h ; y++ )
			for(int x=0 ; x < w ; x++ )
				m[y][x] = 0;
	}
};
matrix operator*(const matrix& a, const matrix& b){
	int h1 = a.m.size(), w1 = a.m[0].size(), h2 = b.m.size(), w2 = b.m[0].size();
	if( w1 != h2 || h1 != w2 ) return matrix();
	
	matrix c(h1, w1);
	for(int i=0 ; i < h1 ; i++ ){
		for(int j=0 ; j < w2 ; j++ ){
			int e = 0;
			for(int k=0 ; k < w1 ; k++ ){
				e += a.m[i][k] * b.m[k][j];
			}
			c.m[i][j] = e;
		}
	}
	return c;
}

matrix get_identify(int n){
	matrix res(n,n);
	for(int i=0 ; i < n ; i++ ) res.m[i][i] = 1;
	return res;
}

matrix pow(const matrix& A, const int z){
	matrix res = get_identify(A.m[0].size());
	matrix x = A;
	for(int i=z-1 ; i ; i >>= 1 ){
		if( i & 1 ){
			res = res * x;
		}
		x = x * x;
	}
	return res;
}

int n, m, z;
P edge[101];

int main(){
	while( cin >> n >> m >> z , n || m || z ){
		for(int i=0 ; i < m ; i++ ){
			int u, v;
			cin >> u >> v;
			u--, v--;
			edge[2*i + 0] = P(u,v);
			edge[2*i + 1] = P(v,u);
		}
		matrix A(2*m, 2*m);
		for(int i=0 ; i < 2*m ; i++ ){
			for(int j=0 ; j < 2*m ; j++ ){
				if( edge[i].second == edge[j].first && edge[i].first != edge[j].second ){
					A.m[i][j] = 1;
				}
			}
		}
		A = pow(A, z);
		bool after[101] = {false};
		bool result[101] = {false};
		for(int i=0 ; i < 2*m ; i++ ){
			if( edge[i].first == 0 ){
				after[i] = true;
			}
		}
		for(int i=0 ; i < 2*m ; i++ ){
			for(int j=0 ; j < 2*m ; j++ ){
				result[j] |= A.m[i][j] && after[i];
			}
		}
		bool ans = false;
		for(int i=0 ; i < 2*m ; i++ ){
			if( result[i] && edge[i].second == n-1 ){
				ans = true;
			}
		}
		cout << (ans? "yes" : "no") << endl;
	}
}