Problem:
Problem H:
いけるかな？
あるところに，日本各地をまわりながら商売をする社長がいた．
    彼はある日，不思議な切符を手に入れた．
    その切符を使うと，なんと目的地までの距離によらず電車の運賃が無料になるという．
    ただし，
    現在の駅から隣接する駅へ移動するのを1ステップと数えたときに，
    移動するステップ数がちょうど切符に書かれた数と等しくならないと
    追加料金を取られてしまう．
    ある区間をただちに折り返すような移動は禁止されているが，
    既に訪れた駅や区間を複数回通ること自体は許される．
    たとえば，駅1・駅2・駅1と移動することはできないが，
    駅1・駅2・駅3・駅1・駅2のような移動は問題ない．
    また，最終的に目的地に到着するならば，出発地や目的地も何度でも通ってよい．
社長はさっそくこの切符を次の目的地に行くために使ってみようと考えた．
    しかし路線図は入り組んでいるため，簡単には経路が定まらない．
    あなたの仕事は，社長に代わって目的地に無料で到達できるかどうかを
    判定するプログラムを書くことである．
駅は 1 から
N
までの番号が振られており，
    出発地の駅は 1，目的地の駅は
N
と決まっている．
    路線図は2つの駅を結ぶ区間の列によって与えられる．
    区間はどちらの方向にも通行することができる．
    同じ駅同士を結ぶような区間は存在しないことと，
    ある駅の対を結ぶ区間はたかだか1つであることが保証されている．
Input
入力は複数のデータセットからなる．
それぞれのデータセットは次のような形式で与えられる．
N
M
Z
s
1
d
1
s
2
d
2
...
s
M
d
M
N
は駅の総数，
M
は区間の総数であり，
Z
は切符に書かれたステップ数である．
s
i
と
d
i
(1 ≤
i
≤ M)
    は駅の番号を表す整数であり，
    それぞれ駅
s
i
と駅
d
i
の間に区間が存在することを表現している．
N
,
M
,
Z
は正の整数であり，次の条件を満たす：
    2 ≤
N
≤ 50,
    1 ≤
M
≤ 50,
    0 <
Z
< 2
31
．
最後のデータセットの後ろに， “
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

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <valarray>
#include <utility>
using namespace std;

struct Matrix{
    int n;
    valarray<int> a;
    Matrix(int N) : n(N), a(N*N) {a=0;}
    void set(int x, int i, int j){
        a[i*n+j] = x;
    }
    int get(int i, int j){
        return a[i*n+j];
    }
    void show() const{      // このconstがないとpow内でshowを呼べない、ナニコレ
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                cout << a[i*n+j] << " ";
            }
            cout << endl;
        }
    }
};
Matrix multiply(const Matrix& A, const Matrix& B){
    if(A.n != B.n){
        throw invalid_argument("Matrix size mismatch");
    }
    int N = A.n;
    Matrix C(N);
    for(int i=0; i<N; i++){
        for(int j=0; j<N; j++){
            int tmp = (A.a[slice(i*N,N,1)] * B.a[slice(j,N,N)]).sum();
            // 今回は01でよい
            if(tmp >= 1){
                C.a[i*N+j] = 1;
            }else{
                C.a[i*N+j] = 0;
            }
        }
    }
    return C;
}
Matrix pow(const Matrix& A, int p){

    // A.show();
    // cout << p << endl;

    if(p==1){
        return A;
    }
    if(p%2){
        Matrix T = pow(A,p-1);
        return multiply(T,A);
    }else{
        Matrix T = pow(A,p/2);
        return multiply(T,T);
    }
}

// adj[i] = 頂点iに隣接する頂点番号のvector
bool solve(int n, int m, vector<vector<int>> adj, int z){
    vector<pair<int,int>> rev_mapping;    // [もともとの頂点iの拡張後の番号の右端、左端)
    int tmp_idx = 1;
    rev_mapping.push_back(make_pair(-1,0));
    for(int i=1; i<=n; i++){
        rev_mapping.push_back(make_pair(tmp_idx,tmp_idx+adj[i].size()));
        tmp_idx += adj[i].size();
    }
    Matrix C(2*m+1);
    for(int i=1; i<=n; i++){
        int s = rev_mapping[i].first;
        for(int j=0; j<adj[i].size(); j++){
            // 各iの拡張頂点に入ってくる辺を考える
            // j番目の拡張頂点にはadj[i][j]からの辺のみが入ってくる
            // adj[i][j]が分裂している場合、adj[adj[i][j]][l] == i なら入れない
            int t = adj[i][j];
            pair<int,int> sec = rev_mapping[t];
            auto it = find(adj[t].begin(), adj[t].end(), i);
            int idx = distance(adj[t].begin(),it);
            for(int k=sec.first; k<sec.second; k++){
                if(k-sec.first == idx) continue;
                C.set(1,s+j,k);
            }
        }
    }
    // 最初の頂点だけ特別扱い
    for(int j=0; j<adj[1].size(); j++){
        int t = adj[1][j];
        pair<int,int> sec = rev_mapping[t];
        auto it = find(adj[t].begin(), adj[t].end(), 1);
        int idx = distance(adj[t].begin(),it);
        for(int k=sec.first; k<sec.second; k++){
            if(k-sec.first == idx){
                C.set(1,k,0);
            }
        }
    }

    // C.show();
    // cout << endl;

    Matrix D = pow(C,z);

    // D.show();
    // cout << endl;

    bool ans = false;
    for(int i=rev_mapping[n].first; i<rev_mapping[n].second; i++){
        if(D.get(i,0) == 1){
            ans = true;
            break;
        }
    }

    return ans;
}

// 頂点数とedgeから隣接リストを作成(無向)
vector<vector<int>> construct_graph(int n, vector<pair<int,int>> edges){
    vector<vector<int>> adj(n);
    for(int i=0; i<edges.size(); i++){
        adj[edges[i].first].push_back(edges[i].second);
        adj[edges[i].second].push_back(edges[i].first);
    }
    return adj;
}

int main(){
    // test_construct();
    // test_solve();

    int n,m,z;
    while(cin >> n >> m >> z){
        if(n==0){
            break;
        }
        vector<pair<int,int>> edges;
        for(int i=0; i<m; i++){
            int s,d;
            cin >> s >> d;
            edges.push_back(make_pair(s,d));
        }
        vector<vector<int>> adj = construct_graph(n+1,edges);
        bool ans = solve(n,m,adj,z);
        if(ans){
            cout << "yes" << endl;
        }else{
            cout << "no" << endl;
        }
    }
}
accuracy: 1
time_ms: 220
memory_kb: 3568
final_rank: 4

code_snippet: #include <iostream>
#include <vector>
using namespace std;

struct Edge {
    int from, to;
};

vector<vector<bool>> multiply(const vector<vector<bool>>& A, 
                             const vector<vector<bool>>& B) {
    int n = A.size();
    vector<vector<bool>> C(n, vector<bool>(n, false));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n && !C[i][j]; k++) {  // 最適化
                C[i][j] = A[i][k] && B[k][j];
            }
        }
    }
    return C;
}

vector<vector<bool>> matrixPower(vector<vector<bool>> base, long long z) {
    int n = base.size();
    vector<vector<bool>> result(n, vector<bool>(n, false));
    for (int i = 0; i < n; i++) result[i][i] = true;
    
    while (z > 0) {
        if (z & 1) result = multiply(result, base);
        base = multiply(base, base);
        z >>= 1;
    }
    return result;
}

int main() {
    int N, M;
    long long Z;
    while (cin >> N >> M >> Z && N != 0) {
        vector<Edge> edges;
        vector<vector<int>> adj(N+1);
        
        for (int i = 0; i < M; i++) {
            int s, d;
            cin >> s >> d;
            edges.push_back({s, d});
            adj[s].push_back(edges.size()-1);
            edges.push_back({d, s});
            adj[d].push_back(edges.size()-1);
        }
        
        int edgeCount = edges.size();
        vector<vector<bool>> trans(edgeCount, vector<bool>(edgeCount, false));
        
        for (int i = 0; i < edgeCount; i++) {
            int currentStation = edges[i].to;
            for (int nextEdgeIdx : adj[currentStation]) {
                if (edges[i].from != edges[nextEdgeIdx].to) {
                    trans[i][nextEdgeIdx] = true;
                }
            }
        }
        
        vector<vector<bool>> transZ = matrixPower(trans, Z-1);
        
        bool canReach = false;
        for (int i = 0; i < edgeCount && !canReach; i++) {
            if (edges[i].from != 1) continue;
            for (int j = 0; j < edgeCount; j++) {
                if (edges[j].to == N && transZ[i][j]) {
                    canReach = true;
                    break;
                }
            }
        }
        
        cout << (canReach ? "yes" : "no") << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 3384
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;
typedef pair<P ,ll> P3;
typedef pair<P ,P> PP;
const ll MOD = ll(1e9)+7;
const int IINF = INT_MAX;
const ll LLINF = LLONG_MAX;
const int MAX_N = int(1e5 + 5);
const double EPS = 1e-6;
const int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define SORT(v) sort((v).begin(), (v).end())
#define SORTR(v) sort((v).rbegin(), (v).rend())
#define ALL(v) (v).begin(), (v).end()

typedef vector<int> vec;
typedef vector<vec> mat;

int n, m, z;

mat mul(mat &A, mat &B){
    mat C(A.size(), vec(B[0].size()));
    for(int i=0;i<int(A.size());i++){
        for(int k=0;k<int(B.size());k++){
            for(int j=0;j<int(B[0].size());j++){
                C[i][j] = (C[i][j] + A[i][k] * B[k][j]) > 0;
            }
        }
    }
    return C;
}

mat pow(mat A, ll x){
    mat B(A.size(), vec(A.size()));
    for(int i=0;i<int(A.size());i++){
        B[i][i] = 1;
    }
    while(x > 0){
        if(x & 1) B = mul(B,A);
        A = mul(A, A);
        x >>= 1;
    }
    return B;
}

int main() {
    while(cin >> n >> m >> z, n){
        int g[55][55]{};
        for(int i=0;i<m;i++){
            int s, d;
            cin >> s >> d;
            s--; d--;
            g[s][d] = 1;
            g[d][s] = 1;
        }
        mat A(n*n);

        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                for(int k=0;k<n;k++){
                    for(int l=0;l<n;l++){
                        if(j != k && i==l){
                            A[i*n+j].push_back(g[i][k]);
                        }
                        else{
                            A[i*n+j].push_back(0);
                        }
                    }
                }
            }
        }
        vec ls;
        for(int i=n-1;i>=0;i--){
            for(int j=n-1;j>=0;j--){
                if(i==0 && j==0)continue;
                if(g[i][j]==0){
                    A.erase(A.begin()+i*n+j);
                    for(auto &v : A){
                        v.erase(v.begin()+i*n+j);
                    }
                }
                else{
                    ls.push_back(i);
                }
            }
        }
        ls.push_back(0);
        reverse(ls.begin(), ls.end());
        /*
        for(auto v:A){
            for(auto i:v){
                cout << i << " ";
            }
            cout << endl;
        }
        */
        mat ans = pow(A, z);
        bool ok = false;
        for(int i=0;i<int(ans.size());i++){
            if(ls[i]==n-1 && ans[0][i]>0){
                ok = true;
            }
        }

        cout << (ok?"yes":"no") << endl;

    }
    return 0;
}
accuracy: 1
time_ms: 900
memory_kb: 39736
final_rank: 20

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;

const int MOD = 1e9 + 9;

vvi mul(vvi a, vvi b)
{
    vvi c(a.size(), vi(b[0].size()));
    for (int k = 0; k < a[0].size(); k++)
    {
        for (int i = 0; i < a.size(); i++)
        {
            for (int j = 0; j < b[0].size(); j++)
            {
                c[i][j] = (c[i][j] + 1ll * a[i][k] * b[k][j]) % MOD;
            }
        }
    }
    return c;
}

