#include <bits/stdint-intn.h>

#include <algorithm>
#include <cstddef>
#include <ctime>
#include <iostream>
#include <map>
#include <memory>
#include <queue>
#include <string>
#include <unordered_map>
#include <vector>

using namespace std;

const long long mod = 1e9 + 7;

int a[1000], n;

int64_t fac[1000], inv_fac[1000];

int64_t pw(int64_t x, int64_t y) {
  int64_t res = 1;
  while (y) {
    if (y & 1) {
      res = (res * x) % mod;
    }
    y >>= 1;
    x = (x * x) % mod;
  }
  return res;
}

void dfs(std::vector<bool>& is_valid, std::vector<std::pair<uint64_t, int>>& v,
         int k, int m, int mask, std::vector<uint64_t>& sets) {
  if (k == m) {
    is_valid[mask] = sets.size() < 2;
    return;
  }
  dfs(is_valid, v, k + 1, m, mask, sets);
  std::vector<uint64_t> new_sets;
  uint64_t new_mask = v[k].first;
  for (auto x : sets) {
    if (new_mask & x) {
      new_mask |= x;
    } else {
      new_sets.push_back(x);
    }
  }
  new_sets.push_back(new_mask);
  dfs(is_valid, v, k + 1, m, (mask | (1 << k)), new_sets);
}

int main() {
  cin >> n;
  for (int i = 0; i < n; i++) cin >> a[i];

  fac[0] = inv_fac[0] = 1;
  for (int i = 1; i < 1000; i++) {
    fac[i] = (fac[i - 1] * i) % mod;
    inv_fac[i] = (inv_fac[i - 1] * pw(i, mod - 2)) % mod;
  }

  vector<int> is_root(n, 0);
  vector<int> component_root(n, -1);
  vector<vector<int>> children(n), parents(n), components(n);
  for (int i = 0; i < n; i++) {
    is_root[i] = true;
    for (int j = 0; j < n; j++)
      if (j != i) {
        if (a[i] % a[j] == 0) {
          is_root[i] = false;
          break;
        }
      }
    int child_cnt = 0;
    for (int j = 0; j < n; j++) {
      if (j != i && a[j] % a[i] == 0) {
        child_cnt++;
      }
    }
    if (child_cnt < 2) is_root[i] = false;

    // if (is_root[i]) cerr << i << ' ' << a[i] << ' ' << child_cnt << endl;
  }

  for (int i = 0; i < n; i++) {
    if (is_root[i] && component_root[i] == -1) {
      component_root[i] = i;
      queue<int> q;
      // cerr << i << ' ';
      q.push(i);
      while (!q.empty()) {
        int x = q.front();
        q.pop();
        for (int j = 0; j < n; j++) {
          if (is_root[j] && component_root[j] == -1) {
            for (int k = 0; k < n; k++) {
              if (!is_root[k] && a[k] % a[x] == 0 && a[k] % a[j] == 0) {
                // if (a[k] == 30) {
                // cerr << "xxx " << a[i] << ' ' << a[j] << ' ' << endl;
                //}
                component_root[j] = i;
                q.push(j);
                // cerr << j << ' ';
                break;
              }
            }
          }
        }
      }
    }
    // cerr << endl;
  }

  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) {
      if (j != i && a[i] % a[j] == 0) {
        if (is_root[j]) {
          children[j].push_back(i);
          parents[i].push_back(j);
        }
      }
    }

  int64_t res = 1;
  int tot_cnt = 0;
  for (int i = 0; i < n; i++) {
    if (is_root[i] && component_root[i] == i) {
      std::vector<int> i_children, i_roots;
      for (int j = 0; j < n; j++) {
        if ((is_root[j] && component_root[j] == i)) {
          i_roots.push_back(j);
        } else if (!is_root[j] && parents[j].size() > 0 &&
                   component_root[parents[j][0]] == i) {
          i_children.push_back(j);
        }
      }

      std::cerr << a[i] << endl;
      for (auto x : i_roots) {
        std::cerr << a[x] << ' ';
      }
      cerr << endl;
      for (auto x : i_children) {
        cerr << a[x] << ' ';
      }
      std::cerr << endl;
      std::cerr << i_children.size() << " ---" << endl;

      int children_cnt = i_children.size();
      map<uint64_t, int> child_cnts_map;
      for (int x : i_children) {
        uint64_t key = 0;
        for (auto k : parents[x]) {
          key |= (1ll << k);
        }
        child_cnts_map[key]++;
      }
      cerr << child_cnts_map.size() << endl;

      int m = child_cnts_map.size();
      std::vector<std::pair<uint64_t, int>> child_cnts(child_cnts_map.begin(),
                                                       child_cnts_map.end());
      sort(child_cnts.begin(), child_cnts.end(),
           [](const auto& a, const auto& b) {
             return __builtin_popcountll(a.first) >
                    __builtin_popcountll(b.first);
           });
      int max_m = 0;
      for (; max_m < m; max_m++)
        if (__builtin_popcountll(child_cnts[max_m].first) == 1) break;

      /* auto is_status_valid = [&child_cnts, &m](uint64_t bitmask) -> bool {
        vector<uint64_t> regions;
        vector<uint64_t> new_regions;
        for (int i = 0; i < m; i++)
          if (1 & (bitmask >> i)) {
            new_regions.clear();
            uint64_t new_mask = child_cnts[i].first;
            for (auto r : regions) {
              if ((r & child_cnts[i].first)) {
                new_mask |= r;
              } else
                new_regions.push_back(r);
            }
            new_regions.push_back(new_mask);
            regions.swap(new_regions);
          }
        return regions.size() <= 1;
      };*/
      // vector<vector<int64_t>> is_valid(1 << m);
      // int max_connection = 0;
      // for (int i = 0; i < m; i++) {
      //}

      vector<bool> is_valid(1 << m);
      vector<uint64_t> _v;
      dfs(is_valid, child_cnts, 0, m, 0, _v);

      /*cout << child_cnts[0].first << "xxxxxxxxx"*/
      // for (int i = 0; i < (1 << m); i++) {
      // if (is_valid[i]) cerr << i << ' ';
      //}

      cerr << time(NULL) << endl;

      vector<int64_t> p(1 << m);
      vector<int> sum(1 << m);

      p[(1 << m) - 1] = 1;
      sum[(1 << m) - 1] = 0;
      for (int bitmask = (1 << m) - 1; bitmask > 0; bitmask--) {
        if (p[bitmask]) {
          for (int k = 0; k < m; k++)
            if ((1 & (bitmask >> k))) {
              int new_sum = sum[bitmask ^ (1 << k)] =
                  sum[bitmask] + child_cnts[k].second;

              int new_bitmask = bitmask ^ (1 << k);
              if (is_valid[new_bitmask]) {
                int add = child_cnts[k].second;
                p[new_bitmask] +=
                    p[bitmask] *
                    (((fac[new_sum - 1] * inv_fac[sum[bitmask]]) % mod * add) %
                     mod) %
                    mod;
                p[new_bitmask] %= mod;
              }
            }
        }
      }
      cerr << time(NULL) << endl;

      res *= p[0];
      res %= mod;
      res *= fac[children_cnt - 1 + tot_cnt];
      res %= mod;
      res *= inv_fac[children_cnt - 1];
      res %= mod;
      res *= inv_fac[tot_cnt];
      res %= mod;
      tot_cnt += children_cnt - 1;
    }
  }

  cout << res << endl;
  return 0;
}


#define DEBUG 0

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

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------
#define MOD 1000000007

int inv(int n) {
    int e = MOD-2,r = 1;
    while (e > 0) {
        if (e & 1) r = ((LLI) r*n) % MOD;
        e >>= 1;
        n = ((LLI) n*n) % MOD;
    }
    return r;
}
int P[7][7];
int a[128],b[8][128],c[8];
vpii v[7],v2[3];
vector<pair<LLI,int> > v3,v4;
int main() {
    int i,j;
    int n;
    scanf("%d",&n);
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) scanf("%d",&P[i][j]);
    }
    for (i = n; i < 7; i++) P[i][i] = 100;

    int k,l,m;
    int inv100 = inv(100);
    for (i = 0; i < 7; i++) {
        for (j = 0; j < 128; j++) {
            LLI p = 1;
            for (k = 0; k < 7; k++) {
                if (j & (1 << k)) p *= ((LLI) P[k][i]*inv100) % MOD,p %= MOD;
                else p *= ((LLI) (100-P[k][i])*inv100) % MOD,p %= MOD;
            }
            v[i].pb(mp(j,p));
        }
    }
    for (i = 0; i < 128; i++) {
        int x = 0;
        for (j = 0; j < 7; j++) {
            if (i & (1 << j)) x++;
        }
        a[i] = c[x]++,b[x][a[i]] = i;
    }
    for (i = 0; i < 6; i += 2) {
        vpii temp;
        for (j = 0; j < v[i].size(); j++) {
            for (k = 0; k < v[i+1].size(); k++) {
                int poss = 0;
                for (l = 0; l < 7; l++) {
                    for (m = 0; m < 7; m++) {
                        if (l != m) {
                            if ((v[i][j].first & (1 << l)) && (v[i+1][k].first & (1 << m))) poss |= (1 << a[(1 << l) | (1 << m)]);
                        }
                    }
                }
                temp.pb(mp(poss,((LLI) v[i][j].second*v[i+1][k].second) % MOD));
            }
        }
        sort(temp.begin(),temp.end());
        for (j = 0; j < temp.size(); j++) {
            if (v2[i/2].empty() || (temp[j].first != v2[i/2].back().first)) v2[i/2].pb(temp[j]);
            else v2[i/2].back().second += temp[j].second,v2[i/2].back().second %= MOD;
        }
    }
    vector<pair<LLI,int> > temp;
    for (i = 0; i < v2[0].size(); i++) {
        for (j = 0; j < v2[1].size(); j++) {
            LLI poss = 0;
            for (k = 0; k < 21; k++) {
                for (l = 0; l < 21; l++) {
                    if ((b[2][k] & b[2][l]) == 0) {
                        if ((v2[0][i].first & (1 << k)) && (v2[1][j].first & (1 << l))) poss |= (1LL << a[b[2][k] | b[2][l]]);
                    }
                }
            }
            temp.pb(mp(poss,((LLI) v2[0][i].second*v2[1][j].second) % MOD));
        }
    }
    sort(temp.begin(),temp.end());
    for (j = 0; j < temp.size(); j++) {
        if (v3.empty() || (temp[j].first != v3.back().first)) v3.pb(temp[j]);
        else v3.back().second += temp[j].second,v3.back().second %= MOD;
    }
    temp.clear();
    for (i = 0; i < v2[2].size(); i++) {
        for (j = 0; j < v[6].size(); j++) {
            LLI poss = 0;
            for (k = 0; k < 21; k++) {
                for (l = 0; l < 7; l++) {
                    if ((b[2][k] & b[1][l]) == 0) {
                        if ((v2[2][i].first & (1 << k)) && (v[6][j].first & (1 << l))) poss |= (1LL << a[b[2][k] | b[1][l]]);
                    }
                }
            }
            temp.pb(mp(poss,((LLI) v2[2][i].second*v[6][j].second) % MOD));
        }
    }
    sort(temp.begin(),temp.end());
    for (j = 0; j < temp.size(); j++) {
        if (v4.empty() || (temp[j].first != v4.back().first)) v4.pb(temp[j]);
        else v4.back().second += temp[j].second,v4.back().second %= MOD;
    }
    int ans = 0;
    for (i = 0; i < v3.size(); i++) {
        LLI r = 0;
        for (j = 0; j < 35; j++) {
            if (v3[i].first & (1LL << j)) r |= (1LL << (34-j));
        }
        for (j = 0; j < v4.size(); j++) {
            if ((r & v4[j].first) > 0) ans += ((LLI) v3[i].second*v4[j].second) % MOD,ans %= MOD;
        }
    }
    printf("%d\n",ans);

    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>P;
