#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
typedef long long ll;
typedef pair< int , int > pii;
typedef unsigned long long ull;
#ifndef ONLINE_JUDGE
void RI(vector< int >&a, int n){a.resize(n); for ( int i=0;i<n;i++) scanf ( "%d" ,&a[i]);}
void RI(){} void RI( int &X){ scanf ( "%d" ,&X);} template < typename ...R>
void RI( int &f,R&...r){RI(f);RI(r...);} void RI( int *p, int *q){ int d=p<q?1:-1;
while (p!=q){ scanf ( "%d" ,p);p+=d;}} void print(){cout<<endl;} template < typename T>
void print( const T t){cout<<t<<endl;} template < typename F, typename ...R>
void print( const F f, const R...r){cout<<f<< ", " ;print(r...);} template < typename T>
void print(T*p, T*q){ int d=p<q?1:-1; while (p!=q){cout<<*p<< ", " ;p+=d;}cout<<endl;}
#endif
template < typename T> bool umax(T&a, const T&b){ return b<=a? false :(a=b, true );}
template < typename T> bool umin(T&a, const T&b){ return b>=a? false :(a=b, true );}
template < typename T>
void V2A(T a[], const vector<T>&b){ for ( int i=0;i<b.size();i++)a[i]=b[i];}
template < typename T>
void A2V(vector<T>&a, const T b[]){ for ( int i=0;i<a.size();i++)a[i]=b[i];}
const double PI = acos (-1.0);
const int INF = 1e9 + 7;
/* -------------------------------------------------------------------------------- */
const int maxn = 107;
struct Graph {
vector<vector< int > > G;
void clear() { G.clear(); }
void resize( int n) { G.resize(n + 2); }
void add( int u, int v) { G[u].push_back(v); }
vector< int > & operator [] ( int u) { return G[u]; }
};
Graph G;
bool vis[maxn], flag[maxn];
int n;
int cnt[maxn], d[maxn], p[maxn];
bool dfs( int s, int t) {
if (s == t) return true ;
vis[s] = true ;
for ( int i = 0; i < G[s].size(); i ++) {
int v = G[s][i];
if (!vis[v]) if (dfs(v, t)) return true ;
}
return false ;
}
bool relax( int u, int v) {
if (d[u] + p[v] > d[v]) {
d[v] = d[u] + p[v];
return true ;
}
return false ;
}
bool work() {
queue< int > Q;
Q.push(1);
fillchar(d, 0);
fillchar(flag, 0);
fillchar(cnt, 0);
d[1] = 100;
flag[1] = true ;
while (!Q.empty()) {
int u = Q.front(); Q.pop();
flag[u] = false ;
if (u == n) return true ;
if (d[u] >= 1e8) {
fillchar(vis, 0);
if (dfs(u, n)) return true ;
}
int sz = G[u].size();
for ( int i = 0; i < sz; i ++) {
int v = G[u][i];
if (relax(u, v)) {
if (!flag[v]) {
flag[v] = true ;
if (cnt[v] > n) continue ;
if (cnt[v] == n) d[v] = INF;
Q.push(v);
cnt[v] ++;
}
}
}
}
return false ;
}
int main() {
#ifndef ONLINE_JUDGE
freopen ( "in.txt" , "r" , stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int m, v;
while (cin >> n, ~n) {
G.clear();
G.resize(n);
for ( int i = 1; i <= n; i ++) {
scanf ( "%d%d" , p + i, &m);
for ( int j = 0; j < m; j ++) {
scanf ( "%d" , &v);
G.add(i, v);
}
}
fillchar(vis, 0);
if (!dfs(1, n)) puts ( "hopeless" );
else puts (work()? "winnable" : "hopeless" );
}
return 0;
}
|