vvi binpow(vvi a, int deg)
{
    if (deg == 0)
    {
        vvi b(a.size(), vi(a.size()));
        for (int i = 0; i < a.size(); i++)
            b[i][i] = 1;
        return b;
    }
    vvi b = binpow(a, deg / 2);
    b = mul(b, b);
    if (deg % 2) b = mul(b, a);
    return b;
}

void solve()
{
    int n, m, q;
    cin >> n >> m >> q;
    if (n == 0) exit(0);

    vi f(2 * m), t(2 * m);
    for (int i = 0; i < m; i++)
    {
        cin >> f[2 * i] >> t[2 * i];
        f[2 * i]--, t[2 * i]--;
        f[2 * i + 1] = t[2 * i];
        t[2 * i + 1] = f[2 * i];
    }
    m *= 2;

    vvi s(1, vi(m));
    for (int i = 0; i < m; i++)
    {
        if (f[i] == 0)
            s[0][i] = 1;
    }

    vvi go(m, vi(m));
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (t[i] == f[j] && f[i] != t[j])
                go[i][j] = 1;
        }
    }

    go = binpow(go, q - 1);
    s = mul(s, go);

    int ok = 0;
    for (int i = 0; i < m; i++)
    {
        if (s[0][i] && t[i] == n - 1)
            ok = 1;
    }
    if (ok) cout << "yes\n";
    else cout << "no\n";
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int t = 2000;
    //cin >> t;
    while (t--)
    {
        solve();
    }
}
accuracy: 1
time_ms: 530
memory_kb: 4776
final_rank: 17

code_snippet: #include <iostream>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;

int N, M, Z;

vector<int> matrix_mul(vector<int> x, vector<int> y, int dim)
{
    vector<int> z(dim * dim, 0);
    for (int i = 0; i < dim; i += 2)
        for (int k = 0; k < dim; ++k)
            for (int j = 0; j < dim; j += 2)
            {
                z[i * dim + j] += y[i * dim + k] * x[k * dim + j];
                z[i * dim + j + 1] += y[i * dim + k] * x[k * dim + j + 1];
                z[(i + 1) * dim + j] += y[(i + 1) * dim + k] * x[k * dim + j];
                z[(i + 1) * dim + j + 1] += y[(i + 1) * dim + k] * x[k * dim + j + 1];
            }
    return z;
}

vector<int> matrix_pow(vector<int> x, int ind, int dim)
{
    if (ind == 1)
        return x;
    else if (ind % 2)
        return matrix_mul(x, matrix_pow(x, ind - 1, dim), dim);
    else
    {
        vector<int> temp = matrix_pow(x, ind / 2, dim);
        return matrix_mul(temp, temp, dim);
    }
}