typedef vector<P>V;
const int N=1e5+5;
int n,m,u,v,w,i;
V e[N],ev[N];
inline V stre(V v,int l){
	static P a[N];int w=0;
if(v.size()>5)
++l,--l;
	for(auto u:v){
		int x,y,xx,yy;tie(x,y)=u;
		for(;tie(xx,yy)=a[w],w && yy<0 && y>0 && xx>=x-l;){
			if(y+yy<0)a[w].second+=y,y=0;
				else if(y+yy>0)y+=yy,--w;else --w,y=0;
			if(!y)break;
		}
		if(y)a[++w]={y>0?x-l:x+l,y};
	}
	return V(a+1,a+w+1);
}
inline V mer(V a,V b){
	static P c[N];int w=0,i=0,j=0;
	for(;i<a.size() || j<b.size();){
		P u=i<a.size() && (j==b.size() || a[i]<b[j])?a[i++]:b[j++];
		if(w && c[w].first==u.first){
			c[w].second+=u.second;
			if(!c[w].second)--w;
		}else c[++w]=u;
	}
	return V(c+1,c+w+1);
}
inline void ins(V&v,P u){
	auto it=lower_bound(v.begin(),v.end(),u);
	if(it!=v.end() && it->first==u.first){
		it->second+=u.second;
		if(!it->second)v.erase(it);
	}else v.insert(it,u);
}
inline int getv(const V&v,int k){
	int ans=0;
	for(auto u:v)if(u.first<=k)ans+=u.second;
	return ans;
}
V dfs(int x,int fa){
	V vv;
	for(auto u:e[x]){
		int y,l;tie(y,l)=u;
		if(y==fa)continue;
		vv=mer(vv,stre(dfs(y,x),2*l-1));
	}
	for(auto&u:ev[x])u.second+=getv(vv,u.first);
	vv=stre(vv,1);
	for(auto u:ev[x]){
		int x,y,z;tie(x,y)=u;z=getv(vv,x);
		if(y>z)ins(vv,{x,y-z}),ins(vv,{x+1,z-y});
	}
	return vv;
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n;
	for(i=1;i<n;++i){
		cin>>u>>v>>w;
		e[u].push_back({v,w});
		e[v].push_back({u,w});
	}
	cin>>m;
	for(i=1;i<=m;++i){
		cin>>w>>v>>u;
		ev[u].push_back({w*2,v});
	}
	auto z=dfs(1,0);int ans=0,zz=0;
	for(auto U:z)ans=max(ans,zz+=U.second);
	cout<<ans<<endl;
}


#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <bitset>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define li       	long long int
#define rep(i,to)	for(li i=0;i<((li)(to));++i)
#define pb       	push_back
#define sz(v)    	((li)(v).size())
#define bit(n)   	(1ll<<(li)(n))
#define all(vec)	(vec).begin(),(vec).end()
#define each(i,c)	\
for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
typedef pair<li,li> PI;
#define MP make_pair
#define F first
#define S second

///////////////////////////////////////////////////////////
//////        "multiple precision integer"         ////////
//////            "irrational class"               ////////
//////       these classes have 680 lines.         ////////
//////   my main answer may be below this class.   ////////
///////////////////////////////////////////////////////////

class MPI{
#define MPI_DIGIT 6
#define MPI_MAX 1000000
public:
	vector<li> MPI_VALUE;
	bool MPI_SIGN;

	MPI(const string &mpi_s){
		MPI_SIGN=false;
		if(sz(mpi_s)){
			if(mpi_s[0]=='-') MPI_SIGN=true;
			for(li i=sz(mpi_s)-1;((mpi_s[0]=='-')?1:0)<=i;i-=MPI_DIGIT){
				li mpi_sum=0;
				li mpi_base=1;
				rep(j,MPI_DIGIT)if(((mpi_s[0]=='-')?1:0)<=i-j){
					mpi_sum+=(mpi_s[i-j]-'0')*mpi_base;
					mpi_base*=10;
				}
				MPI_VALUE.pb(mpi_sum);
			}
		}
		mpi_reform(*this);
	}

	MPI(const vector<li> &mpi_vec){
		MPI_SIGN=false;
		MPI_VALUE=mpi_vec;
		mpi_reform(*this);
	}

	MPI(int mpi_val){
		MPI_SIGN=false;
		if(mpi_val<0){ mpi_val=-mpi_val; MPI_SIGN=true; }
		while(mpi_val){
			MPI_VALUE.pb(mpi_val%MPI_MAX);
			mpi_val/=MPI_MAX;
		}
		mpi_reform(*this);
	}

	MPI(li mpi_val){
		MPI_SIGN=false;
		if(mpi_val<0){ mpi_val=-mpi_val; MPI_SIGN=true; }
		while(mpi_val){
			MPI_VALUE.pb(mpi_val%MPI_MAX);
			mpi_val/=MPI_MAX;
		}
		mpi_reform(*this);
	}

	MPI(bool mpi_need0,bool mpi_need1){
		MPI_SIGN=false;
	}

	MPI(){
		MPI_SIGN=false;
		MPI_VALUE.pb(0);
	}

	string to_string() const{
		string mpi_res="";
		li mpi_p10[MPI_DIGIT+1];
		rep(i,MPI_DIGIT+1) mpi_p10[i]=(i)?(mpi_p10[i-1]*10):1;
		for(li i=sz(MPI_VALUE)-1;0<=i;i--)rep(j,MPI_DIGIT){
			li mpi_tmp=(MPI_VALUE[i]%mpi_p10[MPI_DIGIT-j])/mpi_p10[MPI_DIGIT-j-1];
			if(sz(mpi_res) || mpi_tmp) mpi_res+=string(1,'0'+mpi_tmp);
		}
		if(sz(mpi_res)==0) mpi_res+="0";
		else if(MPI_SIGN) mpi_res="-"+mpi_res;
		return mpi_res;
	}

	li to_long() const{
		li mpi_res=0;
		li mpi_base=1;
		rep(i,sz(MPI_VALUE)){
			mpi_res+=MPI_VALUE[i]*mpi_base;
			mpi_base*=MPI_MAX;
		}
		if(MPI_SIGN) mpi_res=-mpi_res;
		return mpi_res;
	}

	li size() const{
		li mpi_res=(sz(MPI_VALUE)-1)*MPI_DIGIT;
		li mpi_tmp=MPI_VALUE.back();
		while(mpi_tmp){ mpi_res++; mpi_tmp/=10; }
		return mpi_res;
	}

	static MPI mpi_abs_add(const MPI &mpi0,const MPI &mpi1){
		MPI mpi_res(false,false);
		li carry=0;
		rep(i,max(sz(mpi0.MPI_VALUE),sz(mpi1.MPI_VALUE))){
			li mpi_t0=(i<sz(mpi0.MPI_VALUE))?(mpi0.MPI_VALUE[i]):0;
			li mpi_t1=(i<sz(mpi1.MPI_VALUE))?(mpi1.MPI_VALUE[i]):0;
			li mpi_t=mpi_t0+mpi_t1+carry;
			mpi_res.MPI_VALUE.pb(mpi_t%MPI_MAX);
			carry=mpi_t/MPI_MAX;
		}
		if(carry) mpi_res.MPI_VALUE.pb(carry);
		mpi_reform(mpi_res);
		return mpi_res;
	}

	static MPI mpi_abs_sub_sub(const MPI &mpi0,const MPI &mpi1){
		MPI mpi_res(false,false);
		mpi_res.MPI_VALUE=mpi0.MPI_VALUE;
		li carry=0;
		for(li i=0;i<sz(mpi1.MPI_VALUE) || carry;i++){
			mpi_res.MPI_VALUE[i]-=carry;
			carry=0;
			if(i<sz(mpi1.MPI_VALUE)) mpi_res.MPI_VALUE[i]=mpi_res.MPI_VALUE[i]-mpi1.MPI_VALUE[i];
			if(mpi_res.MPI_VALUE[i]<0){
				carry++;
				mpi_res.MPI_VALUE[i]+=MPI_MAX;
			}
		}
		mpi_reform(mpi_res);
		return mpi_res;
	}

	static MPI mpi_abs_sub(const MPI &mpi0,const MPI &mpi1){
		if(!mpi_abs_gt(mpi0,mpi1)) return mpi_abs_sub_sub(mpi0,mpi1);
		MPI mpi_res=mpi_abs_sub_sub(mpi1,mpi0);
		mpi_res.MPI_SIGN=!mpi_res.MPI_SIGN;
		return mpi_res;
	}

	static MPI mpi_abs_mul(const MPI &mpi0,const MPI &mpi1){
		MPI mpi_res(false,false);
		mpi_res.MPI_VALUE=vector<li>(sz(mpi0.MPI_VALUE)+sz(mpi1.MPI_VALUE),0);
		rep(i,sz(mpi0.MPI_VALUE))if(mpi0.MPI_VALUE[i]){
			rep(j,sz(mpi1.MPI_VALUE)){
				mpi_res.MPI_VALUE[i+j]+=mpi0.MPI_VALUE[i]*mpi1.MPI_VALUE[j];
			}
		}
		mpi_add_mul_reform(mpi_res);
		return mpi_res;
	}

