#include <stdio.h>
#include <iostream>
#include <vector>
#include <list>
#include <cmath>
#include <fstream>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <complex>
#include <iterator>
#include <cstdlib>
#include <cstring>
#include <sstream>

using namespace std;

#define EPS (1e-10)
#define EQ(a,b) (abs((a) - (b)) < EPS)
#define EQV(a,b) (EQ((a).real(),(b).real()) && EQ((a).imag(),(b).imag()))

typedef complex<double> P;
typedef long long ll;

const double INF=10000000000.0;
// »ê¼êÌm[hÔÉJÚÅ«éGbWª é©Ç¤©
double p[101][101],w[101][101];
bool passed[101];
vector<int> d[101];

int thisNode;
int cnt;
double minCost=INF;

const ll MOD=100000007;

ll dp[101][101];
ll cmb(int a,int b){
    if(dp[a][b]!=INF)
        return dp[a][b];
    if(a==b)
        return 1;
    if(b==1)
        return dp[a][b]=a;
    return dp[a][b]=((cmb(a-1,b)+cmb(a-1,b-1))%MOD);
}

// AÈOtðì¬µA»ÌOtÅÇÌ|µûªàÁÆàø¦ªÇ¢©ðvZ·é
void dfs(int s,bool start,vector<pair<double,double> > costs){
    // êüµÄ«½çAvZ
    if(passed[s]){
        thisNode=costs.size();
        // Ç±ÌêðÅÉÆé©Åêí¯
        double sum=0;
        for(int i = 0; i < costs.size(); i++)
            sum+=costs[i].second;
        for(int i = 0; i < costs.size(); i++){
            // ÅÌêðè
            double ss=sum-costs[i].second+costs[i].first;
            // ±ÌRXgªÅ¬RXgðXVÅ«é©Ç¤©
            if(!EQ(minCost,ss)&&minCost>ss){
                minCost=ss;
                cnt=1;
            }
            else if(EQ(minCost,ss))
                cnt++;
        }
        return;
    }
    passed[s]=true;
    for(int i = 0; i < d[s].size(); i++){
        int to=d[s][i];
        costs.push_back(make_pair(p[s][to],w[s][to]));
        dfs(to,false,costs);
    }
}

void solve(){

    int n;
    for(int i=0;i<101;i++)
        for(int j=0;j<101;j++)
            dp[i][j]=INF;
  //  ll tmp=(ll)(cmb(100,50)+EPS)%MOD;

    while(cin>>n&&n!=0){
        for(int i = 0; i < 101; i++){
            d[i].clear();
            for(int j = 0; j < 101; j++)
                p[i][j]=w[i][j]=INF;
        }

        for(int i = 0; i < n; i++){
            double pp,ww;
            int id;
            cin>>pp>>id>>ww;
            p[id][i]=1.0/pp;w[id][i]=1.0/ww;
            // ¹ðÇÁ
            d[id].push_back(i);
        }
        // OtðAÈàÌ²ÆÉµ¤
        // »ê¼êªÉÎµÄàÁÆàúÒlÌ¬³¢|µûðvZ·é
        // àµ¯¶lðÂàÌª êÎAL¯µÄ¨­
        memset(passed,0,sizeof(passed));
        int leftNode=n;
        ll mul=1;
        double SumOfminCost=0;
        for(int i = 0; i < n; i++){
            cnt=0;
            if(passed[i])
                continue;
            minCost=INF;
            thisNode=0;
            dfs(i,true,vector<pair<double,double> >());
            // cntÉÅRXgÌæèûªAüÁÄ¢éÌÅA»êà©¯é
            ll tmp=cmb(leftNode,thisNode);
            leftNode-=thisNode;
            mul*=cnt*tmp;
            mul%=MOD;
            SumOfminCost+=minCost;
        }
        mul%=MOD;
        //cout<<SumOfminCost<<" "<<mul<<endl;
        printf("%.10f %d\n",SumOfminCost,(int)mul);
    }
}
int main(){

    solve();

    return 0;
}

Measured memory_bytes: 1360