int main()
{
    while (cin >> N >> M >> Z && N > 0)
    {
        int dim = 2 * M + 2;
        vector<int> edge_adj(dim * dim, 0);

        vector< pair<int, int> > edges(dim - 1);
        edges[0] = make_pair(0, 1);

        int s, d;
        for (int i = 0; i < M; ++i)
        {
            cin >> s >> d;
            edges[2 * i + 1] = make_pair(s, d);
            edges[2 * i + 2] = make_pair(d, s);
        }

        int edges_size = edges.size();
        for (int i = 0; i < edges_size; ++i)
            for (int j = 0; j < edges_size; ++j)
                if (i != j && edges[i].second == edges[j].first && edges[i].first != edges[j].second)
                    edge_adj[i * dim + j] = 1;

        edge_adj = matrix_pow(edge_adj, Z, dim);

        bool ans = false;
        for (int i = 0; i < edges_size; ++i)
        {
            if (edges[i].second == N && edge_adj[i] != 0)
            {
                ans = true;
                break;
            }
        }

        if (ans)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
}
accuracy: 1
time_ms: 200
memory_kb: 5580
final_rank: 5

code_snippet: #include <iostream>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;

int N, M, Z;

vector<int> matrix_mul(vector<int> x, vector<int> y, int dim)
{
    vector<int> z(dim * dim, 0);
    for (int i = 0; i < dim; i += 2)
        for (int k = 0; k < dim; ++k)
            for (int j = 0; j < dim; j += 2)
            {
                z[i * dim + j] += y[i * dim + k] * x[k * dim + j];
                z[i * dim + j + 1] += y[i * dim + k] * x[k * dim + j + 1];
                z[(i + 1) * dim + j] += y[(i + 1) * dim + k] * x[k * dim + j];
                z[(i + 1) * dim + j + 1] += y[(i + 1) * dim + k] * x[k * dim + j + 1];
            }
    return z;
}

vector<int> matrix_pow(vector<int> x, int ind, int dim)
{
    if (ind == 1)
        return x;
    else if (ind % 2)
        return matrix_mul(x, matrix_pow(x, ind - 1, dim), dim);
    else
    {
        vector<int> temp = matrix_pow(x, ind / 2, dim);
        return matrix_mul(temp, temp, dim);
    }
}

int main()
{
    while (cin >> N >> M >> Z && N > 0)
    {
        int dim = 2 * M + 2;
        vector<int> edge_adj(dim * dim, 0);

        vector<pair<int, int>> edges(dim - 1);
        edges[0] = make_pair(0, 1);
        // edges.push_back(make_pair(0, 1));

        int s, d;
        for (int i = 0; i < M; ++i)
        {
            cin >> s >> d;
            edges[2 * i + 1] = make_pair(s, d);
            edges[2 * i + 2] = make_pair(d, s);
            //edges.push_back(make_pair(s, d));
            //edges.push_back(make_pair(d, s));
        }

        int edges_size = edges.size();
        for (int i = 0; i < edges_size; ++i)
            for (int j = 0; j < edges_size; ++j)
                if (i != j && edges[i].second == edges[j].first && edges[i].first != edges[j].second)
                    edge_adj[i * dim + j] = 1;

        edge_adj = matrix_pow(edge_adj, Z, dim);

        bool ans = false;
        for (int i = 0; i < edges_size; ++i)
        {
            if (edges[i].second == N && edge_adj[i] != 0)
            {
                ans = true;
                break;
            }
        }

        if (ans)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
}
accuracy: 1
time_ms: 130
memory_kb: 5664
final_rank: 2

code_snippet: #include <iostream>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;

int N, M, Z;

vector<int> mult(vector<int> x, vector<int> y, int dim)
{
    vector<int> z(dim * dim, 0);
    for (int i = 0; i < dim; i += 2)
        for (int k = 0; k < dim; ++k)
            for (int j = 0; j < dim; j += 2)
            {
                z[i * dim + j] += y[i * dim + k] * x[k * dim + j];
                z[i * dim + j + 1] += y[i * dim + k] * x[k * dim + j + 1];
                z[(i + 1) * dim + j] += y[(i + 1) * dim + k] * x[k * dim + j];
                z[(i + 1) * dim + j + 1] += y[(i + 1) * dim + k] * x[k * dim + j + 1];
            }
    return z;
}

vector<int> pow(vector<int> x, int ind, int dim)
{
    if (ind == 1)
        return x;
    else if (ind % 2)
        return mult(x, pow(x, ind - 1, dim), dim);
    else
    {
        vector<int> temp = pow(x, ind / 2, dim);
        return mult(temp, temp, dim);
    }
}

int main()
{
    while (cin >> N >> M >> Z && N > 0)
    {
        int dim = 2 * M + 2;

        vector<pair<int, int>> edges;
        vector<int> edge_adj(dim * dim, 0);
        edges.push_back(make_pair(0, 1));

        int s, d;
        for (int i = 0; i < M; ++i)
        {
            cin >> s >> d;
            edges.push_back(make_pair(s, d));
            edges.push_back(make_pair(d, s));
        }

        int edges_size = edges.size();
        for (int i = 0; i < edges_size; ++i)
            for (int j = 0; j < edges_size; ++j)
                if (i != j && edges[i].second == edges[j].first && edges[i].first != edges[j].second)
                    edge_adj[i * dim + j] = 1;

        edge_adj = pow(edge_adj, Z, dim);

        bool ans = false;
        for (int i = 0; i < edges_size; ++i)
        {
            if (edges[i].second == N && edge_adj[i] != 0)
            {
                ans = true;
                break;
            }
        }

        if (ans)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
}
accuracy: 1
time_ms: 130
memory_kb: 5740
final_rank: 3

code_snippet: #include <iostream>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;

int N, M, Z;

vector<int> mult(vector<int> x, vector<int> y, int dim)
{
    vector<int> z(dim * dim, 0);
    for (int i = 0; i < dim; i += 2)
        for (int k = 0; k < dim; ++k)
            for (int j = 0; j < dim; j += 2)
            {
                z[i * dim + j] += y[i * dim + k] * x[k * dim + j];
                z[i * dim + j + 1] += y[i * dim + k] * x[k * dim + j + 1];
                z[(i + 1) * dim + j] += y[(i + 1) * dim + k] * x[k * dim + j];
                z[(i + 1) * dim + j + 1] += y[(i + 1) * dim + k] * x[k * dim + j + 1];
            }
    return z;
}

vector<int> pow(vector<int> x, int ind, int dim)
{
    if (ind == 1)
        return x;
    else if (ind % 2)
        return mult(x, pow(x, ind - 1, dim), dim);
    else
    {
        vector<int> temp = pow(x, ind / 2, dim);
        return mult(temp, temp, dim);
    }
}

int main()
{
    while (cin >> N >> M >> Z && N > 0)
    {
        int dim = 2 * M + 2;

        vector< pair<int, int> > edges;
        vector<int> edge_adj(dim * dim, 0);
        edges.push_back(make_pair(0, 1));

        int s, d;
        for (int i = 0; i < M; ++i)
        {
            cin >> s >> d;
            edges.push_back(make_pair(s, d));
            edges.push_back(make_pair(d, s));
        }

        int edges_size = edges.size();
        for (int i = 0; i < edges_size; ++i)
            for (int j = 0; j < edges_size; ++j)
                if (i != j && edges[i].second == edges[j].first && edges[i].first != edges[j].second)
                    edge_adj[i * dim + j] = 1;

        edge_adj = pow(edge_adj, Z, dim);

        bool ans = false;
        for (int i = 0; i < edges_size; ++i)
        {
            if (edges[i].second == N && edge_adj[i] != 0)
            {
                ans = true;
                break;
            }
        }

        if (ans)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
}
accuracy: 1
time_ms: 200
memory_kb: 5592
final_rank: 6

code_snippet: #include <iostream>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;

int N, M, Z;

vector<int> mult(vector<int> x, vector<int> y, int dim)
{
    vector<int> z(dim * dim, 0);
    for (int i = 0; i < dim; i += 2)
        for (int j = 0; j < dim; j += 2)
            for (int k = 0; k < dim; ++k)
            {
                z[i * dim + j] += y[i * dim + k] * x[k * dim + j];
                z[i * dim + j + 1] += y[i * dim + k] * x[k * dim + j + 1];
                z[(i + 1) * dim + j] += y[(i + 1) * dim + k] * x[k * dim + j];
                z[(i + 1) * dim + j + 1] += y[(i + 1) * dim + k] * x[k * dim + j + 1];
            }
    return z;
}

vector<int> pow(vector<int> x, int ind, int dim)
{
    if (ind == 1)
        return x;
    else if (ind % 2)
        return mult(x, pow(x, ind - 1, dim), dim);
    else
    {
        vector<int> temp = pow(x, ind / 2, dim);
        return mult(temp, temp, dim);
    }
}

int main()
{
    while (cin >> N >> M >> Z && N > 0)
    {
        int dim = 2 * M + 2;

        vector< pair<int, int> > edges;
        vector<int> edge_adj(dim * dim, 0);
        edges.push_back(make_pair(0, 1));

        int s, d;
        for (int i = 0; i < M; ++i)
        {
            cin >> s >> d;
            edges.push_back(make_pair(s, d));
            edges.push_back(make_pair(d, s));
        }

        int edges_size = edges.size();
        for (int i = 0; i < edges_size; ++i)
            for (int j = 0; j < edges_size; ++j)
                if (i != j && edges[i].second == edges[j].first && edges[i].first != edges[j].second)
                    edge_adj[i * dim + j] = 1;

        edge_adj = pow(edge_adj, Z, dim);

        bool ans = false;
        for (int i = 0; i < edges_size; ++i)
        {
            if (edges[i].second == N && edge_adj[i] != 0)
            {
                ans = true;
                break;
            }
        }

        if (ans)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
}
accuracy: 1
time_ms: 230
memory_kb: 5524
final_rank: 11

code_snippet: #include <iostream>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;

int N, M, Z;

vector<int> mult(vector<int> lhs, vector<int> rhs, int dim)
{
    vector<int> r(dim * dim, 0);
    for (int i = 0; i < dim; i += 2)
        for (int k = 0; k < dim; ++k)
            for (int j = 0; j < dim; j += 2)
            {
                r[i * dim + j] += rhs[i * dim + k] * lhs[k * dim + j];
                r[i * dim + j + 1] += rhs[i * dim + k] * lhs[k * dim + j + 1];
                r[(i + 1) * dim + j] += rhs[(i + 1) * dim + k] * lhs[k * dim + j];
                r[(i + 1) * dim + j + 1] += rhs[(i + 1) * dim + k] * lhs[k * dim + j + 1];
            }
    return r;
}

vector<int> pow(vector<int> A, int p, int dim)
{
    if (p == 1)
        return A;
    else if (p % 2)
    {
        vector<int> T = pow(A, p - 1, dim);
        return mult(A, T, dim);
    }
    else
    {
        vector<int> T = pow(A, p / 2, dim);
        return mult(T, T, dim);
    }
}

int main()
{
    while (cin >> N >> M >> Z && N > 0)
    {
        int dim = 2 * M + 2;

        vector< pair<int, int> > edges;
        vector<int> edge_adj(dim * dim, 0);
        edges.push_back(make_pair(0, 1));

        int s, d;
        for (int i = 0; i < M; ++i)
        {
            cin >> s >> d;
            edges.push_back(make_pair(s, d));
            edges.push_back(make_pair(d, s));
        }

        int edges_size = edges.size();
        for (int i = 0; i < edges_size; ++i)
        {
            for (int j = 0; j < edges_size; ++j)
            {
                if (i != j && edges[i].second == edges[j].first && edges[i].first != edges[j].second)
                    edge_adj[i * dim + j] = 1;
                else
                    edge_adj[i * dim + j] = 0;
            }
        }

        edge_adj = pow(edge_adj, Z, dim);

        bool ans = false;
        for (int i = 0; i < edges_size; ++i)
        {
            if (edges[i].second == N && edge_adj[i] != 0)
            {
                ans = true;
                break;
            }
        }

        if (ans)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
}
accuracy: 1
time_ms: 210
memory_kb: 5524
final_rank: 8

code_snippet: #include <iostream>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;

int N, M, Z;

vector<int> mult(vector<int> lhs, vector<int> rhs, int dim)
{
    vector<int> r(dim * dim, 0);
    for (int i = 0; i < dim; i += 2)
        for (int k = 0; k < dim; ++k)
            for (int j = 0; j < dim; j += 2)
            {
                r[i * dim + j] += rhs[i * dim + k] * lhs[k * dim + j];
                r[i * dim + j + 1] += rhs[i * dim + k] * lhs[k * dim + j + 1];
                r[(i + 1) * dim + j] += rhs[(i + 1) * dim + k] * lhs[k * dim + j];
                r[(i + 1) * dim + j + 1] += rhs[(i + 1) * dim + k] * lhs[k * dim + j + 1];
            }
    return r;
}

vector<int> pow(vector<int> A, int p, int dim)
{
    if (p == 1)
        return A;
    else if (p % 2)
    {
        vector<int> T = pow(A, p - 1, dim);
        return mult(A, T, dim);
    }
    else
    {
        vector<int> T = pow(A, p / 2, dim);
        return mult(T, T, dim);
    }
}

int main()
{
    while (cin >> N >> M >> Z && N > 0)
    {
        int dim = 2 * M + 2;

        vector< pair<int, int> > edges;
        vector<int> edge_adj(dim * dim, 0);
        edges.push_back(make_pair(0, 1));

        int s, d;
        for (int i = 0; i < M; ++i)
        {
            cin >> s >> d;
            edges.push_back(make_pair(s, d));
            edges.push_back(make_pair(d, s));
        }

        for (int i = 0; i < edges.size(); ++i)
        {
            for (int j = 0; j < edges.size(); ++j)
            {
                if (i != j && edges[i].second == edges[j].first && edges[i].first != edges[j].second)
                    edge_adj[i * dim + j] = 1;
                else
                    edge_adj[i * dim + j] = 0;
            }
        }

        edge_adj = pow(edge_adj, Z, dim);

        bool ans = false;
        for (int i = 0; i < edges.size(); ++i)
        {
            if (edges[i].second == N && edge_adj[i] != 0)
            {
                ans = true;
                break;
            }
        }

        if (ans)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
}
accuracy: 1
time_ms: 200
memory_kb: 5592
final_rank: 6

code_snippet: #include <iostream>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;

int N, M, Z;

vector<int> mult(vector<int> lhs, vector<int> rhs, int dim)
{
    vector<int> r(dim * dim, 0);
    for (int i = 0; i < dim; i += 2)
        for (int k = 0; k < dim; ++k)
            for (int j = 0; j < dim; j += 2)
            {
                r[i * dim + j] += rhs[i * dim + k] * lhs[k * dim + j];
                r[i * dim + j + 1] += rhs[i * dim + k] * lhs[k * dim + j + 1];
                r[(i + 1) * dim + j] += rhs[(i + 1) * dim + k] * lhs[k * dim + j];
                r[(i + 1) * dim + j + 1] += rhs[(i + 1) * dim + k] * lhs[k * dim + j + 1];
            }
    return r;
}

vector<int> pow(vector<int> A, int p, int dim)
{
    if (p == 1)
        return A;
    else if (p % 2)
    {
        vector<int> T = pow(A, p - 1, dim);
        return mult(A, T, dim);
    }
    else
    {
        vector<int> T = pow(A, p / 2, dim);
        return mult(T, T, dim);
    }
}

int main()
{
    while (cin >> N >> M >> Z && N > 0)
    {
        int dim = 2 * M + 2;

        vector<pair<int, int>> edges;
        vector<int> edge_adj(dim * dim, 0);
        edges.push_back(make_pair(0, 1));

        int s, d;
        for (int i = 0; i < M; ++i)
        {
            cin >> s >> d;
            edges.push_back(make_pair(s, d));
            edges.push_back(make_pair(d, s));
        }

        for (int i = 0; i < edges.size(); ++i)
        {
            for (int j = 0; j < edges.size(); ++j)
            {
                if (i != j && edges[i].second == edges[j].first && edges[i].first != edges[j].second)
                    edge_adj[i * dim + j] = 1;
                else
                    edge_adj[i * dim + j] = 0;
            }
        }

        edge_adj = pow(edge_adj, Z, dim);

        bool ans = false;
        for (int i = 0; i < edges.size(); ++i)
        {
            if (edges[i].second == N && edge_adj[i] != 0)
            {
                ans = true;
                break;
            }
        }

        if (ans)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
}
accuracy: 1
time_ms: 120
memory_kb: 5664
final_rank: 1

code_snippet: #include <iostream>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;

int N, M, Z;

vector<int> mult(vector<int> lhs, vector<int> rhs, int dim)
{
    vector<int> r(dim * dim, 0);
    for (int i = 0; i < dim; ++i)
        for (int k = 0; k < dim; ++k)
            for (int j = 0; j < dim; ++j)
                r[i * dim + j] += rhs[i * dim + k] * lhs[k * dim + j];
    return r;
}

vector<int> pow(vector<int> A, int p, int dim)
{
    if (p == 1)
        return A;
    else if (p % 2)
    {
        vector<int> T = pow(A, p - 1, dim);
        return mult(A, T, dim);
    }
    else
    {
        vector<int> T = pow(A, p / 2, dim);
        return mult(T, T, dim);
    }
}

int main()
{
    while (cin >> N >> M >> Z && N > 0)
    {
        int dim = 2 * M + 2;

        vector<pair<int, int>> edges;
        vector<int> edge_adj(dim * dim, 0);
        edges.push_back(make_pair(0, 1));

        int s, d;
        for (int i = 0; i < M; ++i)
        {
            cin >> s >> d;
            edges.push_back(make_pair(s, d));
            edges.push_back(make_pair(d, s));
        }

        for (int i = 0; i < edges.size(); ++i)
        {
            for (int j = 0; j < edges.size(); ++j)
            {
                if (i != j && edges[i].second == edges[j].first && edges[i].first != edges[j].second)
                    edge_adj[i * dim + j] = 1;
                else
                    edge_adj[i * dim + j] = 0;
            }
        }

        edge_adj = pow(edge_adj, Z, dim);

        bool ans = false;
        for (int i = 0; i < edges.size(); ++i)
        {
            if (edges[i].second == N && edge_adj[i] != 0)
            {
                ans = true;
                break;
            }
        }

        if (ans)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
}
accuracy: 1
time_ms: 230
memory_kb: 5876
final_rank: 13

code_snippet: #include <iostream>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;

int N, M, Z;

vector<int> mult(vector<int> lhs, vector<int> rhs, int dim)
{
    vector<int> r(dim * dim, 0);
    for (int i = 0; i < dim; ++i)
        for (int k = 0; k < dim; ++k)
            for (int j = 0; j < dim; ++j)
                r[i * dim + j] += rhs[i * dim + k] * lhs[k * dim + j];
    return r;
}

vector<int> pow(vector<int> A, int p, int dim)
{
    if (p == 1)
        return A;
    else if (p % 2)
    {
        vector<int> T = pow(A, p - 1, dim);
        return mult(A, T, dim);
    }
    else
    {
        vector<int> T = pow(A, p / 2, dim);
        return mult(T, T, dim);
    }
}

int main()
{
    while (cin >> N >> M >> Z && N > 0)
    {
        int dim = 2 * M + 1;

        vector<pair<int, int>> edges;
        vector<int> edge_adj(dim * dim, 0);
        edges.push_back(make_pair(0, 1));

        int s, d;
        for (int i = 0; i < M; ++i)
        {
            cin >> s >> d;
            edges.push_back(make_pair(s, d));
            edges.push_back(make_pair(d, s));
        }

        for (int i = 0; i < edges.size(); ++i)
        {
            for (int j = 0; j < edges.size(); ++j)
            {
                if (i != j && edges[i].second == edges[j].first && edges[i].first != edges[j].second)
                    edge_adj[i * dim + j] = 1;
                else
                    edge_adj[i * dim + j] = 0;
            }
        }

        edge_adj = pow(edge_adj, Z, dim);

        bool ans = false;
        for (int i = 0; i < edges.size(); ++i)
        {
            if (edges[i].second == N && edge_adj[i] != 0)
            {
                ans = true;
                break;
            }
        }

        if (ans)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
}
accuracy: 1
time_ms: 220
memory_kb: 5820
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <utility>
using namespace std;

struct Matrix {
    vector<vector<bool>> table;
    int size;
    Matrix(int n) : table(n, vector<bool>(n)), size(n) {}
    void output() {
        for(auto &i : table) {
            for(auto &&j : i) cout << j;
            cout << endl;
        }
    }
};

Matrix product(const Matrix &a, const Matrix &b) {
    int n = a.size;
    Matrix ret(n);
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            for(int k  = 0; k < n; k++) {
                ret.table[i][k] = ret.table[i][k] | (a.table[i][j] & b.table[j][k]);
            }
        }
    }
    return ret;
}

struct Edge {
    int from, to, from_num, to_num;
    Edge(int _from, int _to, int _from_num, int _to_num)
    : from(_from), to(_to), from_num(_from_num), to_num(_to_num) {}
    Edge() {}
};

// m^k
Matrix doubling(Matrix m, int k) {
    if(k == 1) return m;
    else if(k%2 == 1) return product(m, doubling(m, k-1));
    else {
        auto tmp = doubling(m, k/2);
        return product(tmp, tmp);
    }
}

bool solve(int n, int m, int z) {
    if(z == 1) {
        bool ans = false;
        for(int i = 0; i < m; i++) {
            int s, d;
            cin >> s >> d;
            if((s == 1 && d == n) || (s == n && d == 1)) {
                ans = true;
            }
        }
        return ans;
    }
    vector<vector<Edge>> vertex_number(n);
    for(int i = 0; i < m; i++) {
        int s, d;
        cin >> s >> d;
        --s; --d;
        vertex_number[s].push_back({s, d, i*2, i*2+1});
        vertex_number[d].push_back({d, s, i*2+1, i*2});
    }
    Matrix neighbor(m*2);
    for(auto &edges : vertex_number) {
        for(auto &e : edges) {
            for(auto &e1 : vertex_number[e.from]) {
                if(e1.from_num == e.from_num) continue;
                // cerr << e1.from_num << " " << e.to_num << endl;
                neighbor.table[e1.from_num][e.to_num] = true;
            }
        }
    }
    Matrix start(m*2);
    auto ans = doubling(neighbor, z-1);
    // neighbor.output(); cout << endl;
    // ans.output(); cout << endl;
    for(auto &i : vertex_number[0]) {
        for(auto &j : vertex_number.back()) {
            if(ans.table[i.to_num][j.from_num]) {
                return true;
            }
        }
    }
    return false;
}

int main() {
    int n, m, z;
    vector<bool> ans;
    while(1) {
        cin >> n >> m >> z;
        if(n == 0 && m == 0 && z == 0) break;
        ans.push_back(solve(n, m, z));
    }
    for(auto &&i : ans) {
        cout << (i ? "yes" : "no") << endl;
    }
}
accuracy: 1
time_ms: 700
memory_kb: 3904
final_rank: 18

code_snippet: #line 2 "/home/yuruhiya/programming/library/template/template.cpp"
#include <bits/stdc++.h>
#line 6 "/home/yuruhiya/programming/library/template/constants.cpp"
using namespace std;

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rfor(i, m, n) for (int i = (m); i >= (n); --i)
#define unless(c) if (!(c))
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define range_it(a, l, r) (a).begin() + (l), (a).begin() + (r)

using namespace std;
using ll = long long;
using LD = long double;
using VB = vector<bool>;
using VVB = vector<VB>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
using VS = vector<string>;
using VD = vector<LD>;
using PII = pair<int, int>;
using VP = vector<PII>;
using PLL = pair<ll, ll>;
using VPL = vector<PLL>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQS = priority_queue<T, vector<T>, greater<T>>;
constexpr int inf = 1e9;
constexpr long long inf_ll = 1e18, MOD = 1000000007;
constexpr long double PI = 3.14159265358979323846, EPS = 1e-12;
#line 7 "/home/yuruhiya/programming/library/template/Input.cpp"
using namespace std;

#ifdef _WIN32
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#define fwrite_unlocked fwrite
#define fflush_unlocked fflush
#endif
class Input {
	static int gc() {
		return getchar_unlocked();
	}
	template <class T> static void read(T& v) {
		cin >> v;
	}
	static void read(char& v) {
		while (isspace(v = gc()))
			;
	}
	static void read(bool& v) {
		v = read<char>() != '0';
	}
	static void read(string& v) {
		v.clear();
		for (char c = read<char>(); !isspace(c); c = gc()) v += c;
	}
	static void read(int& v) {
		v = 0;
		bool neg = false;
		char c = read<char>();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(long long& v) {
		v = 0;
		bool neg = false;
		char c = read<char>();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(double& v) {
		v = 0;
		double dp = 1;
		bool neg = false, after_dp = false;
		char c = read<char>();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	static void read(long double& v) {
		v = 0;
		long double dp = 1;
		bool neg = false, after_dp = false;
		char c = read<char>();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	template <class T, class U> static void read(pair<T, U>& v) {
		read(v.first);
		read(v.second);
	}
	template <class T> static void read(vector<T>& v) {
		for (auto& e : v) read(e);
	}
	template <size_t N = 0, class T> static void read_tuple_impl(T& v) {
		if constexpr (N < tuple_size_v<T>) {
			read(get<N>(v));
			read_tuple_impl<N + 1>(v);
		}
	}
	template <class... T> static void read(tuple<T...>& v) {
		read_tuple_impl(v);
	}
	struct ReadVectorHelper {
		int n;
		ReadVectorHelper(int _n) : n(_n) {}
		template <class T> operator vector<T>() {
			vector<T> v(n);
			read(v);
			return v;
		}
	};
	struct Read2DVectorHelper {
		int n, m;
		Read2DVectorHelper(const pair<int, int>& nm) : n(nm.first), m(nm.second) {}
		template <class T> operator vector<vector<T>>() {
			vector<vector<T>> v(n, vector<T>(m));
			read(v);
			return v;
		}
	};

public:
	static string read_line() {
		string v;
		for (char c = read<char>(); c != '\n' && c != '\0'; c = gc()) v += c;
		return v;
	}
	template <class T> static T read() {
		T v;
		read(v);
		return v;
	}
	template <class T> operator T() const {
		return read<T>();
	}
	int operator--(int) const {
		return read<int>() - 1;
	}
	ReadVectorHelper operator[](int n) const {
		return ReadVectorHelper(n);
	}
	Read2DVectorHelper operator[](const pair<int, int>& nm) const {
		return Read2DVectorHelper(nm);
	}
	void operator()() const {}
	template <class H, class... T> void operator()(H&& h, T&&... t) const {
		read(h);
		operator()(forward<T>(t)...);
	}

private:
	template <template <class...> class, class...> struct Multiple;
	template <template <class...> class V, class Head, class... Tail>
	struct Multiple<V, Head, Tail...> {
		template <class... Args> using vec = V<vector<Head>, Args...>;
		using type = typename Multiple<vec, Tail...>::type;
	};
	template <template <class...> class V> struct Multiple<V> { using type = V<>; };
	template <class... T> using multiple_t = typename Multiple<tuple, T...>::type;
	template <size_t N = 0, class T> void multiple_impl(T& t) const {
		if constexpr (N < tuple_size_v<T>) {
			auto& vec = get<N>(t);
			using V = typename remove_reference_t<decltype(vec)>::value_type;
			vec.push_back(read<V>());
			multiple_impl<N + 1>(t);
		}
	}

public:
	template <class... T> auto multiple(int h) const {
		multiple_t<T...> result;
		while (h--) multiple_impl(result);
		return result;
	}
} in;
#define inputs(T, ...) \
	T __VA_ARGS__;     \
	in(__VA_ARGS__)
#define ini(...) inputs(int, __VA_ARGS__)
#define inl(...) inputs(long long, __VA_ARGS__)
#define ins(...) inputs(string, __VA_ARGS__)
#line 7 "/home/yuruhiya/programming/library/template/Output.cpp"
#include <charconv>
#line 10 "/home/yuruhiya/programming/library/template/Output.cpp"
using namespace std;

struct BoolStr {
	const char *t, *f;
	BoolStr(const char* _t, const char* _f) : t(_t), f(_f) {}
} Yes("Yes", "No"), yes("yes", "no"), YES("YES", "NO"), Int("1", "0");
struct DivStr {
	const char *d, *l;
	DivStr(const char* _d, const char* _l) : d(_d), l(_l) {}
} spc(" ", "\n"), no_spc("", "\n"), end_line("\n", "\n"), comma(",", "\n"),
    no_endl(" ", "");
class Output {
	BoolStr B{Yes};
	DivStr D{spc};

public:
	void put(int v) const {
		char buf[12]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(long long v) const {
		char buf[21]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(bool v) const {
		put(v ? B.t : B.f);
	}
	void put(char v) const {
		putchar_unlocked(v);
	}
	void put(const char* v) const {
		fwrite_unlocked(v, 1, strlen(v), stdout);
	}
	void put(double v) const {
		printf("%.20f", v);
	}
	void put(long double v) const {
		printf("%.20Lf", v);
	}
	template <class T> void put(const T& v) const {
		cout << v;
	}
	template <class T, class U> void put(const pair<T, U>& v) const {
		put(v.first);
		put(D.d);
		put(v.second);
	}
	template <class InputIterater>
	void put_range(const InputIterater& begin, const InputIterater& end) const {
		for (InputIterater i = begin; i != end; ++i) {
			if (i != begin) put(D.d);
			put(*i);
		}
	}
	template <class T> void put(const vector<T>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T, size_t N> void put(const array<T, N>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T> void put(const vector<vector<T>>& v) const {
		for (size_t i = 0; i < v.size(); ++i) {
			if (i) put(D.l);
			put(v[i]);
		}
	}

	Output() = default;
	Output(const BoolStr& _boolstr, const DivStr& _divstr) : B(_boolstr), D(_divstr) {}
	Output& operator()() {
		put(D.l);
		return *this;
	}
	template <class H> Output& operator()(H&& h) {
		put(h);
		put(D.l);
		return *this;
	}
	template <class H, class... T> Output& operator()(H&& h, T&&... t) {
		put(h);
		put(D.d);
		return operator()(forward<T>(t)...);
	}
	template <class InputIterator>
	Output& range(const InputIterator& begin, const InputIterator& end) {
		put_range(begin, end);
		put(D.l);
		return *this;
	}
	template <class T> Output& range(const T& a) {
		range(a.begin(), a.end());
		return *this;
	}
	template <class... T> void exit(T&&... t) {
		operator()(forward<T>(t)...);
		std::exit(EXIT_SUCCESS);
	}
	Output& flush() {
		fflush_unlocked(stdout);
		return *this;
	}
	Output& set(const BoolStr& b) {
		B = b;
		return *this;
	}
	Output& set(const DivStr& d) {
		D = d;
		return *this;
	}
	Output& set(const char* t, const char* f) {
		B = BoolStr(t, f);
		return *this;
	}
} out;
#line 3 "/home/yuruhiya/programming/library/template/Step.cpp"
using namespace std;

template <class T> struct Step {
	using value_type = T;

	class iterator {
		value_type a, b, c;

	public:
		constexpr iterator() : a(value_type()), b(value_type()), c(value_type()) {}
		constexpr iterator(value_type _b, value_type _c, value_type _s)
		    : a(_b), b(_c), c(_s) {}
		constexpr iterator& operator++() {
			--b;
			a += c;
			return *this;
		}
		constexpr iterator operator++(int) {
			iterator tmp = *this;
			--b;
			a += c;
			return tmp;
		}
		constexpr const value_type& operator*() const {
			return a;
		}
		constexpr const value_type* operator->() const {
			return &a;
		}
		constexpr bool operator==(const iterator& i) const {
			return b == i.b;
		}
		constexpr bool operator!=(const iterator& i) const {
			return !(b == i.b);
		}
		constexpr value_type start() const {
			return a;
		}
		constexpr value_type size() const {
			return b;
		}
		constexpr value_type step() const {
			return c;
		}
	};
	constexpr Step(value_type b, value_type c, value_type s) : be(b, c, s) {}
	constexpr iterator begin() const {
		return be;
	}
	constexpr iterator end() const {
		return en;
	}
	constexpr value_type start() const {
		return be.start();
	}
	constexpr value_type size() const {
		return be.size();
	}
	constexpr value_type step() const {
		return be.step();
	}
	constexpr value_type sum() const {
		return start() * size() + step() * (size() * (size() - 1) / 2);
	}
	operator vector<value_type>() const {
		return to_a();
	}
	auto to_a() const {
		vector<value_type> result;
		result.reserve(size());
		for (auto i : *this) {
			result.push_back(i);
		}
		return result;
	}

private:
	iterator be, en;
};
template <class T> constexpr auto step(T a) {
	return Step<T>(0, a, 1);
}
template <class T> constexpr auto step(T a, T b) {
	return Step<T>(a, b - a, 1);
}
template <class T> constexpr auto step(T a, T b, T c) {
	return Step<T>(a, a < b ? (b - a - 1) / c + 1 : 0, c);
}
#line 8 "/home/yuruhiya/programming/library/template/Ruby.cpp"
using namespace std;

template <class F> struct Callable {
	F func;
	Callable(const F& f) : func(f) {}
};
template <class T, class F> auto operator|(const T& v, const Callable<F>& c) {
	return c.func(v);
}

struct Sort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const Sort_impl& c) {
		sort(begin(v), end(v));
		return v;
	}
} Sort;
struct SortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) < f(j); });
			return v;
		});
	}
} SortBy;
struct RSort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(rbegin(v), rend(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const RSort_impl& c) {
		sort(rbegin(v), rend(v));
		return v;
	}
} RSort;
struct RSortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) > f(j); });
			return v;
		});
	}
} RSortBy;
struct Reverse_impl {
	template <class T> friend auto operator|(T v, const Reverse_impl& c) {
		reverse(begin(v), end(v));
		return v;
	}
} Reverse;
struct Unique_impl {
	template <class T> friend auto operator|(T v, const Unique_impl& c) {
		v.erase(unique(begin(v), end(v), end(v)));
		return v;
	}
} Unique;
struct Uniq_impl {
	template <class T> friend auto operator|(T v, const Uniq_impl& c) {
		sort(begin(v), end(v));
		v.erase(unique(begin(v), end(v)), end(v));
		return v;
	}
} Uniq;
struct Rotate_impl {
	auto operator()(int&& left) {
		return Callable([&](auto v) {
			int s = static_cast<int>(size(v));
			assert(-s <= left && left <= s);
			if (0 <= left) {
				rotate(begin(v), begin(v) + left, end(v));
			} else {
				rotate(begin(v), end(v) + left, end(v));
			}
			return v;
		});
	}
} Rotate;
struct Max_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *max_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Max_impl& c) {
		return *max_element(begin(v), end(v));
	}
} Max;
struct Min_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *min_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Min_impl& c) {
		return *min_element(begin(v), end(v));
	}
} Min;
struct MaxPos_impl {
	template <class T> friend auto operator|(T v, const MaxPos_impl& c) {
		return max_element(begin(v), end(v)) - begin(v);
	}
} MaxPos;
struct MinPos_impl {
	template <class T> friend auto operator|(T v, const MinPos_impl& c) {
		return min_element(begin(v), end(v)) - begin(v);
	}
} MinPos;
struct MaxBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_it = begin(v);
			auto max_val = f(*max_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_it = it;
					max_val = val;
				}
			}
			return *max_it;
		});
	}
} MaxBy;
struct MinBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_it = begin(v);
			auto min_val = f(*min_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_it = it;
					min_val = val;
				}
			}
			return *min_it;
		});
	}
} MinBy;
struct MaxOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_val = val;
				}
			}
			return max_val;
		});
	}
} MaxOf;
struct MinOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_val = val;
				}
			}
			return min_val;
		});
	}
} MinOf;
struct Count_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return count(begin(v), end(v), val); });
	}
} Count;
struct CountIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return count_if(begin(v), end(v), f); });
	}
} CountIf;
struct Index_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find(begin(v), end(v), val);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} Index;
struct IndexIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} IndexIf;
struct FindIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<typename decltype(v)::value_type> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(*result) : nullopt;
		});
	}
} FindIf;
struct Sum_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			return accumulate(next(begin(v)), end(v), f(*begin(v)),
			                  [&](const auto& a, const auto& b) { return a + f(b); });
		});
	}
	template <class T> friend auto operator|(T v, const Sum_impl& c) {
		return accumulate(begin(v), end(v), typename T::value_type{});
	}
} Sum;
struct Includes {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return find(begin(v), end(v), val) != end(v); });
	}
} Includes;
struct IncludesIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return find_if(begin(v), end(v), f) != end(v); });
	}
} IncludesIf;
struct RemoveIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) {
			v.erase(remove_if(begin(v), end(v), f), end(v));
			return v;
		});
	}
} RemoveIf;
struct Each_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				f(i);
			}
		});
	}
} Each;
struct Select_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using value_type = typename decltype(v)::value_type;
			vector<value_type> result;
			for (const auto& i : v) {
				if (f(i)) result.push_back(i);
			}
			return result;
		});
	}
} Select;
struct Map_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using result_type = invoke_result_t<F, typename decltype(v)::value_type>;
			vector<result_type> result;
			result.reserve(size(v));
			for (const auto& i : v) {
				result.push_back(f(i));
			}
			return result;
		});
	}
} Map;
struct Indexed_impl {
	template <class T> friend auto operator|(const T& v, Indexed_impl& c) {
		using value_type = typename T::value_type;
		vector<pair<value_type, int>> result;
		result.reserve(size(v));
		int index = 0;
		for (const auto& i : v) {
			result.emplace_back(i, index++);
		}
		return result;
	}
} Indexed;
struct AllOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (!f(i)) return false;
			}
			return true;
		});
	}
} AllOf;
struct AnyOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return true;
			}
			return false;
		});
	}
} AnyOf;
struct NoneOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return false;
			}
			return true;
		});
	}
} NoneOf;