	MPI operator+(const MPI &mpi_var)const{
		bool b0=MPI_SIGN,b1=mpi_var.MPI_SIGN;
		if(!b0 &&!b1) return mpi_abs_add(*this,mpi_var);
		if(!b0 && b1) return mpi_abs_sub(*this,mpi_var);
		if( b0 &&!b1) return mpi_abs_sub(mpi_var,*this);
		MPI mpi_res=mpi_abs_add(*this,mpi_var);
		mpi_res.MPI_SIGN= !mpi_res.MPI_SIGN;
		return mpi_res;
	}

	MPI operator-(const MPI &mpi_var)const{
		bool b0=MPI_SIGN,b1=mpi_var.MPI_SIGN;
		if(!b0&&!b1) return mpi_abs_sub(*this,mpi_var);
		if(!b0&& b1) return mpi_abs_add(*this,mpi_var);
		if( b0&& b1) return mpi_abs_sub(mpi_var,*this);
		MPI mpi_res=mpi_abs_add(*this,mpi_var);
		mpi_res.MPI_SIGN= !mpi_res.MPI_SIGN;
		return mpi_res;
	}

	MPI operator*(const MPI &mpi_var)const{
		bool b0=MPI_SIGN,b1=mpi_var.MPI_SIGN;
		if( b0&& b1) return mpi_abs_mul(*this,mpi_var);
		if(!b0&&!b1) return mpi_abs_mul(*this,mpi_var);
		MPI mpi_res=mpi_abs_mul(*this,mpi_var);
		mpi_res.MPI_SIGN= !mpi_res.MPI_SIGN;
		return mpi_res;
	}

	friend std::ostream& operator<<(std::ostream& os,const MPI &mpi_var){
		os<<mpi_var.to_string();
		return os;
	}

	friend std::istream& operator>>(std::istream& is,MPI &mpi_var){
		string mpi_str;
		is>>mpi_str;
		mpi_var=MPI(mpi_str);
		return is;
	}

	static void mpi_subst(MPI &mpi_from,const MPI &mpi_base,li mpi_cons,li mpi_shift){
		li carry=0;
		for(li i=0;i+mpi_shift<sz(mpi_from.MPI_VALUE);i++){
			mpi_from.MPI_VALUE[mpi_shift+i]-=carry;
			carry=0;
			if(i<sz(mpi_base.MPI_VALUE)){
				carry=(mpi_base.MPI_VALUE[i]*mpi_cons)/MPI_MAX;
				mpi_from.MPI_VALUE[mpi_shift+i]-=(mpi_base.MPI_VALUE[i]*mpi_cons)%MPI_MAX;
			}
			while(mpi_from.MPI_VALUE[mpi_shift+i]<0){
				carry++;
				mpi_from.MPI_VALUE[mpi_shift+i]+=MPI_MAX;
			}
		}
	}

	static bool mpi_can_sub(const MPI &mpi_from,const MPI &mpi_base,li mpi_cons,li mpi_shift){
		li carry=0;
		for(li i=0;i+mpi_shift<sz(mpi_from.MPI_VALUE);i++){
			li mpi_tmp=carry;
			if(i<sz(mpi_base.MPI_VALUE)) mpi_tmp+=mpi_base.MPI_VALUE[i]*mpi_cons;
			li mpi_dif=(mpi_tmp-mpi_from.MPI_VALUE[i+mpi_shift]);
			if(mpi_dif<0) carry=0;
			else carry=((mpi_dif%MPI_MAX)?1:0)+mpi_dif/MPI_MAX;
		}
		return carry==0;
	}

	static MPI mpi_abs_div_small(const MPI &mpi_den,const MPI &mpi_num,bool is_div){
		MPI mpi_ans(false,false);
		MPI mpi_rem(mpi_den.MPI_VALUE);
		mpi_ans.MPI_VALUE=vector<li>(sz(mpi_rem.MPI_VALUE),0);
		li mpi_cons=abs(mpi_num.to_long()),carry=0;
		for(li i=sz(mpi_rem.MPI_VALUE)-1;0<=i;i--){
			mpi_rem.MPI_VALUE[i]+=carry*MPI_MAX;
			carry=mpi_rem.MPI_VALUE[i]%mpi_cons;
			mpi_ans.MPI_VALUE[i]=mpi_rem.MPI_VALUE[i]/mpi_cons;
		}
		if(!is_div) return MPI(carry);
		mpi_reform(mpi_ans);
		return mpi_ans;
	}

	static MPI mpi_abs_div(const MPI &mpi_den,const MPI &mpi_num,bool is_div){
		if(mpi_abs_gt(mpi_num,MPI_MAX)) return mpi_abs_div_small(mpi_den,mpi_num,is_div);
		MPI mpi_ans(0);
		MPI mpi_rem(mpi_den.MPI_VALUE);
		mpi_ans.MPI_VALUE=vector<li>(sz(mpi_rem.MPI_VALUE),0);
		li mpi_num_pos=sz(mpi_num.MPI_VALUE)-1;
		li mpi_num_n=mpi_num.MPI_VALUE[mpi_num_pos];

		if(mpi_num_n*MPI_MAX<1000000000000000000ll/MPI_MAX && 1<=mpi_num_pos){
			mpi_num_n=mpi_num_n*MPI_MAX+mpi_num.MPI_VALUE[--mpi_num_pos];
		}

		while(!mpi_abs_gt(mpi_rem,mpi_num)){
			li mpi_rem_pos=sz(mpi_rem.MPI_VALUE)-1;
			li mpi_rem_n=mpi_rem.MPI_VALUE[mpi_rem_pos];
			while(mpi_rem_n<mpi_num_n){
				mpi_rem_n=mpi_rem_n*MPI_MAX+mpi_rem.MPI_VALUE[--mpi_rem_pos];
			}
			li mpi_tmp=mpi_rem_n/mpi_num_n;
			li mpi_dif=mpi_rem_pos-mpi_num_pos;
			while(!mpi_can_sub(mpi_rem,mpi_num,mpi_tmp,mpi_dif)) mpi_tmp--;
			if(mpi_tmp==0){
				mpi_rem_n=mpi_rem_n*MPI_MAX+mpi_rem.MPI_VALUE[--mpi_rem_pos];
				mpi_tmp=mpi_rem_n/mpi_num_n;
				mpi_dif=mpi_rem_pos-mpi_num_pos;
				while(!mpi_can_sub(mpi_rem,mpi_num,mpi_tmp,mpi_dif)) mpi_tmp--;
			}
			mpi_subst(mpi_rem,mpi_num,mpi_tmp,mpi_dif);
			mpi_ans.MPI_VALUE[mpi_dif]+=mpi_tmp;
			mpi_reform(mpi_rem);
		}
		if(!is_div) return mpi_rem;
		mpi_add_mul_reform(mpi_ans);
		return mpi_ans;
	}

	MPI operator/(const MPI &mpi_var)const{
		bool b0=MPI_SIGN,b1=mpi_var.MPI_SIGN;
		if(!b0&&!b1) return mpi_abs_div(*this,mpi_var,true);
		if( b0&& b1) return mpi_abs_div(*this,mpi_var,true);
		MPI mpi_res=mpi_abs_div(*this,mpi_var,true);
		mpi_res.MPI_SIGN=!mpi_res.MPI_SIGN;
		return mpi_res;
	}

	MPI operator%(const MPI &mpi_var)const{
		bool b0=MPI_SIGN;
		if(!b0) return mpi_abs_div(*this,mpi_var,false);
		MPI mpi_res=mpi_abs_div(*this,mpi_var,false);
		mpi_res.MPI_SIGN=!mpi_res.MPI_SIGN;
		return mpi_res;
	}

	bool operator<(const MPI &mpi_var)const{
		bool b0=MPI_SIGN,b1=mpi_var.MPI_SIGN;
		if(!b0&&!b1) return mpi_abs_gt(*this,mpi_var);
		if( b0&& b1) return mpi_abs_sl(*this,mpi_var);
		if(sz(this->MPI_VALUE)==1 && sz(mpi_var.MPI_VALUE)==1){
			if(this->MPI_VALUE.back()==0 && mpi_var.MPI_VALUE.back()==0) return true;
		}
		if( b0&&!b1) return true;
		if(!b0&& b1) return false;
	}

	bool operator>(const MPI &mpi_var)const{
		bool b0=MPI_SIGN,b1=mpi_var.MPI_SIGN;
		if(!b0&&!b1) return mpi_abs_sl(*this,mpi_var);
		if( b0&& b1) return mpi_abs_gt(*this,mpi_var);
		if(sz(this->MPI_VALUE)==1 && sz(mpi_var.MPI_VALUE)==1){
			if(this->MPI_VALUE.back()==0 && mpi_var.MPI_VALUE.back()==0) return true;
		}
		if( b0&&!b1) return false;
		if(!b0&& b1) return true;
	}

	bool operator==(const MPI &mpi_var)const{
		bool b0=MPI_SIGN,b1=mpi_var.MPI_SIGN;
		if( b0&& b1) return mpi_abs_eq(*this,mpi_var);
		if(!b0&&!b1) return mpi_abs_eq(*this,mpi_var);
		if(sz(this->MPI_VALUE)==1 && sz(mpi_var.MPI_VALUE)==1){
			if(this->MPI_VALUE.back()==0 && mpi_var.MPI_VALUE.back()==0) return true;
		}
		return false;
	}

	bool operator>=(const MPI &mpi_var)const{ return !(*this<mpi_var); }
	bool operator<=(const MPI &mpi_var)const{ return !(*this>mpi_var); }
	bool operator!=(const MPI &mpi_var)const{ return !(*this==mpi_var); }
	void operator+=(const MPI &mpi_var){ *this=*this+mpi_var; }
	void operator-=(const MPI &mpi_var){ *this=*this-mpi_var; }
	void operator*=(const MPI &mpi_var){ *this=*this*mpi_var; }
	void operator/=(const MPI &mpi_var){ *this=*this/mpi_var; }
	void operator%=(const MPI &mpi_var){ *this=*this%mpi_var; }
	friend bool operator>(li mpi_li,const MPI &mpi_var){ return MPI(mpi_li)>mpi_var; }
	friend bool operator<(li mpi_li,const MPI &mpi_var){ return MPI(mpi_li)<mpi_var; }
	friend bool operator>=(li mpi_li,const MPI &mpi_var){ return MPI(mpi_li)>=mpi_var; }
	friend bool operator<=(li mpi_li,const MPI &mpi_var){ return MPI(mpi_li)<=mpi_var; }
	friend bool operator!=(li mpi_li,const MPI &mpi_var){ return MPI(mpi_li)!=mpi_var;}
	friend bool operator==(li mpi_li,const MPI &mpi_var){ return MPI(mpi_li)==mpi_var;}

