#include <bits/stdc++.h>

using namespace std;

#define rep(i,m,n) for(int (i)=(int)(m);i<(int)(n);i++)
#define REP(i,n) rep(i,0,n)
#define FOR(i,c) for(decltype((c).begin())i=(c).begin();i!=(c).end();++i)
#define ll long long
#define ull unsigned long long
#define all(hoge) (hoge).begin(),(hoge).end()
#define en '\n'
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
typedef pair<ll, ll> P;
const long long INF = 1LL << 60;
const int INF_INT = 1 << 25;
const long long MOD = (ll) 1e9 + 7;
typedef vector<ll> Array;
typedef vector<Array> Matrix;
const int loose = 0;
const int tight = 1;


template<class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

struct Edge {
	ll to, cap, rev;
	Edge(ll _to, ll _cap, ll _rev) {
	to = _to; cap = _cap; rev = _rev;
	}
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

void add_edge(Graph& G, ll from, ll to, ll cap, bool revFlag, ll revCap) {
	G[from].push_back(Edge(to, cap, (ll)G[to].size()));
	if (revFlag)G[to].push_back(Edge(from, revCap, (ll)G[from].size() - 1));
}

class UnionFind {
 vector<int> data;
 int num;
public:
 UnionFind(int size) : data(size, -1), num(size) { }
 bool unionSet(int x, int y) {
  x = root(x); y = root(y);
  if (x != y) {
   if (data[y] < data[x]) swap(x, y);
   data[x] += data[y]; data[y] = x;
   num--;
  }
  return x != y;
 }
 bool findSet(int x, int y) {
  return root(x) == root(y);
 }
 int root(int x) {
  return data[x] < 0 ? x : data[x] = root(data[x]);
 }
 int size(int x) {
  return -data[root(x)];
 }
 int numSet() {
  return num;
 }
};

//強連結成分分解
class SCC{
	Graph g,rg;
	vector<int> cmp,used,vs;
	int size;
public:
	SCC(Graph _g):g(_g),rg(g.size()),cmp(g.size(),-1),used(g.size(),false){
		REP(i,g.size()){
			for(auto e:g[i]){
				add_edge(rg,e.to,i,1,false,0);//逆辺のグラフ
			}
		}

		REP(i,g.size()){
			if(!used[i]) dfs(i);
		}
		int k=0;
		
		REP(i,vs.size()){
			ll v=vs[vs.size()-1-i];
			if(used[v]){
				rdfs(v,k);
				k++;
			}
		}
		size=k;
	}

	void dfs(int v){
		//帰りがけ順に番号を振る
		used[v]=true;
		for(auto e:g[v]){
			if(!used[e.to]) dfs(e.to);
		}
		vs.push_back(v);
	}

	void rdfs(int v, int k){
		//通ることができた頂点に番号を振る
		used[v]=false;
		cmp[v]=k;
		for(auto e:rg[v]){
			if(used[e.to]) rdfs(e.to,k);
		}
	}

	int getSize(){
		return size;
	}

	int group(int v){
		return cmp[v];
	}
};

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

	while(true){
		ll n;
		cin>>n;
		if(n==0) break;
		vector<double> p(n);
		Graph g(n);
		REP(i,n){
			cin>>p[i];
			ll m;
			cin>>m;

			REP(j,m){
				ll b;
				cin>>b;
				b--;
				add_edge(g,i,b,1,false,1);
			}
		}

		SCC scc(g);

		vector<int> in(scc.getSize());//入次数
		REP(i,g.size()){
			int u=scc.group(i);
			for(auto e:g[i]){
				int v=scc.group(e.to);
				if(u==v) continue;
				in[v]++;
			}
		}

		vector<double> dp(in.size(),1.0);//各グループことの寝坊率
		REP(i,g.size()){
			int u=scc.group(i);
			dp[u]*=p[i];
		}

		double ans=1.0;
		REP(i,in.size()){
			if(in[i]!=0) continue;
			ans *= (1.0-dp[i]);
		}

		cout<<fixed<<setprecision(8)<<ans<<endl;
	}

    return 0;
}