struct Tally_impl {
	template <class F> auto operator()(size_t max_val) {
		return Callable([&](auto v) {
			vector<size_t> result(max_val);
			for (const auto& i : v) {
				result[static_cast<size_t>(i)]++;
			}
			return result;
		});
	}
	template <class T, class value_type = typename T::value_type>
	friend auto operator|(const T& v, Tally_impl& c) {
		map<value_type, size_t> result;
		for (const auto& i : v) {
			result[i]++;
		}
		return result;
	}
} Tally;

template <class T> auto operator*(const vector<T>& a, size_t n) {
	T result;
	for (size_t i = 0; i < n; ++i) {
		result.insert(result.end(), a.begin(), a.end());
	}
	return result;
}
auto operator*(string a, size_t n) {
	string result;
	for (size_t i = 0; i < n; ++i) {
		result += a;
	}
	return result;
}
template <class T, class U> auto& operator<<(vector<T>& a, const U& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T> auto& operator<<(string& a, const T& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T, class U> auto operator+(vector<T> a, const U& b) {
	a << b;
	return a;
}
template <class T> auto operator+(string a, const T& b) {
	a << b;
	return a;
}
#line 6 "/home/yuruhiya/programming/library/template/functions.cpp"
using namespace std;

template <class T> int sz(const T& v) {
	return v.size();
}
template <class T, class U> int lower_index(const T& a, const U& v) {
	return lower_bound(all(a), v) - a.begin();
}
template <class T, class U> int upper_index(const T& a, const U& v) {
	return upper_bound(all(a), v) - a.begin();
}
template <class T> auto Slice(const T& v, size_t i, size_t len) {
	return i < v.size() ? T(v.begin() + i, v.begin() + min(i + len, v.size())) : T();
}
template <class T> T div_ceil(T n, T m) {
	return (n + m - 1) / m;
}
template <class T> T div_ceil2(T n, T m) {
	return div_ceil(n, m) * m;
}
template <class T> T triangle(T n) {
	return (n & 1) ? (n + 1) / 2 * n : n / 2 * (n + 1);
}
template <class T> T nC2(T n) {
	return (n & 1) ? (n - 1) / 2 * n : n / 2 * (n - 1);
}
template <class T> T middle(const T& l, const T& r) {
	return l + (r - l) / 2;
}
template <class T> bool chmax(T& a, const T& b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool chmin(T& a, const T& b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool in_range(const T& v, const T& min, const T& max) {
	return min <= v && v < max;
}
template <class T> bool in_square(T n) {
	T s = sqrt(n);
	return s * s == n || (s + 1) * (s + 1) == n;
}
template <class T = long long> T BIT(int b) {
	return T(1) << b;
}
template <class T, class U = typename T::value_type> U Gcdv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), gcd<U, U>);
}
template <class T, class U = typename T::value_type> U Lcmv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), lcm<U, U>);
}
template <class T, class U> T Pow(T a, U n) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result *= a;
			n--;
		} else {
			a *= a;
			n >>= 1;
		}
	}
	return result;
}
template <class T, class U> T Powmod(T a, U n, T mod) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result = result * a % mod;
			n--;
		} else {
			a = a * a % mod;
			n >>= 1;
		}
	}
	return result;
}
namespace internal {
	template <class T, size_t N> auto make_vector(vector<int>& sizes, const T& init) {
		if constexpr (N == 1) {
			return vector(sizes[0], init);
		} else {
			int size = sizes[N - 1];
			sizes.pop_back();
			return vector(size, make_vector<T, N - 1>(sizes, init));
		}
	}
}  // namespace internal
template <class T, size_t N>
auto make_vector(const int (&sizes)[N], const T& init = T()) {
	vector s(rbegin(sizes), rend(sizes));
	return internal::make_vector<T, N>(s, init);
}
#line 9 "/home/yuruhiya/programming/library/template/template.cpp"
#if __has_include(<library/dump.hpp>)
#include <library/dump.hpp>
#define LOCAL
#else
#define dump(...) ((void)0)
#endif