	MPI operator--(){ *this=*this-MPI(1); return *this; }
	MPI operator++(){ *this=*this+MPI(1); return *this; }
	MPI operator++(int mpi_i){
		MPI mpi_res=*this;
		*this=*this+MPI(1);
		return mpi_res;
	}
	MPI operator--(int mpi_i){
		MPI mpi_res=*this;
		*this=*this-MPI(1);
		return mpi_res;
	}
	MPI operator-(){
		MPI mpi_res=*this;
		mpi_res.MPI_SIGN=!mpi_res.MPI_SIGN;
		return mpi_res;
	}

	static bool mpi_abs_gt(const MPI &mpi0,const MPI &mpi1){
		if(sz(mpi0.MPI_VALUE)==sz(mpi1.MPI_VALUE)){
			for(li i=sz(mpi0.MPI_VALUE)-1;0<=i;i--){
				if(mpi0.MPI_VALUE[i]!=mpi1.MPI_VALUE[i]){
					return mpi0.MPI_VALUE[i]<mpi1.MPI_VALUE[i];
				}
			}
		}
		return sz(mpi0.MPI_VALUE)<sz(mpi1.MPI_VALUE);
	}

	static bool mpi_abs_sl(const MPI &mpi0,const MPI &mpi1){
		if(sz(mpi0.MPI_VALUE)==sz(mpi1.MPI_VALUE)){
			for(li i=sz(mpi0.MPI_VALUE)-1;0<=i;i--){
				if(mpi0.MPI_VALUE[i]!=mpi1.MPI_VALUE[i]){
					return mpi0.MPI_VALUE[i]>mpi1.MPI_VALUE[i];
				}
			}
		}
		return sz(mpi0.MPI_VALUE)>sz(mpi1.MPI_VALUE);
	}

	static bool mpi_abs_eq(const MPI &mpi0,const MPI &mpi1){
		if(sz(mpi0.MPI_VALUE)!=sz(mpi1.MPI_VALUE)) return false;
		rep(i,sz(mpi0.MPI_VALUE)){
			if(mpi0.MPI_VALUE[i]!=mpi1.MPI_VALUE[i]) return false;
		}
		return true;
	}

private:

	static void mpi_reform_vec(vector<li> &mpi_vec){
		if(sz(mpi_vec)==0) mpi_vec.pb(0);
		while(1<sz(mpi_vec) && mpi_vec.back()==0) mpi_vec.pop_back();
	}

	static void mpi_add_mul_reform_vec(vector<li> &mpi_vec){
		li carry=0;
		rep(i,sz(mpi_vec)){
			mpi_vec[i]+=carry;
			carry=mpi_vec[i]/MPI_MAX;
			mpi_vec[i]%=MPI_MAX;
		}
		mpi_vec.pb(carry);
		mpi_reform_vec(mpi_vec);
	}

	static void mpi_reform(MPI &mpi_var){
		mpi_reform_vec(mpi_var.MPI_VALUE);
		if(sz(mpi_var.MPI_VALUE)==1 && mpi_var.MPI_VALUE[0]==0) mpi_var.MPI_SIGN=false;
	}

	static void mpi_add_mul_reform(MPI &mpi_var){
		mpi_add_mul_reform_vec(mpi_var.MPI_VALUE);
		if(sz(mpi_var.MPI_VALUE)==1 && mpi_var.MPI_VALUE[0]==0) mpi_var.MPI_SIGN=false;
	}
};

class IRN{
public:
	MPI IRN_DEN;
	MPI IRN_NUM;
	bool IRN_SIGN;

	IRN(){
		IRN_DEN=0;
		IRN_NUM=1;
		IRN_SIGN=false;
	}
	IRN(string irn_str0,string irn_str1){
		IRN_DEN=irn_str0;
		IRN_NUM=irn_str1;
		IRN_SIGN=false;
		if(IRN_DEN<0) IRN_SIGN=!IRN_SIGN;
		if(IRN_NUM<0) IRN_SIGN=!IRN_SIGN;
		IRN_DEN.MPI_SIGN=false;
		IRN_NUM.MPI_SIGN=false;
		irn_reduct(*this);
	}
	IRN(li irn_li0,li irn_li1){
		IRN_DEN=irn_li0;
		IRN_NUM=irn_li1;
		IRN_SIGN=false;
		if(IRN_DEN<0) IRN_SIGN=!IRN_SIGN;
		if(IRN_NUM<0) IRN_SIGN=!IRN_SIGN;
		IRN_DEN.MPI_SIGN=false;
		IRN_NUM.MPI_SIGN=false;
		irn_reduct(*this);
	}
	IRN(li irn_li){
		IRN_DEN=irn_li;
		IRN_NUM=1;
		IRN_SIGN=false;
	}
	IRN(string irn_str){
		IRN_DEN=irn_str;
		IRN_NUM=1;
		IRN_SIGN=false;
	}

	string to_string() const{
		if(IRN_SIGN && IRN_DEN!=0) return "-"+IRN_DEN.to_string()+"/"+IRN_NUM.to_string();
		return IRN_DEN.to_string()+"/"+IRN_NUM.to_string();
	}

	static MPI irn_mpi_gcd(MPI mpi0,MPI mpi1){
		if(mpi1==0) return 0;
		if(mpi0%mpi1==0) return mpi1;
		return irn_mpi_gcd(mpi1,mpi0%mpi1);
	}

	void irn_reduct(IRN &irn_var)const{
		if(irn_var.IRN_DEN==0){ irn_var.IRN_NUM=1; irn_var.IRN_SIGN=false; return ; }
		if(irn_var.IRN_DEN.MPI_SIGN) irn_var.IRN_SIGN=!irn_var.IRN_SIGN;
		if(irn_var.IRN_NUM.MPI_SIGN) irn_var.IRN_SIGN=!irn_var.IRN_SIGN;
		irn_var.IRN_DEN.MPI_SIGN=false;
		irn_var.IRN_NUM.MPI_SIGN=false;
		MPI irn_t=irn_mpi_gcd(irn_var.IRN_NUM,irn_var.IRN_DEN);
		irn_var.IRN_NUM/=irn_t;
		irn_var.IRN_DEN/=irn_t;
	}

	IRN irn_mul(const IRN &irn0,const IRN &irn1)const{
		IRN irn_res(1,1);
		MPI irn_t=irn_mpi_gcd(irn0.IRN_DEN,irn1.IRN_NUM);
		irn_res.IRN_DEN=irn0.IRN_DEN/irn_t;
		irn_res.IRN_NUM=irn1.IRN_NUM/irn_t;
		irn_t=irn_mpi_gcd(irn0.IRN_NUM,irn1.IRN_DEN);
		irn_res.IRN_DEN*=irn1.IRN_DEN/irn_t;
		irn_res.IRN_NUM*=irn0.IRN_NUM/irn_t;
		if(irn1.IRN_SIGN) irn_res.IRN_SIGN=!irn_res.IRN_SIGN;
		if(irn0.IRN_SIGN) irn_res.IRN_SIGN=!irn_res.IRN_SIGN;
		if(irn_res.IRN_DEN==0){ irn_res.IRN_NUM=1; irn_res.IRN_SIGN=false; }
		return irn_res;
	}

	IRN irn_div(const IRN &irn0,const IRN &irn1)const{
		IRN irn_res(1,1);
		MPI irn_t=irn_mpi_gcd(irn0.IRN_DEN,irn1.IRN_DEN);
		irn_res.IRN_DEN=irn0.IRN_DEN/irn_t;
		irn_res.IRN_NUM=irn1.IRN_DEN/irn_t;
		irn_t=irn_mpi_gcd(irn0.IRN_NUM,irn1.IRN_NUM);
		irn_res.IRN_DEN*=irn1.IRN_NUM/irn_t;
		irn_res.IRN_NUM*=irn0.IRN_NUM/irn_t;
		if(irn1.IRN_SIGN) irn_res.IRN_SIGN=!irn_res.IRN_SIGN;
		if(irn0.IRN_SIGN) irn_res.IRN_SIGN=!irn_res.IRN_SIGN;
		if(irn_res.IRN_DEN==0){ irn_res.IRN_NUM=1; irn_res.IRN_SIGN=false; }
		return irn_res;
	}

	IRN irn_abs_add(const IRN &irn0,const IRN &irn1)const{
		IRN irn_res(0);
		if(irn0.IRN_NUM==irn1.IRN_NUM){
			irn_res.IRN_DEN=irn0.IRN_DEN+irn1.IRN_DEN;
			irn_res.IRN_NUM=irn0.IRN_NUM;
			irn_reduct(irn_res);
			return irn_res;
		}
		irn_res.IRN_NUM=irn0.IRN_NUM*irn1.IRN_NUM;
		irn_res.IRN_DEN=irn0.IRN_DEN*irn1.IRN_NUM;
		irn_res.IRN_DEN+=irn1.IRN_DEN*irn0.IRN_NUM;
		irn_reduct(irn_res);
		return irn_res;
	}

	IRN irn_abs_sub(const IRN &irn0,const IRN &irn1)const{
		IRN irn_res(0);
		if(irn0.IRN_NUM==irn1.IRN_NUM){
			irn_res.IRN_DEN=irn0.IRN_DEN-irn1.IRN_DEN;
			irn_res.IRN_NUM=irn0.IRN_NUM;
			irn_reduct(irn_res);
			return irn_res;
		}
		irn_res.IRN_NUM=irn0.IRN_NUM*irn1.IRN_NUM;
		irn_res.IRN_DEN=irn0.IRN_DEN*irn1.IRN_NUM;
		irn_res.IRN_DEN-=irn1.IRN_DEN*irn0.IRN_NUM;
		irn_reduct(irn_res);
		return irn_res;
	}