template <class T> constexpr T oj_local(const T& oj, const T& local) {
#ifndef LOCAL
	return oj;
#else
	return local;
#endif
}
#line 2 "b.cpp"

bool solve(int n, int m, ll z) {
	const int MAX = 32;
	int M = m * 2;
	VP edges(M);
	rep(i, m) {
		int u = in--, v = in--;
		edges[i * 2] = {u, v};
		edges[i * 2 + 1] = {v, u};
	}

	auto joint = make_vector<bool>({M, M});
	rep(i, M) rep(j, M) {
		joint[i][j] = edges[i].second == edges[j].first && i / 2 != j / 2;
	}

	auto merge_flag = [&](const VVB& flag1, const VVB& flag2) {
		auto res = make_vector<bool>({M, M});
		rep(begin1, M) rep(end1, M) if (flag1[begin1][end1]) {
			rep(begin2, M) if (joint[end1][begin2]) {
				rep(end2, M) if (flag2[begin2][end2]) {
					res[begin1][end2] = true;
				}
			}
		}
		return res;
	};

	auto flag = make_vector<bool>({MAX, M, M});
	rep(i, M) {
		flag[0][i][i] = true;
	}
	FOR(b, 1, MAX) {
		flag[b] = merge_flag(flag[b - 1], flag[b - 1]);
	}

	auto set = flag[0];
	z--;
	rep(b, MAX) if (z & BIT(b)) {
		set = merge_flag(set, flag[b]);
	}

	rep(i, M) rep(j, M) {
		if (set[i][j] && edges[i].first == 0 && edges[j].second == n - 1) {
			return true;
		}
	}
	return false;
}

int main() {
	out.set(yes);
	while (true) {
		int n, m;
		ll z;
		in(n, m, z);
		if (n == 0) break;
		out(solve(n, m, z));
	}
}
accuracy: 1
time_ms: 520
memory_kb: 3716
final_rank: 16

code_snippet: #line 2 "/home/yuruhiya/programming/library/template/template.cpp"
#include <bits/stdc++.h>
#line 6 "/home/yuruhiya/programming/library/template/constants.cpp"
using namespace std;

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rfor(i, m, n) for (int i = (m); i >= (n); --i)
#define unless(c) if (!(c))
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define range_it(a, l, r) (a).begin() + (l), (a).begin() + (r)

using namespace std;
using ll = long long;
using LD = long double;
using VB = vector<bool>;
using VVB = vector<VB>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
using VS = vector<string>;
using VD = vector<LD>;
using PII = pair<int, int>;
using VP = vector<PII>;
using PLL = pair<ll, ll>;
using VPL = vector<PLL>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQS = priority_queue<T, vector<T>, greater<T>>;
constexpr int inf = 1e9;
constexpr long long inf_ll = 1e18, MOD = 1000000007;
constexpr long double PI = 3.14159265358979323846, EPS = 1e-12;
#line 7 "/home/yuruhiya/programming/library/template/Input.cpp"
using namespace std;

#ifdef _WIN32
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#define fwrite_unlocked fwrite
#define fflush_unlocked fflush
#endif
class Input {
	static int gc() {
		return getchar_unlocked();
	}
	template <class T> static void read(T& v) {
		cin >> v;
	}
	static void read(char& v) {
		while (isspace(v = gc()))
			;
	}
	static void read(bool& v) {
		v = read<char>() != '0';
	}
	static void read(string& v) {
		v.clear();
		for (char c = read<char>(); !isspace(c); c = gc()) v += c;
	}
	static void read(int& v) {
		v = 0;
		bool neg = false;
		char c = read<char>();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(long long& v) {
		v = 0;
		bool neg = false;
		char c = read<char>();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(double& v) {
		v = 0;
		double dp = 1;
		bool neg = false, after_dp = false;
		char c = read<char>();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	static void read(long double& v) {
		v = 0;
		long double dp = 1;
		bool neg = false, after_dp = false;
		char c = read<char>();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	template <class T, class U> static void read(pair<T, U>& v) {
		read(v.first);
		read(v.second);
	}
	template <class T> static void read(vector<T>& v) {
		for (auto& e : v) read(e);
	}
	template <size_t N = 0, class T> static void read_tuple_impl(T& v) {
		if constexpr (N < tuple_size_v<T>) {
			read(get<N>(v));
			read_tuple_impl<N + 1>(v);
		}
	}
	template <class... T> static void read(tuple<T...>& v) {
		read_tuple_impl(v);
	}
	struct ReadVectorHelper {
		int n;
		ReadVectorHelper(int _n) : n(_n) {}
		template <class T> operator vector<T>() {
			vector<T> v(n);
			read(v);
			return v;
		}
	};
	struct Read2DVectorHelper {
		int n, m;
		Read2DVectorHelper(const pair<int, int>& nm) : n(nm.first), m(nm.second) {}
		template <class T> operator vector<vector<T>>() {
			vector<vector<T>> v(n, vector<T>(m));
			read(v);
			return v;
		}
	};

public:
	static string read_line() {
		string v;
		for (char c = read<char>(); c != '\n' && c != '\0'; c = gc()) v += c;
		return v;
	}
	template <class T> static T read() {
		T v;
		read(v);
		return v;
	}
	template <class T> operator T() const {
		return read<T>();
	}
	int operator--(int) const {
		return read<int>() - 1;
	}
	ReadVectorHelper operator[](int n) const {
		return ReadVectorHelper(n);
	}
	Read2DVectorHelper operator[](const pair<int, int>& nm) const {
		return Read2DVectorHelper(nm);
	}
	void operator()() const {}
	template <class H, class... T> void operator()(H&& h, T&&... t) const {
		read(h);
		operator()(forward<T>(t)...);
	}

private:
	template <template <class...> class, class...> struct Multiple;
	template <template <class...> class V, class Head, class... Tail>
	struct Multiple<V, Head, Tail...> {
		template <class... Args> using vec = V<vector<Head>, Args...>;
		using type = typename Multiple<vec, Tail...>::type;
	};
	template <template <class...> class V> struct Multiple<V> { using type = V<>; };
	template <class... T> using multiple_t = typename Multiple<tuple, T...>::type;
	template <size_t N = 0, class T> void multiple_impl(T& t) const {
		if constexpr (N < tuple_size_v<T>) {
			auto& vec = get<N>(t);
			using V = typename remove_reference_t<decltype(vec)>::value_type;
			vec.push_back(read<V>());
			multiple_impl<N + 1>(t);
		}
	}

public:
	template <class... T> auto multiple(int h) const {
		multiple_t<T...> result;
		while (h--) multiple_impl(result);
		return result;
	}
} in;
#define inputs(T, ...) \
	T __VA_ARGS__;     \
	in(__VA_ARGS__)
#define ini(...) inputs(int, __VA_ARGS__)
#define inl(...) inputs(long long, __VA_ARGS__)
#define ins(...) inputs(string, __VA_ARGS__)
#line 7 "/home/yuruhiya/programming/library/template/Output.cpp"
#include <charconv>
#line 10 "/home/yuruhiya/programming/library/template/Output.cpp"
using namespace std;

struct BoolStr {
	const char *t, *f;
	BoolStr(const char* _t, const char* _f) : t(_t), f(_f) {}
} Yes("Yes", "No"), yes("yes", "no"), YES("YES", "NO"), Int("1", "0");
struct DivStr {
	const char *d, *l;
	DivStr(const char* _d, const char* _l) : d(_d), l(_l) {}
} spc(" ", "\n"), no_spc("", "\n"), end_line("\n", "\n"), comma(",", "\n"),
    no_endl(" ", "");
class Output {
	BoolStr B{Yes};
	DivStr D{spc};

public:
	void put(int v) const {
		char buf[12]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(long long v) const {
		char buf[21]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(bool v) const {
		put(v ? B.t : B.f);
	}
	void put(char v) const {
		putchar_unlocked(v);
	}
	void put(const char* v) const {
		fwrite_unlocked(v, 1, strlen(v), stdout);
	}
	void put(double v) const {
		printf("%.20f", v);
	}
	void put(long double v) const {
		printf("%.20Lf", v);
	}
	template <class T> void put(const T& v) const {
		cout << v;
	}
	template <class T, class U> void put(const pair<T, U>& v) const {
		put(v.first);
		put(D.d);
		put(v.second);
	}
	template <class InputIterater>
	void put_range(const InputIterater& begin, const InputIterater& end) const {
		for (InputIterater i = begin; i != end; ++i) {
			if (i != begin) put(D.d);
			put(*i);
		}
	}
	template <class T> void put(const vector<T>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T, size_t N> void put(const array<T, N>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T> void put(const vector<vector<T>>& v) const {
		for (size_t i = 0; i < v.size(); ++i) {
			if (i) put(D.l);
			put(v[i]);
		}
	}

	Output() = default;
	Output(const BoolStr& _boolstr, const DivStr& _divstr) : B(_boolstr), D(_divstr) {}
	Output& operator()() {
		put(D.l);
		return *this;
	}
	template <class H> Output& operator()(H&& h) {
		put(h);
		put(D.l);
		return *this;
	}
	template <class H, class... T> Output& operator()(H&& h, T&&... t) {
		put(h);
		put(D.d);
		return operator()(forward<T>(t)...);
	}
	template <class InputIterator>
	Output& range(const InputIterator& begin, const InputIterator& end) {
		put_range(begin, end);
		put(D.l);
		return *this;
	}
	template <class T> Output& range(const T& a) {
		range(a.begin(), a.end());
		return *this;
	}
	template <class... T> void exit(T&&... t) {
		operator()(forward<T>(t)...);
		std::exit(EXIT_SUCCESS);
	}
	Output& flush() {
		fflush_unlocked(stdout);
		return *this;
	}
	Output& set(const BoolStr& b) {
		B = b;
		return *this;
	}
	Output& set(const DivStr& d) {
		D = d;
		return *this;
	}
	Output& set(const char* t, const char* f) {
		B = BoolStr(t, f);
		return *this;
	}
} out;
#line 3 "/home/yuruhiya/programming/library/template/Step.cpp"
using namespace std;

template <class T> struct Step {
	using value_type = T;

	class iterator {
		value_type a, b, c;

	public:
		constexpr iterator() : a(value_type()), b(value_type()), c(value_type()) {}
		constexpr iterator(value_type _b, value_type _c, value_type _s)
		    : a(_b), b(_c), c(_s) {}
		constexpr iterator& operator++() {
			--b;
			a += c;
			return *this;
		}
		constexpr iterator operator++(int) {
			iterator tmp = *this;
			--b;
			a += c;
			return tmp;
		}
		constexpr const value_type& operator*() const {
			return a;
		}
		constexpr const value_type* operator->() const {
			return &a;
		}
		constexpr bool operator==(const iterator& i) const {
			return b == i.b;
		}
		constexpr bool operator!=(const iterator& i) const {
			return !(b == i.b);
		}
		constexpr value_type start() const {
			return a;
		}
		constexpr value_type size() const {
			return b;
		}
		constexpr value_type step() const {
			return c;
		}
	};
	constexpr Step(value_type b, value_type c, value_type s) : be(b, c, s) {}
	constexpr iterator begin() const {
		return be;
	}
	constexpr iterator end() const {
		return en;
	}
	constexpr value_type start() const {
		return be.start();
	}
	constexpr value_type size() const {
		return be.size();
	}
	constexpr value_type step() const {
		return be.step();
	}
	constexpr value_type sum() const {
		return start() * size() + step() * (size() * (size() - 1) / 2);
	}
	operator vector<value_type>() const {
		return to_a();
	}
	auto to_a() const {
		vector<value_type> result;
		result.reserve(size());
		for (auto i : *this) {
			result.push_back(i);
		}
		return result;
	}

private:
	iterator be, en;
};
template <class T> constexpr auto step(T a) {
	return Step<T>(0, a, 1);
}
template <class T> constexpr auto step(T a, T b) {
	return Step<T>(a, b - a, 1);
}
template <class T> constexpr auto step(T a, T b, T c) {
	return Step<T>(a, a < b ? (b - a - 1) / c + 1 : 0, c);
}
#line 8 "/home/yuruhiya/programming/library/template/Ruby.cpp"
using namespace std;

template <class F> struct Callable {
	F func;
	Callable(const F& f) : func(f) {}
};
template <class T, class F> auto operator|(const T& v, const Callable<F>& c) {
	return c.func(v);
}

struct Sort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const Sort_impl& c) {
		sort(begin(v), end(v));
		return v;
	}
} Sort;
struct SortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) < f(j); });
			return v;
		});
	}
} SortBy;
struct RSort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(rbegin(v), rend(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const RSort_impl& c) {
		sort(rbegin(v), rend(v));
		return v;
	}
} RSort;
struct RSortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) > f(j); });
			return v;
		});
	}
} RSortBy;
struct Reverse_impl {
	template <class T> friend auto operator|(T v, const Reverse_impl& c) {
		reverse(begin(v), end(v));
		return v;
	}
} Reverse;
struct Unique_impl {
	template <class T> friend auto operator|(T v, const Unique_impl& c) {
		v.erase(unique(begin(v), end(v), end(v)));
		return v;
	}
} Unique;
struct Uniq_impl {
	template <class T> friend auto operator|(T v, const Uniq_impl& c) {
		sort(begin(v), end(v));
		v.erase(unique(begin(v), end(v)), end(v));
		return v;
	}
} Uniq;
struct Rotate_impl {
	auto operator()(int&& left) {
		return Callable([&](auto v) {
			int s = static_cast<int>(size(v));
			assert(-s <= left && left <= s);
			if (0 <= left) {
				rotate(begin(v), begin(v) + left, end(v));
			} else {
				rotate(begin(v), end(v) + left, end(v));
			}
			return v;
		});
	}
} Rotate;
struct Max_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *max_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Max_impl& c) {
		return *max_element(begin(v), end(v));
	}
} Max;
struct Min_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *min_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Min_impl& c) {
		return *min_element(begin(v), end(v));
	}
} Min;
struct MaxPos_impl {
	template <class T> friend auto operator|(T v, const MaxPos_impl& c) {
		return max_element(begin(v), end(v)) - begin(v);
	}
} MaxPos;
struct MinPos_impl {
	template <class T> friend auto operator|(T v, const MinPos_impl& c) {
		return min_element(begin(v), end(v)) - begin(v);
	}
} MinPos;
struct MaxBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_it = begin(v);
			auto max_val = f(*max_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_it = it;
					max_val = val;
				}
			}
			return *max_it;
		});
	}
} MaxBy;
struct MinBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_it = begin(v);
			auto min_val = f(*min_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_it = it;
					min_val = val;
				}
			}
			return *min_it;
		});
	}
} MinBy;
struct MaxOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_val = val;
				}
			}
			return max_val;
		});
	}
} MaxOf;
struct MinOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_val = val;
				}
			}
			return min_val;
		});
	}
} MinOf;
struct Count_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return count(begin(v), end(v), val); });
	}
} Count;
struct CountIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return count_if(begin(v), end(v), f); });
	}
} CountIf;
struct Index_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find(begin(v), end(v), val);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} Index;
struct IndexIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} IndexIf;
struct FindIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<typename decltype(v)::value_type> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(*result) : nullopt;
		});
	}
} FindIf;
struct Sum_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			return accumulate(next(begin(v)), end(v), f(*begin(v)),
			                  [&](const auto& a, const auto& b) { return a + f(b); });
		});
	}
	template <class T> friend auto operator|(T v, const Sum_impl& c) {
		return accumulate(begin(v), end(v), typename T::value_type{});
	}
} Sum;
struct Includes {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return find(begin(v), end(v), val) != end(v); });
	}
} Includes;
struct IncludesIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return find_if(begin(v), end(v), f) != end(v); });
	}
} IncludesIf;
struct RemoveIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) {
			v.erase(remove_if(begin(v), end(v), f), end(v));
			return v;
		});
	}
} RemoveIf;
struct Each_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				f(i);
			}
		});
	}
} Each;
struct Select_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using value_type = typename decltype(v)::value_type;
			vector<value_type> result;
			for (const auto& i : v) {
				if (f(i)) result.push_back(i);
			}
			return result;
		});
	}
} Select;
struct Map_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using result_type = invoke_result_t<F, typename decltype(v)::value_type>;
			vector<result_type> result;
			result.reserve(size(v));
			for (const auto& i : v) {
				result.push_back(f(i));
			}
			return result;
		});
	}
} Map;
struct Indexed_impl {
	template <class T> friend auto operator|(const T& v, Indexed_impl& c) {
		using value_type = typename T::value_type;
		vector<pair<value_type, int>> result;
		result.reserve(size(v));
		int index = 0;
		for (const auto& i : v) {
			result.emplace_back(i, index++);
		}
		return result;
	}
} Indexed;
struct AllOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (!f(i)) return false;
			}
			return true;
		});
	}
} AllOf;
struct AnyOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return true;
			}
			return false;
		});
	}
} AnyOf;
struct NoneOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return false;
			}
			return true;
		});
	}
} NoneOf;