	IRN irn_add(const IRN &irn0,const IRN &irn1)const{
		if( irn0.IRN_SIGN&& irn1.IRN_SIGN){
			IRN irn_res=irn_abs_add(irn0,irn1);
			irn_res.IRN_SIGN=!irn_res.IRN_SIGN;
			return irn_res;
		}
		if(!irn0.IRN_SIGN&&!irn1.IRN_SIGN) return irn_abs_add(irn0,irn1);
		IRN irn_res;
		if(!irn0.IRN_SIGN&& irn1.IRN_SIGN) irn_res=irn_abs_sub(irn0,irn1);
		if( irn0.IRN_SIGN&&!irn1.IRN_SIGN) irn_res=irn_abs_sub(irn1,irn0);
		if(irn_res.IRN_DEN.MPI_SIGN){
			irn_res.IRN_DEN.MPI_SIGN=false;
			irn_res.IRN_SIGN=true;
		}
		return irn_res;
	}

	IRN irn_sub(const IRN &irn0,const IRN &irn1)const{
		if(!irn0.IRN_SIGN&& irn1.IRN_SIGN) return irn_abs_add(irn0,irn1);
		if( irn0.IRN_SIGN&&!irn1.IRN_SIGN){
			IRN irn_res=irn_abs_add(irn0,irn1);
			irn_res.IRN_SIGN=!irn_res.IRN_SIGN;
			return irn_res;
		}
		IRN irn_res;
		if( irn0.IRN_SIGN&& irn1.IRN_SIGN){
			irn_res=irn_abs_sub(irn0,irn1);
			irn_res.IRN_SIGN=!irn_res.IRN_SIGN;
		}
		if(!irn0.IRN_SIGN&&!irn1.IRN_SIGN){
			irn_res=irn_abs_sub(irn0,irn1);
		}
		if(irn_res.IRN_DEN.MPI_SIGN){
			irn_res.IRN_DEN.MPI_SIGN=false;
			irn_res.IRN_SIGN=true;
		}
		return irn_res;
	}

	bool operator<(const IRN &irn_var)const{
		if(this->IRN_DEN==0 && irn_var.IRN_DEN==0) return false;
		bool b0=this->IRN_SIGN,b1=irn_var.IRN_SIGN;
		if( b0&&!b1) return true;
		if(!b1&& b0) return false;
		MPI left=this->IRN_DEN*irn_var.IRN_NUM;
		MPI right=irn_var.IRN_DEN*this->IRN_NUM;
		if(!b0&&!b1) return left<right;
		return right<left;
	}

	bool operator>(const IRN &irn_var)const{
		if(this->IRN_DEN==0 && irn_var.IRN_DEN==0) return false;
		bool b0=this->IRN_SIGN,b1=irn_var.IRN_SIGN;
		if( b0&&!b1) return false;
		if(!b0&& b1) return true;
		MPI left=this->IRN_DEN*irn_var.IRN_NUM;
		MPI right=irn_var.IRN_DEN*this->IRN_NUM;
		if(!b0&&!b1) return left>right;
		return right<left;
	}

	bool operator==(const IRN &irn_var)const{
		if(this->IRN_DEN==0 && irn_var.IRN_DEN==0) return true;
		if(this->IRN_SIGN && !irn_var.IRN_SIGN) return false;
		if(!this->IRN_SIGN&&  irn_var.IRN_SIGN) return false;
		return this->IRN_DEN==irn_var.IRN_DEN && this->IRN_NUM==irn_var.IRN_NUM;
	}

	IRN operator+(const IRN &irn_var)const{ return irn_add(*this,irn_var); }
	IRN operator-(const IRN &irn_var)const{ return irn_sub(*this,irn_var); }
	IRN operator/(const IRN &irn_var)const{ return irn_div(*this,irn_var); }
	IRN operator*(const IRN &irn_var)const{ return irn_mul(*this,irn_var); }
	void operator+=(const IRN &irn_var){ *this=*this+irn_var; }
	void operator-=(const IRN &irn_var){ *this=*this-irn_var; }
	void operator*=(const IRN &irn_var){ *this=*this*irn_var; }
	void operator/=(const IRN &irn_var){ *this=*this/irn_var; }
	IRN operator<=(const IRN &irn_var)const{ return !(irn_var<*this); }
	IRN operator>=(const IRN &irn_var)const{ return !(*this<irn_var); }
	IRN operator!=(const IRN &irn_var)const{ return !(*this==irn_var); }

	friend std::ostream& operator<<(std::ostream& os,const IRN &irn_var){
		os<<irn_var.to_string();
		return os;
	}
private:
};

////////////////////////////////////////////////////////
//////      "multiple precision integer"        ////////
//////           "irrational class"             ////////
//////      My main answer may be below.        ////////
////////////////////////////////////////////////////////

IRN BASE=IRN(1,1),LEFT=IRN(0,1),RIGHT=IRN(1,1),INIT(0,1);
set<li> used;
li n,cnt;

void recur(li num){
	if(num==0 || used.find(num)!=used.end()) return;
	used.insert(num);
	for(cnt=0;num<n;num*=2) cnt++;
	LEFT+=BASE*cnt;
	BASE*=IRN(num-n,num);
	recur(num-n);
}

int main(){
	cin>>n;
	for(;n%2==0;n/=2) INIT+=IRN(1,1);
	recur(1);
	cout<<LEFT/(RIGHT-BASE)+INIT<<endl;
}


/**
    create by Egor Plisko
    Андрей Александрович, поставьте 10
**/
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pi pair < ll , ll >;
#define prev _prev
#define stack _stack

ll scal(pi a, pi b)
{
    return (ll)a.first * (ll)a.second + (ll)b.first * (ll)b.second;
}

ll mul(pi a, pi b)
{
    return (ll)a.first * (ll)b.second - (ll)a.second * (ll)b.first;
}

int half(pi a)
{
    if (a.second > 0 || (a.second == 0 && a.first >= 0))
        return 0;
    return 1;
}

int half(pi a, pi b)
{
    ll pr = mul(a, b);
    if (pr != 0)
        return (pr <= 0);
    return (scal(a, b) < 0);
}

const int M = 210;
const int MOD = 998244353;

int n, x[M], y[M], dp[M], val[M][M], ml[M], ei[M][M], first[M][M], last[M][M], sum[2 * M], ok[M][M];
vector<int> v[M];
vector<int> way[M][M];

pi vect(int i, int j)
{
    return make_pair(x[j] - x[i], y[j] - y[i]);
}

pi vect(pi t)
{
    return make_pair(x[t.second] - x[t.first], y[t.second] - y[t.first]);
}

void dfs_help(int p, int pr)
{
    int id = -1;
    for (int i = 0; i < (int)v[p].size(); i++)
    {
        if (v[p][i] == pr)
            id = i;
        else
            dfs_help(v[p][i], p);
    }
    if (id != -1)
    {
        swap(v[p][id], v[p].back());
        v[p].pop_back();
    }
}

vector<int> stack;

void dfs_way(int p, int pr, int st)
{
    stack.push_back(p);
    if (p != st && (int)stack.size() >= 3)
    {
        bool ch = true;
        for (int i : stack)
            if (mul(vect(st, p), vect(st, i)) < 0)
            {
                ch = false;
                break;
            }
        if (ch)
            way[st][p] = stack;
    }
    for (int i : v[p])
        if (i != pr)
            dfs_way(i, p, st);
    stack.pop_back();
}

bool cmp(pi a, pi b){
    pi va = vect(a);
    pi vb = vect(b);
    int ha = half(va);
    int hb = half(vb);
    if (ha != hb)
        return ha < hb;
    ll pr = mul(va, vb);
    if (pr != 0)
        return (pr > 0);
    return a < b;
}

bool good(pi a, pi b, pi c){
    int hb = half(a, b);
    int hc = half(a, c);
    if (hb != hc)
        return hb < hc;
    return mul(b, c) > 0;
}

vector<int> g[M];

vector<int> dfs(int p){
    ml[p] = 1;
    vector<int> now = {p};
    for (int i : v[p])
    {
        vector<int> to = dfs(i);
        for (int x : to)
            now.push_back(x);
        ml[p] = (ll)ml[p] * dp[i] % MOD;
    }
    dp[p] = ml[p];
    for (int i : v[p])
    {
        int cur = ml[i];
        for (int j : v[p])
            if (j != i)
                cur = (ll)cur * dp[j] % MOD;
        dp[p] += cur;
        if (dp[p] >= MOD)
            dp[p] -= MOD;
    }
    for (int i : now)
        g[i].clear();
    int k = 0;
    for (int i : now)
        for (int j : v[i])
        {
            g[i].push_back(j);
            g[j].push_back(i);
            ei[i][j] = k++;
            ei[j][i] = k++;
        }
    for (int i : now)
        for (int j : now)
            ok[i][j] = 0;
    vector<pi> al;
    for (int i : now)
        for (int j : now)
            if (!way[i][j].empty() && mul(vect(i, j), vect(i, p)) >= 0)
            {
                al.push_back(make_pair(i, j));
                first[i][j] = ei[way[i][j][0]][way[i][j][1]];
                last[i][j] = ei[way[i][j][(int)way[i][j].size() - 1]][way[i][j][(int)way[i][j].size() - 2]];
                if (val[i][j] != -1)
                    continue;
                ok[i][j] = 1;
                val[i][j] = 1;
                for (int x = 0; x < (int)way[i][j].size(); x++)
                {
                    int v_cur = way[i][j][x];
                    pi lb, rb;
                    if (x == 0)
                    {
                        lb = vect(v_cur, way[i][j][x + 1]);
                        lb.first = -lb.first, lb.second = -lb.second;
                    }
                    else
                        lb = vect(v_cur, way[i][j][x - 1]);
                    if (x + 1 == (int)way[i][j].size())
                    {
                        rb = vect(v_cur, way[i][j][x - 1]);
                        rb.first = -rb.first, rb.second = -rb.second;
                    }
                    else
                        rb = vect(v_cur, way[i][j][x + 1]);
                    for (int to : v[v_cur])
                        if (good(lb, vect(v_cur, to), rb))
                        {
                            if (x != 0 && to == way[i][j][x - 1])
                                continue;
                            if (x + 1 < (int)way[i][j].size() && to == way[i][j][x + 1])
                                continue;
                            val[i][j] = (ll)val[i][j] * dp[to] % MOD;
                        }
                }
            }
    sort(al.begin(), al.end(), cmp);
    for (int v_st : now)
        for (int ig : g[v_st])
        {
            if (half(vect(v_st, ig)))
                continue;
            for (int ban = -1; ban <= 1; ban += 2)
            {
                for (int i = 0; i < k; i++)
                    sum[i] = 0;
                sum[ei[v_st][ig]] = 1;
                for (pi t : al)
                {
                    if (ban == -1 && ok[t.first][t.second])
                        continue;
                    int S = first[t.first][t.second];
                    int F = last[t.first][t.second];
                    sum[F] += (ll)sum[S] * val[t.first][t.second] % MOD;
                    if (sum[F] >= MOD)
                        sum[F] -= MOD;
                }
                sum[ei[v_st][ig]]--;
                if (sum[ei[v_st][ig]] < 0)
                    sum[ei[v_st][ig]] += MOD;
                dp[p] += ban * sum[ei[v_st][ig]];
                if (dp[p] >= MOD)
                    dp[p] -= MOD;
                if (dp[p] < 0)
                    dp[p] += MOD;
            }
        }
    return now;
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> x[i] >> y[i];
    for (int i = 0; i < n - 1; i++)
    {
        int s, f;
        cin >> s >> f;
        s--, f--;
        v[s].push_back(f);
        v[f].push_back(s);
    }
    for (int i = 0; i < n; i++)
        dfs_way(i, -1, i);
    dfs_help(0, -1);
    memset(val, -1, sizeof(val));
    dfs(0);
    cout << dp[0] << "\n";
    return 0;
}


#include<bits/stdc++.h>
#define int long long
#define left greetings_traveller
#define right ya_snova_jivu
using namespace std;

const int N = 1e5 + 5, inf = 3e15;

int n, a, b, g[N], k[N], dp[N];

map < int, int > left, right;

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin >> n >> a >> b;
    for(int i = 1; i < n; i++){
        cin >> g[i];
    }
    for(int i = 1; i <= n; i++){
        cin >> k[i];
        dp[i] = inf;
    }
    dp[a] = 0;
    int l = a, r = a, tl = a, tr = a;
    left[k[a]] = right[k[a]] = a;
    while(dp[b] == inf){
        bool p = false;
        if(r < n){
            int need = g[r];
            if(right[need]){
                dp[r + 1] = dp[r] + 1;
            }
            else if(left[need]){
                if(left[need] < tl){
                    dp[r + 1] = dp[left[need]] + abs(r + 1 - left[need]);
                    tl = left[need];
                }
                else{
                    dp[r + 1] = dp[r] + 1;
                }
            }
            if(dp[r + 1] != inf){
                r++;
                p = true;
                if(!right[k[r]]){
                    right[k[r]] = r;
                }
            }
        }
        if(l > 1){
            int need = g[l - 1];
            if(left[need]){
                dp[l - 1] = dp[l] + 1;
            }
            else if(right[need]){
                if(right[need] > tr){
                    dp[l - 1] = dp[right[need]] + abs(l - 1 - right[need]);
                    tr = right[need];
                }
                else{
                    dp[l - 1] = dp[l] + 1;
                }
            }
            if(dp[l - 1] != inf){
                l--;
                p = true;
                if(!left[k[l]]){
                    left[k[l]] = l;
                }
            }
        }
        if(!p){
            return cout << "-1", 0;
        }
    }
    cout << dp[b];
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;

#define pb push_back
#define mp make_pair
#define X first
#define Y second

int n, x[23];
vector<int> y;
map<int, int> z;
vector<pair<int, int>> f;

void dfs(int k, int a, int b)
{
	if (k == 1)
	{
		for (int i = 1; i <= y[0]; ++i) f.pb(mp(a, b));
		return;
	}
	int c = 6 - a - b;
	dfs(k - 1, a, c);
	for (int i = 1; i <= y[k-1]; ++i) f.pb(mp(a, b));
	dfs(k - 1, c, b);
}

int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) scanf("%d", &x[i]);
	for (int i = n; i > 1; --i) ++z[x[i]];
	for (auto i : z) y.pb(i.Y);
	dfs(y.size(), 1, 2);
	f.pb(mp(1, 3));
	dfs(y.size(), 2, 3);
	printf("%d\n", f.size());
	for (auto i : f) printf("%d %d\n", i.X, i.Y);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int K = 5000 + 1;

map<int, map<int, int> > fac;
vector<int> sum;
map<int, int> v;
int n;

void build() {
  bitset<K> isp;
  isp.set();
  for(int i = 2 ; i * i < K ; ++i) if(isp[i]) {
    for(int j = i * i ; j < K ; j += i) isp[j] = 0;
  }
  vector<int> p;
  for(int i = 2 ; i < K ; ++i) if(isp[i]) p.push_back(i);
  map<int, int> m;
  sum.resize(K);
  int cnt = 0;
  for(int i = 2 ; i < K ; ++i) {
    int x = i, j = 0;
    while(x > 1) {
      if(isp[x]) {
        m[x]++;
        cnt++;
        break;
      }
      int cc = 0;
      while(x % p[j] == 0) cc++, x /= p[j];
      if(cc) m[p[j]] += cc, cnt += cc;
      j++;
    }
    fac[i] = m;
    sum[i] = cnt;
  }
}
void init() {
  cin >> n;
  for(int i = 0 ; i < n ; ++i) {
    int a; cin >> a;
    if(a != 1) v[a]++;
  }
}
void solve() {
  int ans = 0;
  for(auto [i, j] : v) {
    ans += sum[i] * j;
  }
  while(1) {
    map<int, int> tmp;
    for(auto [i, j] : v) {
      tmp[fac[i].rbegin()->first] += j;
    }
    int mx = 0, val = 0;
    for(auto [i, j] : tmp) if(j > val) mx = i, val = j;
    if(val < n - val) break;
    ans += n - val - val;
    vector<int> tt;
    for(auto [i, j] : v) {
      if(fac[i].rbegin()->first == mx) {
        fac[i].rbegin()->second--;
        if(fac[i].rbegin()->second == 0) {
          fac[i].erase(fac[i].rbegin()->first);
          if(fac[i].empty()) tt.push_back(i);
        }
      }
      else tt.push_back(i);
    }
    for(auto t : tt) v.erase(t);
  }
  cout << ans << '\n';
}

int main() {
  build();
  init();
  solve();
}


#include<set>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 200005, M = 2000005;
int n, m;
long long p[N], v[N], anss[M];

int minTurn() {
	for (int i = 0; i < n; ++i) {
		v[i] = p[i];
	}
	int ret = 0;
	long long maxm = m;
	while (true) {
		for (int i = n - 1; i >= 0; --i) {
			long long now = min(maxm, v[i]);
			if (now == 0) {
				return ret;
			} else {
				maxm = now - 1;
				v[i] -= now;
			}
		}
		++ret;
	}
}

int maxTurn() {
	for (int i = 0; i < n; ++i) {
		v[i] = p[i];
	}
	int ret = 0;
	long long minm = 1;
	while (true) {
		for (int i = 0; i < n; ++i) {
			if (minm > m) {
				return ret;
			}
			if (v[i] < minm) {
				return ret;
			} else {
				v[i] -= minm++;
			}
		}
		++ret;
	}
}

long long mins[N];

long long solve(int t) {
	if (anss[t] != -1) {
		return anss[t];
	}
	long long last = 0;
	for (int i = 0; i < n; ++i) {
		v[i] = p[i];
	}
	long long ret = 0;
	for (int i = 0; i < t; ++i) {
		for (int j = 0; j < n; ++j) {
			v[j] -= ++last;
			ret += last;
		}
	}
	int delta = m - last;
	for (int i = t - 1; i >= 0 && delta; --i) {
		for (int j = n - 1; j >= 0 && delta; --j) {
			delta = v[j] > delta ? delta : v[j];
			v[j] -= delta;
			ret += delta;
		}
	}
	return anss[t] = ret;
}