struct Tally_impl {
	template <class F> auto operator()(size_t max_val) {
		return Callable([&](auto v) {
			vector<size_t> result(max_val);
			for (const auto& i : v) {
				result[static_cast<size_t>(i)]++;
			}
			return result;
		});
	}
	template <class T, class value_type = typename T::value_type>
	friend auto operator|(const T& v, Tally_impl& c) {
		map<value_type, size_t> result;
		for (const auto& i : v) {
			result[i]++;
		}
		return result;
	}
} Tally;

template <class T> auto operator*(const vector<T>& a, size_t n) {
	T result;
	for (size_t i = 0; i < n; ++i) {
		result.insert(result.end(), a.begin(), a.end());
	}
	return result;
}
auto operator*(string a, size_t n) {
	string result;
	for (size_t i = 0; i < n; ++i) {
		result += a;
	}
	return result;
}
template <class T, class U> auto& operator<<(vector<T>& a, const U& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T> auto& operator<<(string& a, const T& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T, class U> auto operator+(vector<T> a, const U& b) {
	a << b;
	return a;
}
template <class T> auto operator+(string a, const T& b) {
	a << b;
	return a;
}
#line 6 "/home/yuruhiya/programming/library/template/functions.cpp"
using namespace std;

template <class T> int sz(const T& v) {
	return v.size();
}
template <class T, class U> int lower_index(const T& a, const U& v) {
	return lower_bound(all(a), v) - a.begin();
}
template <class T, class U> int upper_index(const T& a, const U& v) {
	return upper_bound(all(a), v) - a.begin();
}
template <class T> auto Slice(const T& v, size_t i, size_t len) {
	return i < v.size() ? T(v.begin() + i, v.begin() + min(i + len, v.size())) : T();
}
template <class T> T div_ceil(T n, T m) {
	return (n + m - 1) / m;
}
template <class T> T div_ceil2(T n, T m) {
	return div_ceil(n, m) * m;
}
template <class T> T triangle(T n) {
	return (n & 1) ? (n + 1) / 2 * n : n / 2 * (n + 1);
}
template <class T> T nC2(T n) {
	return (n & 1) ? (n - 1) / 2 * n : n / 2 * (n - 1);
}
template <class T> T middle(const T& l, const T& r) {
	return l + (r - l) / 2;
}
template <class T> bool chmax(T& a, const T& b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool chmin(T& a, const T& b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool in_range(const T& v, const T& min, const T& max) {
	return min <= v && v < max;
}
template <class T> bool in_square(T n) {
	T s = sqrt(n);
	return s * s == n || (s + 1) * (s + 1) == n;
}
template <class T = long long> T BIT(int b) {
	return T(1) << b;
}
template <class T, class U = typename T::value_type> U Gcdv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), gcd<U, U>);
}
template <class T, class U = typename T::value_type> U Lcmv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), lcm<U, U>);
}
template <class T, class U> T Pow(T a, U n) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result *= a;
			n--;
		} else {
			a *= a;
			n >>= 1;
		}
	}
	return result;
}
template <class T, class U> T Powmod(T a, U n, T mod) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result = result * a % mod;
			n--;
		} else {
			a = a * a % mod;
			n >>= 1;
		}
	}
	return result;
}
namespace internal {
	template <class T, size_t N> auto make_vector(vector<int>& sizes, const T& init) {
		if constexpr (N == 1) {
			return vector(sizes[0], init);
		} else {
			int size = sizes[N - 1];
			sizes.pop_back();
			return vector(size, make_vector<T, N - 1>(sizes, init));
		}
	}
}  // namespace internal
template <class T, size_t N>
auto make_vector(const int (&sizes)[N], const T& init = T()) {
	vector s(rbegin(sizes), rend(sizes));
	return internal::make_vector<T, N>(s, init);
}
#line 9 "/home/yuruhiya/programming/library/template/template.cpp"
#if __has_include(<library/dump.hpp>)
#include <library/dump.hpp>
#define LOCAL
#else
#define dump(...) ((void)0)
#endif

template <class T> constexpr T oj_local(const T& oj, const T& local) {
#ifndef LOCAL
	return oj;
#else
	return local;
#endif
}
#line 2 "b.cpp"

bool solve(int n, int m, ll z) {
	const int MAX = 32;
	int M = m * 2;
	VP edges(M);
	rep(i, m) {
		int u = in--, v = in--;
		edges[i * 2] = {u, v};
		edges[i * 2 + 1] = {v, u};
	}

	if (z == 1) {
		return edges | Includes(pair(0, n - 1));
	}

	auto joint = make_vector<bool>({M, M});
	rep(i, M) rep(j, M) {
		joint[i][j] = edges[i].second == edges[j].first && i / 2 != j / 2;
	}
	dump(joint);

	auto flag = make_vector<bool>({MAX, M, M});
	rep(i, M) {
		flag[0][i][i] = true;
	}
	FOR(b, 1, MAX) {
		rep(begin1, M) rep(end1, M) if (flag[b - 1][begin1][end1]) {
			rep(begin2, M) if (joint[end1][begin2]) {
				rep(end2, M) if (flag[b - 1][begin2][end2]) {
					flag[b][begin1][end2] = true;
				}
			}
		}
	}

	auto set = flag[0];
	dump(set);
	z--;
	rep(b, MAX) if (z & BIT(b)) {
		auto next_set = make_vector<bool>({M, M});
		rep(begin1, M) rep(end1, M) if (set[begin1][end1]) {
			rep(begin2, M) if (joint[end1][begin2]) {
				rep(end2, M) if (flag[b][begin2][end2]) {
					next_set[begin1][end2] = true;
				}
			}
		}
		dump(b, next_set);
		set = next_set;
	}

	rep(i, M) rep(j, M) if (set[i][j]) {
		if (edges[i].first == 0 && edges[j].second == n - 1) {
			return true;
		}
	}
	return false;
}

int main() {
	out.set(yes);
	while (true) {
		int n, m;
		ll z;
		in(n, m, z);
		if (n == 0) break;
		out(solve(n, m, z));
	}
}
accuracy: 1
time_ms: 500
memory_kb: 3608
final_rank: 15

code_snippet: #include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repr(i, n) for (int i = (n); i >= 0; --i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define FORR(i, m, n) for (int i = (m); i >= (n); --i)
#define equals(a, b) (fabs((a) - (b)) < EPS)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const ll mod = 1000000007;
//const ll mod = 998244353;
const int inf = 1e9 + 10;
const ll INF = 1e18;
const ld EPS = 1e-10;
const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }

typedef vector<int> vec;
typedef vector<vec> mat;

mat matmul(mat& a, mat& b) {
  mat c(a.size(), vec(b[0].size(), 0));
  rep(i, a.size()) {
    rep(k, b.size()) {
      rep(j, b[0].size()) {
        c[i][j] |= a[i][k] & b[k][j];
      }
    }
  }
  return c;
}