int main() {
	ios::sync_with_stdio(false);
	cin >> n >> m;
	for (int i = 0; i < n; ++i) {
		cin >> p[i];
	}
	int l = minTurn(), r = maxTurn();
	for (int i = l; i <= r; ++i) {
		anss[i] = -1;
	}
	long long ans = max(solve(l), solve(r));
	int mid1, mid2;
	for (int i = 0; i < 100; ++i) {
		mid1 = (l + l + r) / 3;
		mid2 = (l + r + r) / 2;
		ans = max(ans, solve(mid1));
		ans = max(ans, solve(mid2));
		if (solve(mid1) > solve(mid2)) {
			r = mid2;
		} else {
			l = mid1;
		}
	}
	cout << ans << endl;
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <maㅁp>
#include <queue>
#include <stack>
#include <deque>
#include <stdlib.h>
using namespace std;
typedef long long int lld;
typedef long double ld;
pair<lld,lld> arr[7777],ans;
vector<int> v[66];
int main(void){
	int n;
	scanf("%d",&n);
	for(int e=0;e<n;e++){
		scanf("%lld",&arr[e].first);
		lld tmp = arr[e].first,val = 0;
		while(tmp!=0){
			if(tmp%2) v[val].push_back(e);
			tmp/=2;
		}
	}
	for(int e=0;e<n;e++){
		scanf("%lld",&arr[e].second);
		ans += arr[e].second;
	}
	for(int e=0;e<66;e++){
		if(v[e].size()==1){
			int now = v[e][0];
			ans -= arr[now].second;
		}
	}
	printf("%lld",ans);
	return 0;
}


#ifndef LOCAL
#pragma GCC optimize("O3")
#endif
#include "bits/stdc++.h"
using namespace std;
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
//~ eni(!=) cerr << boolalpha << i; ris; }
eni(!=) cerr << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

typedef long long ll;

const int AND = 0, OR = 1, NAND = 2, NOR = 3;
const int nax = 1005;

struct S {
	int type;
	S zmien() {
		S he;
		he.type = type ^ 1;
		return he;
	}
	void read() {
		static char sl[10];
		scanf("%s", sl);
		string s = string(sl);
		if(s == "and") type = AND;
		else if(s == "or") type = OR;
		else if(s == "nand") type = NAND;
		else if(s == "nor") type = NOR;
		else {
			cout << "unknown type: " << s << endl;
			assert(false);
		}
	}
	bool operator () (bool a, bool b) {
		if(type == AND) return a & b;
		if(type == OR) return a | b;
		if(type == NAND) return !(a & b);
		if(type == NOR) return !(a | b);
		assert(false);
	}
};

void read(pair<S, pair<int,int>> & p) {
	p.first.read();
	static char sl[105];
	scanf("%s", sl);
	int n = strlen(sl);
	vector<int> w;
	for(int i = 0; i < n; ++i)
		if(sl[i] == 'x')
			w.push_back(i);
	assert((int) w.size() == 2);
	p.second = {w[0], w[1]};
}

vector<int> w[nax];

int main() {
	int n, m, k;
	scanf("%d%d%d", &n, &m, &k);
	vector<pair<S, pair<int,int>>> one(m), two(k);
	for(int i = 0; i < m; ++i)
		read(one[i]);
	for(int i = 0; i < k; ++i)
		read(two[i]);

	const int M = 10 * 1000;
	vector<pair<vector<bool>, vector<bool>>> pre(M);
	for(auto & p : pre) {
		vector<bool> a(n), b(m), c(k), d(k);
		for(int i = 0; i < n; ++i) a[i] = rand() % 2;
		for(int i = 0; i < m; ++i) b[i] = one[i].first(a[one[i].second.first], a[one[i].second.second]);
		for(int i = 0; i < k; ++i) c[i] = two[i].first(b[two[i].second.first], b[two[i].second.second]);
		for(int i = 0; i < k; ++i) d[i] = two[i].first.zmien()(b[two[i].second.first], b[two[i].second.second]);
		p = {c, d};
	}
	vector<bool> maybe(k, true);
	for(auto & p : pre) {
		auto & c = p.first;
		auto & d = p.second;
		debug() << imie(c);
		for(int i = 0; i < k; ++i) if(c[i] & d[i]) maybe[i] = false;
		bool any = false;
		for(int i = 0; i < k; ++i) if(maybe[i]) if(c[i] | d[i]) any = true;
		if(!any) {
			puts("-1");
			return 0;
		}
	}

	vector<vector<bool>> e(k, vector<bool>(k));

	for(auto & p : pre) {
		auto & c = p.first;
		auto & d = p.second;
		debug() << imie(c);
		debug() << imie(d);
		debug();
		for(int i = 0; i < k; ++i) if(maybe[i])
			for(int j = i + 1; j < k; ++j) if(maybe[j])
				if((c[i] & d[j]) | (c[j] & d[i])) e[i][j] = e[j][i] = true;
	}

	for(int i = 0; i < k; ++i)
		for(int j = i + 1; j < k; ++j) if(e[i][j]) {
			w[i].push_back(j);
			w[j].push_back(i);
			//~ printf("%d %d\n", i, j);
		}

	int answer = 0;
	for(int i = 0; i < k; ++i) if(!maybe[i]) ++answer;
	vector<bool> vis(k);
	vector<pair<vector<int>, vector<int>>> they;
	vector<bool> taken(k);
	for(int i = 0; i < k; ++i) if(maybe[i] && !vis[i]) {
		vector<int> A, B;
		vector<int> kol{i};
		vector<int> dist(k);
		vis[i] = true;
		for(int j = 0; j < (int) kol.size(); ++j) {
			int a = kol[j];
			if(dist[a] % 2) A.push_back(a);
			else B.push_back(a);
			for(int b : w[a]) if(!vis[b]) {
				vis[b] = true;
				dist[b] = dist[a] + 1;
				kol.push_back(b);
			}
		}
		if(A.size() < B.size()) swap(A, B);
		// bierzemy pierwsza
		they.push_back({A, B});
		for(int x : A) taken[x] = true;

		//~ printf("%d %d\n", A, B);
		answer += (int) B.size();
	}
	bool yeah = true;
	for(auto & p : pre) {
		auto & c = p.first;
		auto & d = p.second;
		bool any = false;
		for(int i = 0; i < k; ++i) if(taken[i]) if(c[i] | d[i]) any = true;
		if(!any) {
			yeah = false;
			break;
		}
	}

	if(!yeah) for(pair<vector<int>, vector<int>> p : they) {
		int by = 1000000;
		auto memo = taken;
		for(int x : p.first) {
			assert(taken[x]);
			taken[x] = false;
		}
		for(int x : p.second) {
			assert(!taken[x]);
			taken[x] = true;
		}

		bool tu = true;
		for(auto & p : pre) {
			auto & c = p.first;
			auto & d = p.second;
			bool any = false;
			for(int i = 0; i < k; ++i) if(taken[i]) if(c[i] | d[i]) any = true;
			if(!any) {
				tu = false;
				break;
			}
		}
		if(tu) by = min(by, (int) abs(p.first.size() - p.second.size()));

		taken = memo;
		answer += by;
	}

	printf("%d\n", answer);
	return 0;

	//~ int answer = -1;
	for(int mask = 0; mask < (1 << k); ++mask) {
		bool ok = true;
		for(int i = 0; i < k; ++i) if(mask & (1 << i)) if(!maybe[i]) ok = false;
		if(!ok) continue;
		for(int rep = 0; rep < 200; ++rep) {
			vector<bool> a(n), b(m), c(k), d(k);
			for(int i = 0; i < n; ++i) a[i] = rand() % 2;
			for(int i = 0; i < m; ++i) b[i] = one[i].first(a[one[i].second.first], a[one[i].second.second]);
			for(int i = 0; i < k; ++i) c[i] = two[i].first(b[two[i].second.first], b[two[i].second.second]);
			for(int i = 0; i < k; ++i) d[i] = two[i].first.zmien()(b[two[i].second.first], b[two[i].second.second]);
			//~ debug() << imie(c);
			//~ debug() << imie(d);
			//~ debug();
			bool raz = false, dwa = false;
			for(int i = 0; i < k; ++i) if(mask & (1 << i)) {
				if(c[i]) raz = true;
				if(d[i]) dwa = true;
			}
			if(raz && dwa) ok = false;
			if(!raz && !dwa) ok = false;
			if(!ok) break;
			//~ for(int i = 0; i < k; ++i)
				//~ if(c[i] && d[i])
					//~ maybe[i] = false;
		}
		if(ok) answer = max(answer, __builtin_popcount(mask));
		//~ debug() << imie(maybe);
	}
	assert(answer != -1);

	//~ if(answer == -1) printf("%d\n", answer);
	//~ else printf("%d\n", k - answer);

	printf("%d\n", k - answer);
}


#include <bits/stdc++.h>
#define div suka
#define ll long long
using namespace std;
const int mod = 1000000007;
int Sum(int x, int y){
	if (x+y<0) return x+y+mod;
	if (x+y>=mod) return x+y-mod;
	return x+y;
}
int mult(int x, int y){
	return ((ll) x * (ll) y) % (ll) mod;
}
const int K = 100007;
vector<int> div[K];
int pw(int x, int y){
	if (y == 0) return 1;
	if (y==1) return x%mod;
	if (y % 2 == 0){
		int R = pw(x, y/2);
		return mult(R, R);
	}
	return mult(x, pw(x, y-1));
}
int arr[1000];
int get(int n, int l, int r){
	int res=0;
	for (int i=l; i <= r; i++){
		if (__gcd(i, n) == 1) res++;
	}
	return res;
}
signed main() {
	#ifdef LOCAL
		freopen("H_input.txt", "r", stdin);
		//freopen("C_output.txt", "w", stdout);
	#endif
    ios_base::sync_with_stdio(0); cin.tie(0);
   	int n, k;
   	cin >> n >> k;
   	for (int i=2; i < K; i++){
   		if (div[i].size() >= 1) continue;
   		for (int j=i; j < K; j += i) div[j].push_back(i);
   	}
   	int ans=0;
   	for (int g=1; g < n; g++){
   		int len = (n+g-1)/g;
   		for (int sum=2; sum <= 2*(len-1); sum++){
   			int L, R;
   			if (sum <= len) L = 1;
   			else L = sum-len+1;
   			if (sum >= len) R = len-1;
   			else R = sum-1;
   			int var = get(sum, L, R);
   			int count1 = g - (n%g), g1 = len-1;
   			int count2 = (n%g), g2 = len;
   			if (n%g == 0) swap(count1, count2);
   			int kf = 1;
   			int cmp1, cmp2;
   			if (sum <= g1+1) cmp1=1;
   			else cmp1 = sum-g1;
   			if (sum <= g2+1) cmp2=1;
   			else cmp2 = sum-g2;
   			kf = mult(kf, pw(pw(k, cmp1), count1));
   			kf = mult(kf, pw(pw(k, cmp2), count2));
   			//cout << g << " " << sum << " " << kf << " " << var << endl;
   			ans = Sum(ans, mult(kf, var));
   		}
   	}
   	int R = pw(k, mod-2);
   	ans = mult(ans, pw(R, n));
   	cout << ans;
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
using ll = long long;
const int MOD = 998244353;

class SegTree {
	private:
		struct El {
			int p[2][2]; // Probability that leftmost is L/R and rightmost is L/R
			El() {
				p[0][0] = 0;
				p[0][1] = 0;
				p[1][0] = 0;
				p[1][1] = 0;
			}
			static El id() {
				El res;
				res.p[0][0] = 1;
				res.p[1][1] = 1;
				return res;
			}
		};
		static El combine(const El& le, const El& ri) {
			El res;
			for (int a = 0; a < 2; ++a) {
				for (int b = 0; b < 2; ++b) {
					for (int i = 0; i < 2; ++i) {
						res.p[a][b] = (res.p[a][b] + (ll)le.p[a][i] * ri.p[i][b]) % MOD;
					}
				}
			}
			return res;
		}
		void update(int i) {
			for (i >>= 1; i > 0; i >>= 1) seg[i] = combine(seg[2*i], seg[2*i+1]);
		}

		vector<El> seg;
		int h = 1;
	public:
		SegTree(int n) {
			while(h < n) h *= 2;
			seg.resize(2*h, El::id());
		}

		int prob(int i, int a, int b) {
			i += h;
			El backup = seg[i];
			for (int x = 0; x < 2; ++x) {
				for (int y = 0; y < 2; ++y) {
					if (x != a || y != b) seg[i].p[x][y] = 0;
				}
			}
			update(i);

			ll res = (seg[1].p[0][0] + seg[1].p[0][1]) % MOD;

			seg[i] = backup;
			update(i);
			return res;
		}
		void setv(int i, int a, int b, int c, int d) {
			i += h;
			seg[i].p[0][0] = a;
			seg[i].p[0][1] = b;
			seg[i].p[1][0] = c;
			seg[i].p[1][1] = d;
			update(i);
		}
		void zero(int i, int a, int b) {
			i += h;
			seg[i].p[a][b] = 0;
			update(i);
		}
};

ll modPow(ll a, ll b) {
	if (b & 1) return a * modPow(a, b-1) % MOD;
	if (b > 0) return modPow(a*a % MOD, b / 2);
	return 1;
}

struct Atom {
	int xi, vi, pi;
};

struct Rat {
	ll a, b;

	// a / b < rhs.a / rhs.b?
	bool operator<(const Rat& rhs) const {
		return a * rhs.b < b * rhs.a;
	}
	ll modv() const { return a * modPow(b, MOD-2) % MOD; }
};

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

	int n;
	cin >> n;

	SegTree seg(n);

	vector<Atom> atoms(n);
	for (auto& v : atoms) cin >> v.xi >> v.vi >> v.pi;

	const ll HI = modPow(100, MOD - 2);
	for (int i = 0; i < n; ++i) {
		int prob0 = (100 - atoms[i].pi) * HI % MOD;
		int prob1 = atoms[i].pi * HI % MOD;
		seg.setv(i, prob0, prob1, prob0, prob1);
	}

	vector<pair<Rat, pair<int, pair<int, int>>>> que;
	for (int i = 0; i+1 < n; ++i) {
		ll dist = atoms[i+1].xi - atoms[i].xi;
		for (int a = 0; a < 2; ++a) {
			for (int b = 0; b < 2; ++b) {
				ll vel = (a ? 1 : -1) * atoms[i].vi + (b ? -1 : 1) * atoms[i+1].vi;
				Rat r = {dist, vel};
				if (vel > 0) que.push_back({r, {i, {a, b}}}); // Collision eventually happens
			}
		}
	}
	sort(que.begin(), que.end());

	ll res = 0;
	for (auto pr : que) {
		ll t = pr.first.modv();
		int i = pr.second.first;
		int a = pr.second.second.first;
		int b = pr.second.second.second;

		ll prob = seg.prob(i+1, a, b);
		res = (res + prob * t) % MOD;
		seg.zero(i+1, a, b);

		// cerr << "event " << i << ' ' << a << ' ' << b << ": " << t << ' ' << prob << '\n';
	}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <cassert>
#include <ctime>

using namespace std;

#ifdef WIN32
  #define LLD "%I64d"
#else
  #define LLD "%lld"
#endif

typedef pair<int, int> pii;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<ll> vll;
typedef vector<vll> vvll;

ll rdtsc() {
  ll tmp;
  asm("rdtsc" : "=A"(tmp));
  return tmp;
}

inline int myrand() {
  return abs((rand() << 15) ^ rand());
}

inline int rnd(int x) {
  return myrand() % x;
}

#define TASKNAME "text"
#define pb push_back
#define mp make_pair
#define EPS (1e-9)
#define INF ((int)1e9)
#define sqr(x) ((x) * (x))
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define sz(x) ((int)(x).size())

const int maxn = (int)2e5 + 10;
int value[maxn];
int pr[maxn], w[maxn], diff[maxn];
int bounds[maxn][2];

int get(int v) {
  if (pr[v] == v)
    return v;
  get(pr[v]);
  diff[v] += diff[pr[v]];
  pr[v] = pr[pr[v]];
  return pr[v];
}

int getValue(int v) {
  if (pr[v] == v)
    return 0;
  get(v);
  return diff[v];
}

void myUnion(int a, int b, int value) {
  //eprintf("add %d->%d  %d\n", a, b, value);
  assert(a == pr[a] && b == pr[b]);
  assert(a != b);
  if (w[a] == w[b])
    ++w[b];
  if (w[a] > w[b])
    swap(a, b), value = -value;
  pr[a] = b;
  diff[a] = -value;
  bounds[b][0] = min(bounds[b][0], bounds[a][0] + diff[a]);
  bounds[b][1] = max(bounds[b][1], bounds[a][1] + diff[a]);
  bounds[a][0] = bounds[a][1] = 0;
}

bool solve() {
  int n, m;
  if (scanf("%d%d", &n, &m) < 2)
    return 0;

  for (int i = 0; i < n; ++i)
    pr[i] = i, w[i] = 0, bounds[i][0] = bounds[i][1] = diff[i] = 0;

  int fail = -1;
  int res = -1;
  int maxSize = (n <= 2) ? -INF : 0;
  for (int i = 0; i < m; ++i) {
    int s, t, w, b;
    scanf("%d%d%d%d", &s, &t, &w, &b);
    --s, --t;
    if (fail != -1)
      continue;

    int value = w * b;
    if (get(s) == get(t)) {
      //eprintf("%d + %d = %d\n", getValue(s), value, getValue(t));
      if (getValue(s) + value != getValue(t)) {
        fail = i;
        continue;
      }
      continue;
    }
    int S = s, T = t;
    if (pr[S] != S)
      value += diff[S], S = pr[S];
    if (pr[T] != T)
      value -= diff[T], T = pr[T];

    assert(pr[S] == S && pr[T] == T);

    int vs[2] = {S, T};
    for (int it = 0; it < 2; ++it) {
      if (get(0) == vs[it] && bounds[vs[!it]][0] <= getValue(0) - value) {
        fail = i;
        break;
      }
      if (get(n - 1) == vs[it] && bounds[vs[!it]][1] >= getValue(n - 1) - value) {
        fail = i;
        break;
      }
      value = -value;
    }

    if (fail != -1)
      continue;

    myUnion(S, T, value);

    if (res == -1 && get(0) == get(n - 1)) {
      res = getValue(n - 1) - getValue(0);
    }

    int root = get(S);
    if (get(0) != root && get(n - 1) != root) {
      int size = bounds[root][1] - bounds[root][0];
      maxSize = max(maxSize, size);
    }
    if (res != -1 && maxSize >= res) {
      //eprintf("%d >= %d\n", maxSize, res);
      fail = i;
      continue;
    }
    //for (int j = 0; j < n; ++j)
    //  eprintf("%d[%d..%d]%c", getValue(j), bounds[j][0], bounds[j][1], " \n"[j == n - 1]);
  }

  if (fail != -1)
    printf("BAD %d\n", fail + 1);
  else {
    if (res != -1)
      printf("%d\n", res);
    else
      printf("UNKNOWN\n");
  }
  return 1;
}

int main() {
  srand(rdtsc());
#ifdef DEBUG
  freopen(TASKNAME".in", "r", stdin);
  freopen(TASKNAME".out", "w", stdout);
#endif

  while (1) {
    if (!solve())
      break;
    #ifdef DEBUG
      eprintf("%.18lf\n", (double)clock() / CLOCKS_PER_SEC);
    #endif
  }
  return 0;
}


#include <bits/stdc++.h>

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define SZ(x) ((int) (x).size())
#define ALL(x) x.begin(), x.end()

using namespace std;
typedef long long LL;
typedef unsigned int uint;

template <typename T> inline bool cmin(T & a, const T & b) { return a > b ? a = b, 1 : 0;}
template <typename T> inline bool cmax(T & a, const T & b) { return a < b ? a = b, 1 : 0;}

const int MaxN = 205;
uint n, d, M, c[MaxN][MaxN], f[MaxN][MaxN], g[MaxN];

nt main() {
	cin >> n >> d >> M;
	c[0][0] = 1;
	for (int i = 1; i <= n; i++) {
		c[i][0] = 1;
		for (int j = 1; j <= i; j++)
			c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % M;
	}
	f[1][0] = 1;
	for (int i = 2; i <= n; i++) {
		for (int k = 0; k < d; k++)
			(g[i - 1] += f[i - 1][k]) %= M;
		for (int j = 1; j < i; j++)
			for (int k = 0; k < d; k++)
				f[i][k + 1] = (f[i][k + 1] + (LL) f[i - j][k] * g[j] % M * c[i - 2][j - 1]) % M;
	}
	int ans = 0;
	for (int i = 0; i < n; i++)
		for (int j = 0; j <= d; j++)
			for (int k = 0; j + k <= d; k++) {
				if(k == 1) continue;
				ans = (ans + (LL) f[i + 1][j] * f[n - i][k]) % M;
			}
	ans = (LL) ans * 2 * n * (n - 1) % M;
	cout << ans << endl;
	return 0;
}


#include <iostream>
using namespace std;

unsigned long long n;
unsigned long long c1, c2;

unsigned long long mature;

void getMature()
{
	mature = 0;
	char c;
	for (int i = 0; i < n; i++)
	{
		cin >> c;
		if (c == '1')
			mature++;
	}
}

unsigned long long getCost(unsigned long long size, unsigned long long count)
{
	return count * (c1 + c2 * (size - 1) * (size - 1));
}

unsigned long long check(unsigned long long group)
{
	unsigned long long k = n / group;
	unsigned long long r = n % group;
	unsigned long long smallGroup = group - r;
	unsigned long long bigGroup = r;
	return getCost(k, smallGroup) + getCost(k + 1, bigGroup);
}

unsigned long long all()
{
	unsigned long long min = pow(2, 64) - 1;
	unsigned long long current;
	for (int i = mature; i > 0; i--)
	{
		current = check(i);
		if (current < min)
			min = current;
	}
	return min;
}

int main()
{
	cin >> n >> c1 >> c2;
	getMature();
	cout << all();
	return 0;
}


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

int main()
{
	int a, h, w;
	cin >> a >> h >> w;

	if (a > h || a > w)
	{
		printf("-1\n");
		return 0;
	}

	if (a <= 1000000)
	{
		int x = max(1, (w - a) / (2 * a)), y = max(1, (h - a) / (2 * a));
		double ans = 1e100;
		while (w >= a * x && h >= a * y)
		{
			double d1 = double(w - a * x) / (x + 1);
			double d2 = double(h - a * y) / (y + 1);

			if ((w - a * x) * 1ll * (y + 1) == (h - a * y) * 1ll * (x + 1))
			{
				ans = min(ans, d1);
				--x; --y;
			}
			else if (d1 > d2) --x;
			else --y;
		}

		if (ans == 1e100) printf("-1\n");
		else printf("%.9f\n", ans);
	}
	else
	{
		double ans = 1e100;
		for (int x = 1; w >= a * x; x++)
		{
			for (int y = 1; h >= a * y; y++)
			{
				if ((w - a * x) * 1ll * (y + 1) == (h - a * y) * 1ll * (x + 1)) ans = min(ans, double(w - a * x) / (x + 1));
			}
		}

		if (ans == 1e100) printf("-1\n");
		else printf("%.9f\n", ans);
	}
}