mat matpow(mat a, ll n) {
  mat b(a.size(), vec(a.size(), 0));
  rep(i, a.size()) b[i][i] = 1;
  while (n > 0) {
    if (n & 1) b = matmul(b, a);
    a = matmul(a, a);
    n >>= 1;
  }
  return b;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(25);

  while (1) {
    int n, m, z;
    cin >> n >> m >> z;
    if (n == 0 && m == 0 && z == 0) return 0;
    
    vector<int> s(2 * m), d(2 * m);
    rep(i, m) {
      cin >> s[i] >> d[i];
      s[i]--, d[i]--;
      s[i + m] = d[i], d[i + m] = s[i];
    }
    mat res(2 * m + 1, vector<int>(2 * m + 1, 0));
    rep(i, 2 * m) {
      rep(j, 2 * m) {
        if (d[i] == s[j] && abs(i - j) != m) res[i][j] = 1;
      }
    }
    rep(j, 2 * m) {
      if (s[j] == 0) res[2 * m][j] = 1;
    }
    res = matpow(res, z);
    bool ans = false;
    rep(j, 2 * m) {
      if (d[j] == n - 1 && res[2 * m][j]) ans = true;
    }
    cout << (ans ? "yes" : "no") << '\n';
  }





  
  return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 3100
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int long long
#define rep(i, n) for (int i = 0; i < (n); i++)
#define reps(i, n) for (int i = 1; i <= (n); i++)
#define all(x) (x).begin(), (x).end()
#define uniq(x) (x).erase(unique(all(x)), end(x))
#define bit(n) (1LL << (n))
#define cdiv(a, b) (((a) - 1) / (b) + 1)
#define dump(x) cerr << #x " = " << (x) << endl
using vint = vector<int>;
using vvint = vector<vint>;
using pint = pair<int, int>;
using vpint = vector<pint>;
template<typename T> using priority_queue_rev = priority_queue<T, vector<T>, greater<T>>;
constexpr double PI = 3.1415926535897932384626433832795028;
constexpr int DY[8] = {0, 1, 0, -1, 1, 1, -1, -1};
constexpr int DX[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int gcd(int a, int b) {
    while (b) { swap(a %= b, b); }
    return a;
}
int lcm(int a, int b) { return a / gcd(a, b) * b; }
template<typename T> void fin(T mes) {
    cout << mes << endl;
    exit(0);
}
template<typename T, typename U> bool chmax(T &a, const U &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template<typename T, typename U> bool chmin(T &a, const U &b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}
template<typename T, typename U> ostream &operator<<(ostream &os, const pair<T, U> &rhs) {
    os << "(" << rhs.first << ", " << rhs.second << ")";
    return os;
}
template<typename T> ostream &operator<<(ostream &os, const vector<T> &rhs) {
    os << "{";
    for (auto itr = rhs.begin(); itr != rhs.end(); itr++) {
        os << *itr << (next(itr) != rhs.end() ? ", " : "");
    }
    os << "}";
    return os;
}
struct setup {
    static constexpr int PREC = 20;
    setup() {
        cout << fixed << setprecision(PREC);
        cerr << fixed << setprecision(PREC);
    };
} setup;

/*
 * Koch Curve http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_5_C
 * 約10分
 * 実装例があったので頭がバグらずに済みました。複素数を使うと楽だと思います。
 */

template<typename M>
struct matrix {
    using T = typename M::T;
    int h, w;
    std::vector<std::vector<T>> data;
    matrix(int h, int w) : h(h), w(w), data(h, std::vector<T>(w, M::id_pl())) {}
    matrix(const std::vector<std::vector<T>> &src) : h(src.size()), w(src[0].size()), data(src) {}
    std::vector<T> &operator[](int i) { return data[i]; }
    const std::vector<T> &operator[](int i) const { return data[i]; }
    static matrix identity(int n) {
        matrix ret(n, n);
        for (int i = 0; i < n; i++) { ret[i][i] = M::id_cr(); }
        return ret;
    }
    bool operator==(const matrix &rhs) const {
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                if (data[i][j] != rhs[i][j]) { return false; }
            }
        }
        return true;
    }
    bool operator!=(const matrix &rhs) const { return std::rel_ops::operator!=(*this, rhs); }
    matrix &operator+=(const matrix &rhs) {
        assert(h == rhs.h && w == rhs.w);
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                (*this)[i][j] = M::pl((*this)[i][j], rhs[i][j]);
            }
        }
        return *this;
    }
    matrix &operator-=(const matrix &rhs) {
        assert(h == rhs.h && w == rhs.w);
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                (*this)[i][j] = M::pl((*this)[i][j], M::inv_pl(rhs[i][j]));
            }
        }
        return *this;
    }
    matrix &operator*=(const matrix &rhs) {
        assert(w == rhs.h);
        std::vector<std::vector<T>> ret(h, std::vector<T>(rhs.w, M::id_pl()));
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < rhs.w; j++) {
                for (int k = 0; k < w; k++) {
                    ret[i][j] = M::pl(ret[i][j], M::cr((*this)[i][k], rhs[k][j]));
                }
            }
        }
        data = ret;
        h = data.size(), w = data[0].size();
        return *this;
    }
    matrix &operator/=(const matrix &rhs) { return *this *= rhs.inv(); }
    matrix operator+() const { return *this; }
    matrix operator-() const { return matrix(h, w) -= (*this); }
    matrix operator+(const matrix &rhs) const { return matrix(*this) += rhs; }
    matrix operator-(const matrix &rhs) const { return matrix(*this) -= rhs; }
    matrix operator*(const matrix &rhs) const { return matrix(*this) *= rhs; }
    matrix operator/(const matrix &rhs) const { return matrix(*this) /= rhs; }
    matrix inv() const {
        assert(h == w);
        matrix id = identity(h);
        std::vector<std::vector<T>> ex(h, std::vector<T>(w << 1));
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) { ex[i][j] = (*this)[i][j]; }
            for (int j = 0; j < w; j++) { ex[i][w + j] = id[i][j]; }
        }
        for (int i = 0; i < h; i++) {
            for (int j = i; j < w; j++) {
                if (!M::is_id_pl(ex[i][j])) {
                    swap(ex[i], ex[j]);
                    break;
                }
            }
            if (M::is_id_pl(ex[i][i])) { return matrix(0, 0); }
            T inv = M::inv_cr(ex[i][i]);
            for (int j = i + 1; j < w << 1; j++) { ex[i][j] = M::cr(ex[i][j], inv); }
            for (int j = i + 1; j < h; j++) {
                for (int k = i + 1; k < w << 1; k++) {
                    ex[j][k] = M::pl(ex[j][k], M::inv_pl(M::cr(ex[i][k], ex[j][i])));
                }
            }
        }
        for (int i = h - 1; i > 0; i--) {
            for (int j = i - 1; j >= 0; j--) {
                for (int k = w; k < w << 1; k++) {
                    ex[j][k] = M::pl(ex[j][k], M::inv_pl(M::cr(ex[i][k], ex[j][i])));
                }
            }
        }
        std::vector<std::vector<T>> ret(h, std::vector<T>(w));
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                ret[i][j] = ex[i][w + j];
            }
        }
        return ret;
    }
    matrix pow(long long n) const {
        assert(h == w);
        matrix ret = identity(h), mul = *this;
        while (n > 0) {
            if (n & 1) { ret *= mul; }
            mul *= mul;
            n >>= 1;
        }
        return ret;
    }
    friend std::ostream &operator<<(std::ostream &os, const matrix &rhs) {
        for (int i = 0; i < rhs.h; i++) {
            os << "[";
            for (int j = 0; j < rhs.w; j++) {
                os << rhs[i][j] << (j + 1 == rhs.w ? "]\n" : ",");
            }
        }
        return os;
    }
};

struct bool_mat {
    using T = bool;
    static T pl(const T &a, const T &b) { return a | b; }
    static T cr(const T &a, const T &b) { return a & b; }
    static T id_pl() { return 0; }
    static T id_cr() { return 1; }
    static T inv_pl(const T &a) { return 0; } // 本当はない
    static T inv_cr(const T &a) { return 0; } // 本当はない
    static bool is_id_pl(const T &a) { return a == 0; };
};

// Can I go there? 実装中
// 辺ベースでbool値の行列累乗をすればいけるはず

void solve(int N, int M, int Z) {
    vint s(M), d(M);
    vvint edx(N);
    vint rev(2 * M), to(2 * M);
    rep(i, M) {
        cin >> s[i] >> d[i];
        s[i]--, d[i]--;
        edx[s[i]].push_back(2 * i + 0), rev[2 * i + 0] = 2 * i + 1, to[2 * i + 0] = d[i];
        edx[d[i]].push_back(2 * i + 1), rev[2 * i + 1] = 2 * i + 0, to[2 * i + 1] = s[i];
    }
    matrix<bool_mat> a(M * 2 + 1, M * 2 + 1), b(M * 2 + 1, 1);
    b[M * 2][0] = 1;
    rep(i, edx[0].size()) { a[edx[0][i]][M * 2] = 1; }
    rep(i, M * 2) {
        int t = to[i];
        rep(j, edx[t].size()) { a[edx[t][j]][i] = 1; }
        a[rev[i]][i] = 0;
    }
    b = a.pow(Z) * b;
    bool ans = false;
    rep(i, M * 2) {
        if (to[i] == N - 1 && b[i][0]) { ans = true; }
    }
    if (ans) { cout << "yes" << endl; }
    else { cout << "no" << endl; }
}
signed main() {
    while (true) {
        int N, M, Z;
        cin >> N >> M >> Z;
        if (N == 0 && M == 0 && Z == 0) { break; }
        solve(N, M, Z);
    }
}
accuracy: 1
time_ms: 800
memory_kb: 3088
final_rank: 19

code_snippet: //全く思いつきもしない
//先に遷移行列をn乗したものを計算すれば良い
//NかけるNで行列作ると、行って戻るパターンは管理しきれない
//2*Nかける2*Nでいいのでは
//うーんわからん、辛いな
//今はどこにいるか次にどこに行きたいかで考えていたけど、それでは直前の情報を受け取れない
//どこにいたのか今どこにいるかを考える
//今いる位置を頂点 + どこから来たかで管理すれば良い．つまり，辺と向きで管理すれば良い．有向辺 (道 + 向き) に番号を振り，ある番号 (が表す辺) から次にどの番号 (があらわす辺) に行けるかを表すような遷移行列を作る
//頂点の個数ぶんの行と列を確保しようと考えていたが、今回は辺で確保する
//セグフォはくそ


#include<iostream>
#include<vector>
#include<utility>
#include<algorithm>
#include<sstream>
#include<bitset>
using namespace std;

typedef vector<vector<int>> mat;

mat mat_transpose(mat m,int length){
  mat new_m(length,vector<int>(length,0));
  for(int i=0;i<length;i++){
    for(int j=0;j<length;j++){
      new_m[i][j]=m[j][i];
    }
  }
  return new_m;
}

mat mat_mat_mult(mat m1,mat m2,int length){
  mat new_m(length,vector<int>(length,0));
  m2=mat_transpose(m2,length);
  for(int i=0;i<length;i++){
    for(int j=0;j<length;j++){
      for(int k=0;k<length;k++){
        new_m[i][j]+=m1[i][k]*m2[j][k];
      }
    }
  }
  return new_m;
}

vector<int> mat_vec_mult(mat m,vector<int> v,int length){
  vector<int> new_v(length);
  for(int i=0;i<length;i++){
    for(int j=0;j<length;j++){
      new_v[i]+=v[j]*m[i][j];
    }
  }
  return new_v;
}





int main(){
  int N,M,Z;
  int d,s;
  while(cin >> N >> M >> Z && N!=0){
    //cout << "a" << endl;
    vector<int> da(2*M,0);
    mat dp(2*M,vector<int>(2*M,0));
    vector<pair<int,int>> dp_sub(2*M);
    for(int i=0;i<M;i++){
      cin >> s >> d;
      dp_sub[i]=make_pair(d-1,s-1);dp_sub[i+M]=make_pair(s-1,d-1);
    }
    //ここまではOK
    for(int i=0;i<2*M;i++){
      //インデックスミス(修正済み)
      for(int j=0;j<2*M;j++){
        //ここで帰るパターンもOKになってるじゃないか、アホなのか
        //反対にしてしまっていた
        //やっと答えがあった
        if(dp_sub[i].first==dp_sub[j].second && dp_sub[i].second!=dp_sub[j].first){
          dp[i][j]=1;
        }
      }
    }
    //初期化
    for(int i=0;i<2*M;i++){
      if(dp_sub[i].first==0){da[i]=1;}
    }
    //ここを、繰り返し自乗法でやる(元はZ回愚直に回してた)
    //おーー32以内でできるすごい
    stringstream bitsts;
    string bits;

    //Z=1の時を考えると、ベクトルの初期化の時点でその道を通っていることになるので、Z-1が正しい
    //bitなので若干頭が混乱して訳のわからないコードを書きかけた
    bitsts << bitset<32>(Z-1);
    bits = bitsts.str();

    mat bitmemory[32];
    bitmemory[31]= dp;
    for(int i=31;i>0;i--){bitmemory[i-1]=mat_mat_mult(bitmemory[i],bitmemory[i],2*M);}

    stringstream bitsts_sub;
    string bits_sub;

    for(int i=0;i<32;i++){
      if(bits[i]=='1'){
        da=mat_vec_mult(bitmemory[i],da,2*M);
      }
    }

    int che=0;
    for(int i=0;i<2*M;i++){
      if(da[i]!=0 && dp_sub[i].second==N-1){
        che=1;cout << "yes" << endl;break;
      }
    }
    if(che==0){cout << "no" << endl;}
  }
}
accuracy: 1
time_ms: 230
memory_kb: 4644
final_rank: 9