/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author majk
 */

#ifndef MAJK_LIB
#define MAJK_LIB

#include <vector>
#include <stack>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <iomanip>
#include <set>
#include <functional>
#include <algorithm>
#include <numeric>
#include <cassert>
#include <cmath>
#include <string>
#include <queue>
#include <array>
#include <bitset>
using namespace std;

#define x first
#define y second
typedef std::pair<int,int> pii; typedef long long ll; typedef unsigned long long ull; typedef unsigned int ui; typedef pair<ui,ui> puu;

template <typename T, typename U> std::istream&operator>>(std::istream&i, pair<T,U>&p) {i >> p.x >> p.y; return i;}
template<typename T>std::istream&operator>>(std::istream&i,vector<T>&t) {for(auto&v:t){i>>v;}return i;}
template <typename T, typename U> std::ostream&operator<<(std::ostream&o, const pair<T,U>&p) {o << p.x << ' ' << p.y; return o;}
template<typename T>std::ostream&operator<<(std::ostream&o,const vector<T>&t) {if(t.empty())o<<'\n';for(size_t i=0;i<t.size();++i){o<<t[i]<<" \n"[i == t.size()-1];}return o;}
template<typename T> using minheap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using maxheap = priority_queue<T, vector<T>, less<T>>;
ui logceil(ll x) { return x?8*sizeof(ll)-__builtin_clzll(x):0; }

namespace std { template<typename T,typename U>struct hash<pair<T,U>>{hash<T>t;hash<U>u;size_t operator()(const pair<T,U>&p)const{return t(p.x)^(u(p.y)<<7);}}; }
template<typename T,typename F>T bsh(T l,T h,const F&f){T r=-1,m;while(l<=h){m=(l+h)/2;if(f(m)){l=m+1;r=m;}else{h=m-1;}}return r;}
template<typename F> double bshd(double l,double h,const F&f,double p=1e-9){ui r=3+(ui)log2((h-l)/p);while(r--){double m=(l+h)/2;if(f(m)){l=m;}else{h=m;}}return (l+h)/2;}
template<typename T,typename F>T bsl(T l,T h,const F&f){T r=-1,m;while(l<=h){m=(l+h)/2;if(f(m)){h=m-1;r=m;}else{l=m+1;}}return r;}
template<typename F> double bsld(double l,double h,const F&f,double p=1e-9){ui r=3+(ui)log2((h-l)/p);while(r--){double m=(l+h)/2;if(f(m)){h=m;}else{l=m;}}return (l+h)/2;}
template<typename T> T gcd(T a,T b) { if (a<b) swap(a,b); return b?gcd(b,a%b):a; }

template<typename T>class vector2:public vector<vector<T>>{public:vector2(){} vector2(size_t a,size_t b,T t=T()):vector<vector<T>>(a,vector<T>(b,t)){}};
template<typename T>class vector3:public vector<vector2<T>>{public:vector3(){} vector3(size_t a,size_t b,size_t c,T t=T()):vector<vector2<T>>(a,vector2<T>(b,c,t)){}};
template<typename T>class vector4:public vector<vector3<T>>{public:vector4(){} vector4(size_t a,size_t b,size_t c,size_t d,T t=T()):vector<vector3<T>>(a,vector3<T>(b,c,d,t)){}};
template<typename T>class vector5:public vector<vector4<T>>{public:vector5(){} vector5(size_t a,size_t b,size_t c,size_t d,size_t e,T t=T()):vector<vector4<T>>(a,vector4<T>(b,c,d,e,t)){}};

#endif
#ifndef MOD_H
#define MOD_H

template <unsigned int N> class Field {
    typedef unsigned int ui;
    typedef unsigned long long ull;
	inline ui pow(ui a, ui p){ui r=1,e=a;while(p){if(p&1){r=((ull)r*e)%N;}e=((ull)e*e)%N;p>>=1;}return r;}
	/*extended GCD(slow):ll t=0,nt=1,r=N,nr=a;while(nr){ll q=r/nr;t-=q*nt;swap(t,nt);r-=q*nr;swap(r,nr);}assert(r<=1);return(t<0)?t+N:t;*/
	inline ui inv(ui a){return pow(a,N-2);}
public:
    inline Field(int x = 0) : v(x) {}
	inline Field<N> pow(int p){return (*this)^p; }
	inline Field<N> operator^(int p){return {(int)pow(v,(ui)p)};}
    inline Field<N>&operator+=(const Field<N>&o) {if (v+o.v >= N) v += o.v - N; else v += o.v; return *this; }
    inline Field<N>&operator-=(const Field<N>&o) {if (v<o.v) v -= o.v-N; else v-=o.v; return *this; }
    inline Field<N>&operator*=(const Field<N>&o) {v=(ull)v*o.v % N; return *this; }
    inline Field<N>&operator/=(const Field<N>&o) { return *this*=inv(o.v); }
    inline Field<N> operator+(const Field<N>&o) const {Field<N>r{*this};return r+=o;}
    inline Field<N> operator-(const Field<N>&o) const {Field<N>r{*this};return r-=o;}
    inline Field<N> operator*(const Field<N>&o) const {Field<N>r{*this};return r*=o;}
    inline Field<N> operator/(const Field<N>&o) const {Field<N>r{*this};return r/=o;}
    inline Field<N> operator-() {if(v) return {(int)(N-v)}; else return {0};};
    inline Field<N>& operator++() { ++v; if (v==N) v=0; return *this; }
    inline Field<N> operator++(int) { Field<N>r{*this}; ++*this; return r; }
    inline Field<N>& operator--() { --v; if (v==-1) v=N-1; return *this; }
    inline Field<N> operator--(int) { Field<N>r{*this}; --*this; return r; }
    inline bool operator==(const Field<N>&o) const { return o.v==v; }
	inline bool operator!=(const Field<N>&o) const { return o.v!=v; }
	inline explicit operator ui() const { return v; }
	inline static vector<Field<N>>fact(int t){vector<Field<N>>F(t+1,1);for(int i=2;i<=t;++i){F[i]=F[i-1]*i;}return F;}
	inline static vector<Field<N>>invfact(int t){vector<Field<N>>F(t+1,1);Field<N> X{1};for(int i=2;i<=t;++i){X=X*i;}F[t]=1/X;for(int i=t-1;i>=2;--i){F[i]=F[i+1]*(i+1);}return F;}
private: ui v;
};
template<unsigned int N>istream &operator>>(std::istream&is,Field<N>&f){unsigned int v;is>>v;f=v;return is;}
template<unsigned int N>ostream &operator<<(std::ostream&os,const Field<N>&f){return os<<(unsigned int)f;}
template<unsigned int N>Field<N> operator+(int i,const Field<N>&f){return Field<N>(i)+f;}
template<unsigned int N>Field<N> operator-(int i,const Field<N>&f){return Field<N>(i)-f;}
template<unsigned int N>Field<N> operator*(int i,const Field<N>&f){return Field<N>(i)*f;}
template<unsigned int N>Field<N> operator/(int i,const Field<N>&f){return Field<N>(i)/f;}

typedef Field<1000000007> FieldMod;

struct Ring {
	template <typename T>
	static T div(T p, T q, T N) {
		T t=0,nt=1,r=N,nr=q;
		while(nr!=0){ T q=r/nr;t-=q*nt;r-=q*nr;swap(t,nt);swap(r,nr); }
		t=(t<0)?t+N:t;
		r=(r<0)?r+N:r;
		if (gcd(p,N)%r!=0) { return 0; }
		return (t*p/r)%N;
	}
};
#endif

constexpr int S = 128;
namespace std {
    template<std::size_t N> bool operator<(const std::bitset<N> &x, const std::bitset<N> &y) {
        for (int i = N - 1; i >= 0; i--) {
            if (x[i] ^ y[i]) return y[i];
        }
        return false;
    }
}

class E2MarekAndMatchingHardVersion {
public:
    void solve(istream& cin, ostream& cout) {
        int N; cin >> N;
        vector2<int> P(N, N); cin >> P;
        map<bitset<S>, FieldMod> G;
        G[1] = 1;
        for (int i = 0; i < N; ++i) {
            map<vector<int>, FieldMod> H;
            for (auto g: G) {
                vector<int> S;
                for (int m = 0; m < (1<<N); ++m)if (g.x[m]) S.push_back(m);
                H[S] = g.y;
            }
            G.clear();
            for (int j = 0; j < (1<<N); ++j) {
                FieldMod pst = 1;
                for (int k = 0; k < N; ++k) if (j&1<<k) pst *= P[i][k]; else pst *= 100 - P[i][k];
                for (auto h: H) {
                    bitset<S> ans;
                    for (int l = 0; l < N; ++l) {
                        if ((j&1<<l) == 0) continue;
                        for (int m: h.x) if ((m&1<<l) == 0) ans[m | 1<<l] = true;
                    }
                    if (ans.any()) G[ans] += h.y * pst;
                }
            }
        }

        FieldMod ans = 0;
        for (auto g: G) ans += g.y;
        for (int i = 0; i < N*N; ++i) ans /= 100;
        cout << ans << endl;
    }
};

int main() {
	ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
	E2MarekAndMatchingHardVersion solver;
	std::istream& in(std::cin);
	std::ostream& out(std::cout);
	solver.solve(in, out);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int mod = 1000000007;

const int N = 1 << 20;

int fpow(int x, int y) {
  int ret = 1;
  while(y) {
    if(y & 1) ret = (1LL * ret * x) % mod;
    x = (1LL * x * x) % mod;
    y >>= 1;
  }
  return ret;
}

const int M = 21;

int n;
int f[N], g[N];
int p[M][M];

int idx[2][N];
int rev[N];
int matched[M];
int adj[M][M];

void work(int *f, vector < int > l, vector < int > r, vector < int > subgraph, int *idx) {

  vector < pair < int, int > > edges;
  for(int x : l) {
    for(int y : r) {
      edges.emplace_back(x, y);
    }
  }

  for(int mask = 0; mask < (1 << edges.size()); ++mask) {
    int rate = 1;
    int newmask = 0;
    for(int i = 0; i < edges.size(); ++i) {
      if(mask & (1 << i)) {
        rate = (1LL * rate * p[edges[i].first][edges[i].second]) % mod;
        adj[edges[i].first][edges[i].second] = 1;
      }
      else {
        rate = (1LL * rate * (1 - p[edges[i].first][edges[i].second])) % mod;
        adj[edges[i].first][edges[i].second] = 0;
      }
      rate = (rate + mod) % mod;
    }

    for(int gr : subgraph) {
      vector < int > perm, indices;
      for(int x : l) perm.push_back(x);
      for(int i = 0; i < n; ++i) if(gr & (1 << i)) {
        indices.push_back(i + n);
      }

      bool flag = false;
      do{
        bool ok  = true;
        for(int i = 0; i < perm.size(); ++i){
          if(!adj[perm[i]][indices[i]]) ok = false;
        }
        if(ok) {
          flag = true;
          break;
        }
      }
      while(next_permutation(indices.begin(), indices.end()));
      if(flag) newmask |= (1 << idx[gr]);
    }
    f[newmask] += rate;
    f[newmask] %= mod;
  }
}

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

  cin >> n;
  for(int i = 0; i < n; ++i) {
    for(int j = 0; j < n; ++j) {
      cin >> p[i][j + n];
      p[i][j + n] = (1LL * p[i][j + n] * fpow(100, mod - 2)) % mod;
    }
  }

  if(n == 1) {
    cout << p[0][1];
    return 0;
  }

  int m1 = n / 2;
  int m2 = n - m1;

  int cnt = 0, cnt2 = 0;
  vector < int > sub1, sub2;
  for(int mask = 0; mask < (1 << n); ++mask) {
    if(__builtin_popcount(mask) == m1) {
      idx[0][mask] = cnt++;
      sub1.push_back(mask);
    }
    if(__builtin_popcount(mask) == m2) {
      idx[1][mask] = cnt2++;
      sub2.push_back(mask);
    }
  }

  for(int i = 0; i < sub2.size(); ++i) {
    int mask = sub2[i];
    for(int bigmask = 0; bigmask < (1 << cnt2); ++bigmask) {
      if(bigmask & (1 << i)) rev[bigmask] |= (1 << idx[0][(1 << n) - 1 - mask]);
    }
  }

  vector < int > l1, l2;
  vector < int > r;
  for(int i = n; i < n + n; ++i) {
    r.push_back(i);
  }

  for(int i = 0; i < m1; ++i) l1.push_back(i);
  for(int i = m1; i < n; ++i) l2.push_back(i);

  work(f, l1, r, sub1, idx[0]);
  work(g, l2, r, sub2, idx[1]);

  for(int i = 0; i < cnt; ++i) {
    for(int mask = 0; mask < (1 << cnt); ++mask) {
      if(mask & (1 << i)) {
        f[mask] += f[mask ^ (1 << i)];
        f[mask] %= mod;
      }
    }
  }

  long long ans = 0;

  for(int mask = 1; mask < (1 << cnt2); ++mask) {
    int w = (1 - f[(1 << cnt) - 1 - rev[mask]] + mod) % mod;
//    cout << mask << " " << rev[mask] << " " << w << " " << g[mask] << endl;
    ans += 1LL * w * g[mask] % mod;
    ans %= mod;
  }

  cout << ans;

  return 0;
}

/// moi mask,


#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define fst first
#define snd second
#define sz(x) (int) ((x).size())
#define forn(i, n) for (int i = 0; (i) < (n); ++i)
#define fornr(i, n) for (int i = (n) - 1; (i) >= 0; --i)
#define forab(i, a, b) for (int i = (a); (i) < (b); ++i)
#define forba(i, a, b) for (int i = (b) - 1; (i) >= (a); --i)
#define forit(it, c) for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define all(c) (c).begin(), (c).end()

#ifdef LOCAL
	#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
	#define eprintf(...) static_cast<void>(0)
#endif

#ifdef _WIN32
	#define I64 "%I64d"
#else
	#define I64 "%lld"
#endif

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef unsigned int uint;
typedef vector<int> vi;
typedef pair<int, int> pii;

#define FNAME ""

const int MAX_N = 10, MOD = 1e9 + 7;

int a[MAX_N][MAX_N];

inline int add(int a, int b) {
	a += b;
	return a >= MOD ? a - MOD : a;
}

inline int sub(int a, int b) {
	a -= b;
	return a < 0 ? a + MOD : a;
}

inline int mul(int a, int b) {
	return (a * 1ll * b) % MOD;
}

inline int power(int a, int n) {
	if (!n)
		return 1;
	int b = power(a, n / 2);
	b = mul(b, b);
	return n & 1 ? mul(b, a) : b;
}

inline int rev(int a) {
	return power(a, MOD - 2);
}

inline int divv(int a, int b) {
	return mul(a, rev(b));
}

int main() {
#ifdef LOCAL
	freopen(FNAME".in", "r", stdin);
	freopen(FNAME".out", "w", stdout);
#endif

	int n;
	scanf("%d", &n);
	forn (i, n)
		forn (j, n) {
			scanf("%d", &a[i][j]);
			a[i][j] = divv(a[i][j], 100);
		}
	vector<pair<vector<char>, int>> sets, newSets;
	vector<char> newSet;
	sets.pb(mp(vector<char>{0}, 1));
	forn (g, n) {
		newSets.clear();
		forn (mask, (1 << n)) {
			int value = 1;
			forn (j, n)
				if (mask & (1 << j))
					value = mul(value, a[j][g]);
				else
					value = mul(value, sub(1, a[j][g]));
			for (auto& np : sets) {
				newSet.clear();
				for (int mask2 : np.fs) {
					int possible = ~mask2 & mask;
					while (possible) {
						int pos = possible & (-possible);
						newSet.pb(mask2 | pos);
						possible ^= pos;
					}
				}
				if (!sz(newSet))
					continue;
				sort(all(newSet));
				newSet.resize(unique(all(newSet)) - newSet.begin());
				newSets.pb(mp(newSet, mul(np.sc, value)));
			}
		}
		sort(all(newSets));
		sets.clear();
		int i = 0;
		while (i < sz(newSets)) {
			int j = i;
			int sumVal = 0;
			while (j < sz(newSets) && newSets[j].fs == newSets[i].fs)
				sumVal = add(sumVal, newSets[j].sc), j++;
			sets.pb(mp(newSets[i].fs, sumVal));
			i = j;
		}
	}
	int res = 0;
	for (auto& np : sets)
		res = add(res, np.sc);
	cout << res << "\n";
	return 0;
}


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

const int MOD = 1e9 + 7;
#define BS bitset < 128 >
unordered_map < BS , int > id; int N , cnt , P[7][7] , dp[2][70003] , trans[70003][128] , prob[128] , iv100;

int poww(long long a , int b){int times = 1; while(b){if(b & 1) times = times * a % MOD; a = a * a % MOD; b >>= 1;} return times;}

int dfs(BS &x){
	if(id.find(x) != id.end()) return id[x];
	int nd = id[x] = ++cnt; BS tmp[7] , tp;
	for(int i = 0 ; i < N ; ++i) for(int j = 0 ; j < 1 << N ; ++j) tmp[i][j | (1 << i)] = tmp[i][j | (1 << i)] | x[j];
	for(int i = 0 ; i < 1 << N ; ++i){
		tp = x; for(int j = 0 ; j < N ; ++j) if(i >> j & 1) tp |= tmp[j];
		trans[nd][i] = dfs(tp);
	}
	return nd;
}

int main(){
	cin >> N; BS tmp; tmp.set(0); dfs(tmp); iv100 = poww(100 , MOD - 2); cerr << id.size() << endl;
	for(int i = 0 ; i < N ; ++i) for(int j = 0 ; j < N ; ++j) cin >> P[i][j];
	dp[0][1] = 1; int x = 0;

	for(int i = 0 ; i < N ; ++i){
		for(int j = 0 ; j < 1 << N ; ++j){
			prob[j] = 1;
			for(int k = 0 ; k < N ; ++k)
				prob[j] = 1ll * prob[j] * iv100 % MOD * (j >> k & 1 ? P[i][k] : 100 - P[i][k]) % MOD;
		}

		memset(dp[x ^= 1] , 0 , sizeof(dp[x]));
		for(int j = 1 ; j <= cnt ; ++j)
			if(dp[x ^ 1][j])
				for(int k = 0 ; k < 1 << N ; ++k)
					dp[x][trans[j][k]] = (dp[x][trans[j][k]] + 1ll * dp[x ^ 1][j] * prob[k]) % MOD;
	}
	for(int i = 0 ; i < 1 << N ; ++i) tmp.set(i);
	cout << dp[x][id[tmp]] << endl; return 0;
}


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto& a : x)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rsz resize

const int MOD = 1000000007; // 998244353
const ll INF = 1e18;
const int MX = 200005;
const ld PI = 4*atan((ld)1);

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

namespace input {
	template<class T> void re(complex<T>& x);
	template<class T1, class T2> void re(pair<T1,T2>& p);
	template<class T> void re(vector<T>& a);
	template<class T, size_t SZ> void re(array<T,SZ>& a);

	template<class T> void re(T& x) { cin >> x; }
	void re(double& x) { string t; re(t); x = stod(t); }
	void re(ld& x) { string t; re(t); x = stold(t); }
	template<class T, class... Ts> void re(T& t, Ts&... ts) {
		re(t); re(ts...);
	}

	template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = cd(a,b); }
	template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
	template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
	template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
	void pr(int x) { cout << x; }
	void pr(long x) { cout << x; }
	void pr(ll x) { cout << x; }
	void pr(unsigned x) { cout << x; }
	void pr(unsigned long x) { cout << x; }
	void pr(unsigned long long x) { cout << x; }
	void pr(float x) { cout << x; }
	void pr(double x) { cout << x; }
	void pr(ld x) { cout << x; }
	void pr(char x) { cout << x; }
	void pr(const char* x) { cout << x; }
	void pr(const string& x) { cout << x; }
	void pr(bool x) { pr(x ? "true" : "false"); }

	template<class T1, class T2> void pr(const pair<T1,T2>& x);
	template<class T> void pr(const T& x);

	template<class T, class... Ts> void pr(const T& t, const Ts&... ts) {
		pr(t); pr(ts...);
	}
	template<class T1, class T2> void pr(const pair<T1,T2>& x) {
		pr("{",x.f,", ",x.s,"}");
	}
	template<class T> void pr(const T& x) {
		pr("{"); // const iterator needed for vector<bool>
		bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0;
		pr("}");
	}

	void ps() { pr("\n"); } // print w/ spaces
	template<class T, class... Ts> void ps(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(" "); ps(ts...);
	}

	void pc() { pr("]\n"); } // debug w/ commas
	template<class T, class... Ts> void pc(const T& t, const Ts&... ts) {
		pr(t); if (sizeof...(ts)) pr(", "); pc(ts...);
	}
	#define dbg(x...) pr("[",#x,"] = ["), pc(x);
}

using namespace output;

namespace io {
	void setIn(string s) { freopen(s.c_str(),"r",stdin); }
	void setOut(string s) { freopen(s.c_str(),"w",stdout); }
	void setIO(string s = "") {
		cin.sync_with_stdio(0); cin.tie(0); // fast I/O
		cin.exceptions(cin.failbit); // ex. throws exception when you try to read letter into int
		if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
	}
}

using namespace io;

template<class T> T invGeneral(T a, T b) {
	a %= b; if (a == 0) return b == 1 ? 0 : -1;
	T x = invGeneral(b,a);
	return x == -1 ? -1 : ((1-(ll)b*x)/a+b)%b;
}

template<class T> struct modular {
	T val;
	explicit operator T() const { return val; }
	modular() { val = 0; }
	modular(const ll& v) {
		val = (-MOD <= v && v <= MOD) ? v : v % MOD;
		if (val < 0) val += MOD;
	}

	// friend ostream& operator<<(ostream& os, const modular& a) { return os << a.val; }
	friend void pr(const modular& a) { pr(a.val); }
	friend void re(modular& a) { ll x; re(x); a = modular(x); }

	friend bool operator==(const modular& a, const modular& b) { return a.val == b.val; }
	friend bool operator!=(const modular& a, const modular& b) { return !(a == b); }
	friend bool operator<(const modular& a, const modular& b) { return a.val < b.val; }

	modular operator-() const { return modular(-val); }
	modular& operator+=(const modular& m) { if ((val += m.val) >= MOD) val -= MOD; return *this; }
	modular& operator-=(const modular& m) { if ((val -= m.val) < 0) val += MOD; return *this; }
	modular& operator*=(const modular& m) { val = (ll)val*m.val%MOD; return *this; }
	friend modular pow(modular a, ll p) {
		modular ans = 1; for (; p; p /= 2, a *= a) if (p&1) ans *= a;
		return ans;
	}
	friend modular inv(const modular& a) {
		auto i = invGeneral(a.val,MOD); assert(i != -1);
		return i;
	} // equivalent to return exp(b,MOD-2) if MOD is prime
	modular& operator/=(const modular& m) { return (*this) *= inv(m); }

	friend modular operator+(modular a, const modular& b) { return a += b; }
	friend modular operator-(modular a, const modular& b) { return a -= b; }
	friend modular operator*(modular a, const modular& b) { return a *= b; }

	friend modular operator/(modular a, const modular& b) { return a /= b; }
};

typedef modular<int> mi;
typedef pair<mi,mi> pmi;
typedef vector<mi> vmi;
typedef vector<pmi> vpmi;

typedef unsigned long long ul;

ul no[7];
int n;
mi p[7][7];

ul po(int x) {
    return (ul)1<<x;
}

int main() {
	setIO(); re(n); // can we match for each of
	F0R(i,n) F0R(j,n) {
	    re(p[i][j]); p[i][j] /= 100;
	    // ps("??",p[i][j]);
	}
	F0R(i,n) {
	    F0R(j,1<<n) if (!((j>>i)&1)) {
	        no[i] |= po(j);
	        // ps("??",i,j);
	    }
	    // ps("H")
	}
	// ps(no[0],no[1]);
	unordered_map<ul,mi> m; m[1] = 1;
	F0R(i,n) {
	    unordered_map<ul,mi> M;
	    trav(t,m) {
    	    F0R(j,1<<n) {
    	        ul res = 0; mi prob = 1;
    	        F0R(k,n) {
    	            if (j&(1<<k)) {
    	                prob *= p[i][k];
    	                res |= (t.f&no[k])<<((1<<k));
    	            } else {
    	                prob *= 1-p[i][k];
    	            }
    	        }
    	        // ps("WUT",t,i,j,res);
    	        M[res] += t.s*prob;
    	    }
    	}
    	// ps("??");
    	swap(m,M);
	}
    // trav(t,m) ps(t.f,t.s);
	ps(m[po((1<<n)-1)]);
	// you should actually read the stuff at the bottom
}

/* stuff you should look for
	* int overflow, array bounds
	* special cases (n=1?), set tle
	* do smth instead of nothing and stay organized
*/


#include <stdio.h>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <set>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <complex>
#include <map>
#include <unordered_map>
#include <queue>
#include <array>
#include <bitset>
#include <chrono>
#include <random>
using namespace std;
typedef long double ld;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef vector<pii> vii;
typedef vector<string> vs;
const int mod = 1e9 + 7;

ll mpow(ll x, ll n) {
  ll res = 1;
  while (n) {
    if (n & 1) res = res * x % mod;
    x = x * x % mod;
    n /= 2;
  }
  return res;
}

const int DEBUG = 0;

unordered_map<ll, vi> tovi;

ll mhash(const vi& v) {
  ll s = 0;
  for (int x : v) {
    s = 131 * s + x + 1;
  }
  if (!tovi.count(s)) {
    tovi[s] = v;
  }
  return s;
}

int main() {
  //mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  std::ios::sync_with_stdio(false); std::cin.tie(0);
  int n = 6;
  if (!DEBUG) cin >> n;
  vvl p(n, vl(n, 50));
  vi pc(1 << n);
  for (int i = 0; i < (int)pc.size(); ++i) pc[i] = __builtin_popcount(i);
  for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) {
    if (!DEBUG) cin >> p[i][j];
    p[i][j] = p[i][j] * mpow(100, mod - 2) % mod;
  }
  map<ll, int> d;
  d[mhash(vi(1 << n))] = 1;
  ll res = 0;
  for (int i = 0; i < n; ++i) {
    map<ll, int> nd;
    cerr << i << ' ' << d.size() << endl;
    vl prods(1 << n);
    for (int mask = 0; mask < (1 << n); ++mask) {
      ll prod = 1;
      for (int j = 0; j < n; ++j) {
        if (mask & (1 << j)) {
          prod = prod * p[i][j] % mod;
        } else {
          prod = prod * (1 - p[i][j]) % mod;
        }
      }
      prods[mask] = prod;
    }
    for (const auto& it : d) {
      vi v = tovi[it.first];
      for (int mask = 0; mask < (1 << n); ++mask) {
        vi nv = v;
        bool fail = 0;
        for (int nmask = mask; nmask < (1 << n); nmask = (nmask + 1) | mask) {
          nv[nmask]++;
          if (nv[nmask] > pc[nmask]) {
            fail = 1;
            break;
          }
        }
        if (fail) continue;
        for (int j = 0; j < (int)nv.size(); ++j) {
          if (nv[j] + n - 1 - i <= pc[j]) nv[j] = 0;
        }
        ll h = mhash(nv);
        nd[h] = (nd[h] + prods[mask] * it.second) % mod;
      }
    }
    d.swap(nd);
  }
  for (auto& it : d) {
    res = (res + it.second) % mod;
  }
  cout << (res % mod + mod) % mod << endl;
  return 0;
}


/**
 * June 2012 Codechef Long Contest
 *
 * Problem:     MATCH
 * Author:      Anton Lunyov (Tester)
 * Complexity:  O(S * 2^N * N + M * 2^N * S), where S defined below
 * Timing:      0.03 out of 3
 *
 * Description:
 * Recall that we have two sets of vertexes U with |U|=n<=6
 * and V that can be quite large. We call subsets of vertexes in U by masks.
 * We scan vertexes in V one by one. At each moment we should know
 * what probability has each possible graph. But since we care only about
 * value of maximum matching we unite all graphs in several groups.
 * Namely the only thing that we should know is what masks satisfy Hall lemma
 * in the current graph. Mask T satisfies Hall lemma if
 * for each submask S of T we have |ADJ(S)|>=|S|
 * where ADJ(S) is the set of vertexes from V of the graph
 * that are adjacent to some vertex of S. We store this set of masks
 * as a "supermask" of length 2^n (since n<=6 we can use 64bit integer type).
 * Such supermasks will be our DP states.
 * Surprisingly but there is relatively small number of such states.
 */

#include <cstdio>
#include <bitset>
using namespace std;

typedef unsigned long long ULL;
//typedef __uint128_t u128;
//typedef __uint128_t u128;
#define next nxttt
#define prev prv
typedef bitset<128> u128;
typedef long long ll;
const ll mod=1000000007;
u128 zero;

ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}

inline int bit(int n) {
    return 1 << n;
}

inline u128 bitu128(int n) {
	u128 p=zero; p[n]=1;
	return p;
}

const int maxN = 7; // this solution is so fast that can handle n=6 easily
const int max2N = 1 << maxN;
const int maxM = 100;

const int maxS = 64184; // the number of DP states for n=6

// sizes[i] = NextPrime[2 * len[i]]
// where len[i] is the number of DP states for n=i
// It is used as the size of hash table when n=i
const int sizes[maxN + 1] = {0, 5, 11, 37, 137, 821, 7529, 164184};
const int maxSZ = 164184; // the maximum size for hash table

// "bfs" is the queue of DP states traversed in some convenient order
// but it is not real queue; we do not erase old states
// "len" is the current number of states in "bfs"
// After precalc "len" is equal to the total number of DP states
int len;
u128 bfs[maxS];

// hash table for efficient finding whether the DP state is new
int SZ; // size of hash table

// "what[i]" is some DP state; they are stored in quite random order here
u128 what[maxSZ];

// bfs[ind[i]] = what[i]
// So "ind[i]" is the index of DP state "what[i]" in "bfs" array
int ind[maxSZ];

// return the index of DP state "state" in the array "bfs"
// if this state is new then insert it to the hash table and to the array "bfs"
int get_ind(u128 state) {
    // position where we try to insert "state"
    int pos=0;
    for (int i=0;i<128;i++) {
    	pos=(pos*2+state[i])%SZ;
    }
    //int pos = state % SZ;
    while (true) {
        // if "state" has already been before we break
        if (what[pos] == state) {
            break;
        }
        if (what[pos] == 0) {
            what[pos] = state;
            bfs[len] = state;
            ind[pos] = len;
            ++len;
            return len-1;
        }

        ++pos;
        if (pos==SZ) {
            pos = 0;
        }
    }
    // in the end "what[pos]" is always equal to "state"
    // so "ind[pos]" is correct index of "state" in "bfs"
    return ind[pos];
}

// next[mask][k] is the index of DP state (in "bfs" array)
// that we obtain from the DP state "bfs[k]"
// when we add a new vertex v from V such that ADJ(v) = mask to the graph
int next[max2N][maxS];

// match[k] is the size of maximum matching of DP state "bfs[k]"
int match[maxS];

void precalc(int n) {
    int N = bit(n);

    u128 fixed_size[maxN + 1] = {0};
    for (int mask = 0; mask < N; ++mask)
    {
        int cnt = 0;
        for (int i = 0; i < n; ++i) {
            if (mask & bit(i)) {
                cnt++;
            }
        }
        // "cnt" is now the number of
        fixed_size[cnt] |= bitu128(mask);
    }

    // initialization of hash table and "bfs" array
    SZ = sizes[n];
    for (int k = 0; k < SZ; ++k) {
        what[k] = 0;
    }
    len=0;

    // state = 1 represents empty graph
    get_ind(1);

    for (int k = 0; k < len; ++k) {
        // our current state
        u128 state = bfs[k];

        // pred_hall[i] is the supermask of masks
        // that will satisfy Hall lemma condition if we add edge (U[i],v)
        // to the graph with the given DP state
        // (with possible exclusion of some masks from the current "state")
        // One can see that pred_hall[i] can be obtained
        // by including vertex "i" to each "mask" of the "state"
        u128 pred_hall[maxN] = {0};
        for (int mask = 0; mask < N; ++mask) {
            if ((state & bitu128(mask)).any()) {
                for (int i = 0; i < n; ++i) {
                    pred_hall[i] |= bitu128(mask | bit(i));
                }
            }
        }

        // looping through all possible masks
        for (int mask = 0; mask < N; ++mask) {
            // "nxt" is the DP state that we obtain
            // after adding edges (U[i],v) for all "i" in "mask"
            // to the graph that has DP state "state"
            // One can see that this state is the union of all states that
            // will be obtained by adding each of the edge separately
            u128 nxt = state;
            for (int i = 0; i < n; ++i) {
                if (mask & bit(i)) {
                    nxt |= pred_hall[i];
                }
            }

            // we call "get_ind" that make all needed things with "nxt":
            // check whether it is the new DP state, add it to the "bfs" if yes
            // and return its index in "bfs" in both cases
            next[mask][k] = get_ind(nxt);
        }
        for (int i = n; i >= 0; --i) {
            if ((state & fixed_size[i]).any()) {
                match[k]=i;
                break;
            }
        }
    }
 //   printf("%d\n",len);
}

ll p[maxN][maxM]; // probability adjacent matrix
ll prev[maxS]; // previous row of DP values
ll cur[maxS]; // current row of DP values

ll expectedMaximumMatching(int n, int m) {
    // initialization of "prev"
    prev[0]=1;
    for (int k=1;k<len;k++) {
        prev[k] = 0;
    }

    int N = bit(n);
    // looping though all vertexes of V
    for (int j = 0; j < m; ++j) {
        // initialization of "cur"
        for (int k = 0; k < len; ++k) {
            cur[k] = 0;
        }

        // looping through all possible masks = ADJ(V[j])
        for (int mask = 0; mask < N; ++mask) {
            // "prob" is the probability that ADJ(V[j]) = mask
            ll prob = 1;
            for (int i = 0; i < n; ++i) {
                prob = (prob*(mask & bit(i) ? p[i][j] : mod+1 - p[i][j]))%mod;
            }

            // if we were previously in the state "bfs[k]"
            // then adding all edges (U[i],V[j]) for all "i" from "mask"
            // will bring us to the DP state with index "next[mask][k]"
            for (int k = 0; k < len; ++k)
                cur[next[mask][k]] = (cur[next[mask][k]]+prob * prev[k])%mod;
        }

        // copying of "prev" to "cur"
        for (int k = 0; k < len; ++k) {
            // We need this in order to avoid dealing with numbers
            // less than 1e-308. This can be several times slower
            // than with usual numbers. There was a discussion of this effect
            // at Codeforces after some TopCoder SRM.
            prev[k] = cur[k];
        }
    }

    // calcultating the answer
    ll ans = 0;
    for (int k = 0; k < len; ++k) {
//    	printf("%d %lld\n",k,prev[k]);
    	if (match[k]==n) ans=(ans+prev[k])%mod;
    }
    return ans;
}

int main() {
    int n, m;
    scanf("%d", &n); m=n;

    precalc(n);

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            scanf("%lld", &p[i][j]);
            p[i][j]=p[i][j]*powmod(100,mod-2)%mod;
        }
    }

    ll ans = expectedMaximumMatching(n, m);
    printf("%lld\n", ans);

    return 0;
}


#include "bits/stdc++.h"
#include<vector>
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
#include<set>
#include<iomanip>
#include<assert.h>
#include<unordered_map>
#include<unordered_set>
#include<string>
#include<stack>
#include<complex>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;
const ld eps=1e-9;

#define WHATS(var)cout<<__LINE__<<' '<<#var<<"="<<var<<endl;

template<class S, class T> ostream& operator <<(ostream &os, const pair<S, T> v){
	os << "( " << v.first << ", " << v.second << ")"; return os;
}
template<class T> ostream& operator <<(ostream &os, const vector<T> &v){
	for(int i = 0; i < v.size(); i++){if(i > 0){os << " ";} os << v[i];} return os;
}
template<class T> ostream& operator <<(ostream &os, const vector<vector<T>> &v){
	for(int i = 0; i < v.size(); i++){if(i > 0){os << endl;} os << v[i];} return os;
}
template<class T> ostream& operator <<(ostream &os, const vector<set<T>> &v){
	for(int i = 0; i < v.size(); i++){if(i > 0){os << endl;} os << v[i];} return os;
}
template<class T> ostream& operator <<(ostream &os, const set<T> &v){
	int i=0;
	for(auto it:v){
		if(i > 0){os << ' ';}
		os << it;
		i++;
	}
	return os;
}
using ll=long long ;

const int mod = 1000000007;
struct Mod {
public:
	int num;
	Mod() : Mod(0) { ; }
	Mod(long long int n) : num((n % mod + mod) % mod) {
		static_assert(mod<INT_MAX / 2, "mod is too big, please make num 'long long int' from 'int'");
	}
	Mod(int n) : Mod(static_cast<long long int>(n)) { ; }
	operator int() { return num; }
};

Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
Mod operator+(const long long int a, const Mod b) { return Mod(a) + b; }
Mod operator+(const Mod a, const long long int  b) { return b + a; }
Mod operator++(Mod &a) { return a + Mod(1); }
Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
Mod operator--(Mod &a) { return a - Mod(1); }
Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
Mod operator*(const long long int a, const Mod b) { return Mod(a)*b; }
Mod operator*(const Mod a, const long long int b) { return Mod(b)*a; }
Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
Mod operator*=(Mod& a, const long long int &b) { return a = a * b; }
Mod operator^(const Mod a, const int n) {
	if (n == 0) return Mod(1);
	Mod res = (a * a) ^ (n / 2);
	if (n % 2) res = res * a;
	return res;
}
Mod mod_pow(const Mod a, const int n) {
	if (n == 0) return Mod(1);
	Mod res = mod_pow((a * a), (n / 2));
	if (n % 2) res = res * a;
	return res;
}
Mod inv(const Mod a) { return a ^ (mod - 2); }
Mod operator/(const Mod a, const Mod b) {
	assert(b.num != 0);
	return a * inv(b);
}
Mod operator/(const long long int a, const Mod b) {
	return Mod(a) / b;
}
Mod operator/=(Mod &a, const Mod b) {
	return a = a / b;
}

#define MAX_MOD_N 1024000

Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
void init(const int amax = MAX_MOD_N) {
	fact[0] = Mod(1); factinv[0] = 1;
	for (int i = 0; i < amax - 1; ++i) {
		fact[i + 1] = fact[i] * Mod(i + 1);
		factinv[i + 1] = factinv[i] / Mod(i + 1);
	}
}
Mod comb(const int a, const int b) {
	return fact[a] * factinv[b] * factinv[a - b];
}
map<int,int>mp;
void init(vector<vector<Mod>>&pers){
	vector<int>v(3,0);
	for(int i=0;i<3;++i)v.push_back(1);
	int id=0;
	do{
		int tt=0;
		for(int k=0;k<6;++k){
			if(v[k])tt^=(1<<k);
		}
		mp[tt]=id;
		id++;
	}while(next_permutation(v.begin(),v.end()));

	int N;cin>>N;
	int s=3-(N+1)/2;
	for(int i=0;i<s;++i)pers[i][i]=Mod(1);
	for(int i=s;i<s+N;++i){
		for(int j=s;j<s+N;++j){
			int p;cin>>p;
			pers[i][j]=Mod(p)/Mod(100);
		}
	}
	for(int i=s+N;i<6;++i)pers[i][i]=Mod(1);
}
vector<Mod> solve(const vector<vector<Mod>>&pers,int al=0){
	vector<Mod>l_nums(1<<20);
	for(int xx=0;xx<(1<<18);++xx){
		vector<vector<int>>haves(3,vector<int>(6));
		Mod per=1;
		for(int i=0;i<3;++i){
			for(int j=0;j<6;++j){
				int k=i*6+j;
				if(xx&(1<<k)){
					haves[i][j]=true;
					per*=pers[al+i][j];
				}else{
					per*=(Mod(1)-pers[al+i][j]);
				}
			}
		}
		int flags=0;
		for(int i=0;i<6;++i){
			if(!haves[0][i])continue;
			for(int j=0;j<6;++j){
				if(!haves[1][j])continue;
				if(i==j)continue;
				for(int k=0;k<6;++k){
					if(!haves[2][k])continue;
					if(i==k)continue;
					if(j==k)continue;
					else{
						int anum=0;
						anum^=(1<<i);
						anum^=(1<<j);
						anum^=(1<<k);
						flags |=(1<<mp[anum]);
					}
				}
			}
		}
		l_nums[flags]+=per;
	}
	return l_nums;
}
int main() {
	ios::sync_with_stdio(false);

	vector<vector<Mod>>pers(6,vector<Mod>(6));

	init(pers);
	//cout<<3<<endl;

	auto u_nums=solve(pers,0);
	auto d_nums=solve(pers,3);
	for(int x=1;x<(1<<20);x<<=1){
		for(int i=0;i<(1<<20);++i){
			if((i&x)==0){
				d_nums[i^x]+=d_nums[i];
			}
		}
	}
	//cout<<3<<endl;
	Mod answer=0;
	for(int i=0;i<(1<<20);++i){
		if(u_nums[i].num){
			//WHATS(i)
			int need=0;
			{
				for(int x=0;x<20;++x){
					if(i&(1<<x)){
						need|=(1<<(19-x));
					}
				}
			}
			//WHATS(u_nums[i].num)
			int pp=((1<<20)-1)^i;
			//WHATS(pp)

			Mod nanswer=u_nums[i]*(Mod(1)-d_nums[((1<<20)-1)^need]);
			answer+=nanswer;
		}
	}
	cout<<answer.num<<endl;

	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1<<20)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxk][maxk];
int elo[maxk][maxk];
int maska[maxn];

LL dp[maxn][2];

int daj(bool f)
{
  vector<VI> ziom = {{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}};
  int mask = 0;
  for(auto s : ziom)
    for(int i = 1;i <= 6;i++)
      for(int j = i + 1;j <= 6;j++)
        for(int k = j + 1;k <= 6;k++)
        {
          if(elo[i][s[0] + f * 3] and elo[j][s[1] + f * 3] and elo[k][s[2] + f * 3])
          {
            mask |= maska[(f ? 126 : 0) ^ ((1<<i) + (1<<j) + (1<<k))];
          }
      }

  // for(int i = 0;i < SZ(kraw);i++)
  //   for(int j = i + 1;j < SZ(kraw);j++)
  //     if(kraw[i].fi != kraw[j].fi and kraw[i].se != kraw[j].se)
  //       for(int k = j + 1;k < SZ(kraw);k++)
  //         if(kraw[i].fi != kraw[k].fi and kraw[j].fi != kraw[k].fi and kraw[i].se != kraw[k].se and kraw[j].se != kraw[k].se)
  //           mask |= maska[(f ? 126 : 0) ^ ((1<<kraw[i].se) + (1<<kraw[j].se) + (1<<kraw[k].se))];
  return mask;
}

LL pot(LL a, LL w)
{
  if(!w) return 1;
  LL b = pot(a, w / 2);
  b = b * b % mod;
  if(w & 1)
    b = b * a % mod;
  return b;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  for(int i = 1;i <= n;i++)
    for(int j = 1;j <= n;j++)
      cin>>tab[i][j];
  int xd = 0;
  for(int i = 1;i <= 6;i++)
    for(int j = i + 1;j <= 6;j++)
      for(int k = j + 1;k <= 6;k++)
        maska[(1<<i) ^ (1<<j) ^ (1<<k)] = (1<<xd++);
  for(int i = n + 1;i <= 6;i++)
    tab[i][i] = 100;
  VPII kraw;
  n = 6;
  for(int i = 1;i <= n;i++)
    for(int j = 1;j <= n;j++)
      kraw.pb({i, j});
  LL odw = pot(100, mod - 2);
  for(int k = 0;k < 2;k++)
    for(int i = 0;i < (1<<18);i++)
    {
      // dbg(i, k);
      LL p = 1LL;
      for(int j = 0;j < 18;j++)
        if((1<<j) & i)
        {
          p = p * tab[kraw[j + k * 18].fi][kraw[j + k * 18].se] % mod * odw % mod;
          elo[kraw[j + k * 18].se][kraw[j + k * 18].fi] = 1;
        }
        else
        {
          p = p * (100 - tab[kraw[j + k * 18].fi][kraw[j + k * 18].se]) % mod * odw % mod;
          elo[kraw[j + k * 18].se][kraw[j + k * 18].fi] = 0;
        }
      int cur = daj(k);
      dp[cur][k] += p;
      dp[cur][k] %= mod;
    }
  LL res = 1;
  for(int i = 0;i < 20;i++)
    for(int j = 0;j < (1<<20);j++)
      if((1<<i) & j)
      {
        dp[j][0] += dp[j ^ (1<<i)][0];
        dp[j][0] %= mod;
      }
  for(int i = 0;i < (1<<20);i++)
    res = (res - dp[i][0] * dp[((1<<20) - 1) ^ i][1]) % mod;
  res += mod;
  res %= mod;
  cout<<res;
	return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx")
//#undef LOCAL
#include <bits/stdc++.h>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;

#ifdef LOCAL
struct PrettyOS {
    ostream& os;
    bool first;
    template <class T> auto operator<<(T&& x) {
        if (!first) os << ", ";
        first = false;
        os << x;
        return *this;
    }
};
template <class... T> void dbg0(T&&... t) {
    (PrettyOS{cerr, true} << ... << t);
}
#define dbg(...)                                            \
    do {                                                    \
        cerr << __LINE__ << " : " << #__VA_ARGS__ << " = "; \
        dbg0(__VA_ARGS__);                                  \
        cerr << endl;                                       \
    } while (false);
#else
#define dbg(...)
#endif

template <class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    return os << "P(" << p.first << ", " << p.second << ")";
}

template <class T> ostream& operator<<(ostream& os, const V<T>& v) {
    os << "[";
    for (auto d : v) os << d << ", ";
    return os << "]";
}

template <uint MD> struct ModInt {
    using M = ModInt;
    const static M G;
    uint v;
    ModInt(ll _v = 0) { set_v(_v % MD + MD); }
    M& set_v(uint _v) {
        v = (_v < MD) ? _v : _v - MD;
        return *this;
    }
    explicit operator bool() const { return v != 0; }
    M operator-() const { return M() - *this; }
    M operator+(const M& r) const { return M().set_v(v + r.v); }
    M operator-(const M& r) const { return M().set_v(v + MD - r.v); }
    M operator*(const M& r) const { return M().set_v(ull(v) * r.v % MD); }
    M operator/(const M& r) const { return *this * r.inv(); }
    M& operator+=(const M& r) { return *this = *this + r; }
    M& operator-=(const M& r) { return *this = *this - r; }
    M& operator*=(const M& r) { return *this = *this * r; }
    M& operator/=(const M& r) { return *this = *this / r; }
    bool operator==(const M& r) const { return v == r.v; }
    M pow(ll n) const {
        M x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    M inv() const { return pow(MD - 2); }
    friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; }
};
using Mint = ModInt<TEN(9) + 7>;
// template<> const Mint Mint::G = Mint(3);

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

    int n;
    cin >> n;

    VV<Mint> mat(n, V<Mint>(n));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int x;
            cin >> x;
            //x = 1;
            mat[i][j] = Mint(x) / Mint(100);
        }
    }

    using ST = pair<V<int>, Mint>;
    V<ST> sts;
    sts.push_back(ST({0}, Mint(1)));

    for (int ph = 0; ph < n; ph++) {
        V<ST> nsts;
        for (int f = 1; f < (1 << n); f++) {
            Mint freq = 1;
            for (int i = 0; i < n; i++) {
                if ((f >> i) & 1) {
                    freq *= mat[ph][i];
                } else {
                    freq *= Mint(1) - mat[ph][i];
                }
            }
            for (auto st: sts) {
                V<int> nst;
                for (auto d: st.first) {
                    for (int i = 0; i < n; i++) {
                        if ((d >> i) & 1) continue;
                        if (!((f >> i) & 1)) continue;
                        nst.push_back(d ^ (1 << i));
                    }
                }
                if (nst.empty()) continue;
                sort(nst.begin(), nst.end());
                nst.erase(unique(nst.begin(), nst.end()), nst.end());
                nsts.push_back({nst, st.second * freq});
            }
        }
        sort(nsts.begin(), nsts.end(), [&](const ST& l, const ST& r) {
            return l.first < r.first;
        });

        sts.clear();
        for (auto st: nsts) {
            if (sts.size() && sts.back().first == st.first) {
                sts.back().second += st.second;
            } else {
                sts.push_back(st);
            }
        }
        dbg(ph, nsts.size());
        //dbg(nst);
    }

    dbg(sts);

    Mint ans = (sts.empty() ? Mint(0) : sts[0].second);

    cout << ans << 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;
}
vi masks,masks2;
int prob[1 << 20],prob2[1 << 20];
int P[6][6];
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]);
    }

    int k,h = (n+1)/2;
    int h2 = n-h;
    int inv100 = inv(100);
    for (i = 0; i < (1 << n); i++) {
        int c = 0;
        for (j = 0; j < n; j++) {
            if (i & (1 << j)) c++;
        }
        if (c == h) masks.pb(i);
        if (c == h2) masks2.pb(i);
    }
    for (i = 0; i < (1 << (n*h)); i++) {
        LLI p = 1;
        for (j = 0; j < n*h; j++) {
            int x = j/n,y = j % n;
            if (i & (1 << j)) p *= ((LLI) P[x][y]*inv100) % MOD,p %= MOD;
            else p *= ((LLI) (100-P[x][y])*inv100) % MOD,p %= MOD;
        }
        int poss = 0;
        for (j = 0; j < masks.size(); j++) {
            vi v;
            for (k = 0; k < n; k++) {
                if (masks[j] & (1 << k)) v.pb(k);
            }
            do {
                for (k = 0; k < v.size(); k++) {
                    int a = k*n+v[k];
                    if (!(i & (1 << a))) break;
                }
                if (k == v.size()) {
                    poss |= (1 << j);
                    break;
                }
            } while (next_permutation(v.begin(),v.end()));
        }
        prob[poss] += p,prob[poss] %= MOD;
    }
    for (i = 0; i < (1 << (n*h2)); i++) {
        LLI p = 1;
        for (j = 0; j < n*h2; j++) {
            int x = j/n+h,y = j % n;
            if (i & (1 << j)) p *= ((LLI) P[x][y]*inv100) % MOD,p %= MOD;
            else p *= ((LLI) (100-P[x][y])*inv100) % MOD,p %= MOD;
        }
        int poss = 0;
        for (j = 0; j < masks.size(); j++) {
            vi v;
            for (k = 0; k < n; k++) {
                if (!(masks[j] & (1 << k))) v.pb(k);
            }
            do {
                for (k = 0; k < v.size(); k++) {
                    int a = k*n+v[k];
                    if (!(i & (1 << a))) break;
                }
                if (k == v.size()) {
                    poss |= (1 << j);
                    break;
                }
            } while (next_permutation(v.begin(),v.end()));
        }
        prob2[poss] += p,prob2[poss] %= MOD;
    }
    LLI ans = 0;
    for (i = 0; i < masks.size(); i++) {
        for (j = 0; j < (1 << masks.size()); j++) {
            if (j & (1 << i)) prob2[j] += prob2[j^(1 << i)],prob2[j] %= MOD;
        }
    }
    for (i = 0; i < (1 << masks.size()); i++) ans += (LLI) prob[i]*prob2[((1 << masks.size())-1)^i],ans %= MOD;
    printf("%I64d\n",(MOD+1-ans) % MOD);

    return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1<<20)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxk][maxk];
int elo[maxk][maxk];
int maska[maxn];

LL dp[maxn][2];

int daj(VPII kraw, bool f)
{
  for(int i = 0;i <= 6;i++)
    for(int j = 0;j <= 6;j++)
      elo[i][j] = 0;
  for(auto s : kraw)
    elo[s.se][s.fi] = 1;
  vector<VI> ziom = {{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}};
  int mask = 0;
  for(auto s : ziom)
    for(int i = 1;i <= 6;i++)
      for(int j = i + 1;j <= 6;j++)
        for(int k = j + 1;k <= 6;k++)
        {
          if(elo[i][s[0] + f * 3] and elo[j][s[1] + f * 3] and elo[k][s[2] + f * 3])
          {
            mask |= maska[(f ? 126 : 0) ^ ((1<<i) + (1<<j) + (1<<k))];
          }
      }

  // for(int i = 0;i < SZ(kraw);i++)
  //   for(int j = i + 1;j < SZ(kraw);j++)
  //     if(kraw[i].fi != kraw[j].fi and kraw[i].se != kraw[j].se)
  //       for(int k = j + 1;k < SZ(kraw);k++)
  //         if(kraw[i].fi != kraw[k].fi and kraw[j].fi != kraw[k].fi and kraw[i].se != kraw[k].se and kraw[j].se != kraw[k].se)
  //           mask |= maska[(f ? 126 : 0) ^ ((1<<kraw[i].se) + (1<<kraw[j].se) + (1<<kraw[k].se))];
  return mask;
}

LL pot(LL a, LL w)
{
  if(!w) return 1;
  LL b = pot(a, w / 2);
  b = b * b % mod;
  if(w & 1)
    b = b * a % mod;
  return b;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  for(int i = 1;i <= n;i++)
    for(int j = 1;j <= n;j++)
      cin>>tab[i][j];
  int xd = 0;
  for(int i = 1;i <= 6;i++)
    for(int j = i + 1;j <= 6;j++)
      for(int k = j + 1;k <= 6;k++)
        maska[(1<<i) ^ (1<<j) ^ (1<<k)] = (1<<xd++);
  for(int i = n + 1;i <= 6;i++)
    tab[i][i] = 100;
  VPII kraw;
  n = 6;
  for(int i = 1;i <= n;i++)
    for(int j = 1;j <= n;j++)
      kraw.pb({i, j});
  for(int k = 0;k < 2;k++)
    for(int i = 0;i < (1<<18);i++)
    {
      // dbg(i, k);
      LL p = 1LL;
      VPII xd;
      for(int j = 0;j < 18;j++)
        if((1<<j) & i)
        {
          p = p * tab[kraw[j + k * 18].fi][kraw[j + k * 18].se] % mod * pot(100, mod - 2) % mod;
          xd.pb(kraw[j + k * 18]);
        }
        else
        {
          p = p * (100 - tab[kraw[j + k * 18].fi][kraw[j + k * 18].se]) % mod * pot(100, mod - 2) % mod;
        }
      int cur = daj(xd, k);
      dp[cur][k] += p;
      dp[cur][k] %= mod;
    }
  LL res = 1;
  for(int i = 0;i < 20;i++)
    for(int j = 0;j < (1<<20);j++)
      if((1<<i) & j)
      {
        dp[j][0] += dp[j ^ (1<<i)][0];
        dp[j][0] %= mod;
      }
  for(int i = 0;i < (1<<20);i++)
    res = (res - dp[i][0] * dp[((1<<20) - 1) ^ i][1]) % mod;
  res += mod;
  res %= mod;
  cout<<res;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
const int N=(1<<20)+5;
int n,lim,ans,p1[N],p2[N];
int flag[10][10],a[10][10],h[10][10][10];
int fpow(int x,int y) {
	int res=1;
	while (y) {
		if (y&1) res=1ll*res*x%mod;
		x=1ll*x*x%mod,y>>=1;
	}
	return res;
}
int inv(int x) { return fpow(x,mod-2); }
bool check(int x,int y,int z) {
	int a[3]={x,y,z},d[3]={0,1,2};
	do {
		if (flag[a[d[0]]][1] && flag[a[d[1]]][2] && flag[a[d[2]]][3]) return 1;
	} while (next_permutation(d,d+3));
	return 0;
}

void dfs1(int P,int x,int y) {
	if (x==7 && y==1) {
		int sta=0;
		for (int i=1; i<=6; i++)
			for (int j=i+1; j<=6; j++)
				for (int k=j+1; k<=6; k++)
					if (check(i,j,k)) {
						int x=1;
			            while (x==i || x==j || x==k) x++;
			            int y=x+1;
			            while (y==i || y==j || y==k) y++;
			            int z=y+1;
			            while (z==i || z==j || z==k) z++;
			            sta|=h[x][y][z];
					}
		p1[sta]=(p1[sta]+P)%mod;
//		if (P!=0) printf("!!!!! %d %d\n",sta,p1[sta],P);
		return;
	}
	flag[x][y]=1;
	if (y==3) dfs1(1ll*P*a[x][y]%mod,x+1,1);
	else dfs1(1ll*P*a[x][y]%mod,x,y+1);
	flag[x][y]=0;
	if (y==3) dfs1(1ll*P*(mod+1-a[x][y])%mod,x+1,1);
	else dfs1(1ll*P*(mod+1-a[x][y])%mod,x,y+1);
}

void dfs2(int P,int x,int y) {
	if (x==7 && y==4) {
		int sta=0;
		for (int i=1; i<=6; i++)
			for (int j=i+1; j<=6; j++)
				for (int k=j+1; k<=6; k++)
					if (check(i,j,k)) sta|=h[i][j][k];
		p2[sta]=(p2[sta]+P)%mod;
//		if (P!=0) printf("!!!! %d %d %d\n",sta,p2[sta],P);
		ans=(ans+1ll*p1[lim^sta]*P%mod)%mod;
		return;
	}
	flag[x][y-3]=1;
	if (y==6) dfs2(1ll*P*a[x][y]%mod,x+1,4);
	else dfs2(1ll*P*a[x][y]%mod,x,y+1);
	flag[x][y-3]=0;
	if (y==6) dfs2(1ll*P*(mod+1-a[x][y])%mod,x+1,4);
	else dfs2(1ll*P*(mod+1-a[x][y])%mod,x,y+1);
}

int main() {
	scanf("%d",&n);
	for (int i=1; i<=n; i++)
		for (int j=1; j<=n; j++)
			scanf("%d",&a[i][j]),a[i][j]=1ll*a[i][j]*inv(100)%mod;
	for (int i=n+1; i<=6; i++) a[i][i]=1;
	int tot=0;
    for (int i=1; i<=6; i++)
			for (int j=i+1; j<=6; j++)
				for (int k=j+1; k<=6; k++)
					h[i][j][k]=1<<tot++;
	dfs1(1,1,1);
//	printf("!!!!!!\n");
	lim=(1<<20)-1;
	for (int i=0; i<=19; i++)
		 for (int j=0; j<=lim; j++)
		 	if (j>>i&1) p1[j]=(p1[j]+p1[j^1<<i])%mod;
//	printf("!!! %d\n",p1[lim]);
	dfs2(1,1,4);
	ans=(mod+1-ans)%mod;
	printf("%d\n",ans);
	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1<<20)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxk][maxk];
int elo[maxk][maxk];
int maska[maxn];

LL dp[maxn][2];

int daj(VPII kraw, bool f)
{
  for(int i = 0;i <= 6;i++)
    for(int j = 0;j <= 6;j++)
      elo[i][j] = 0;
  for(auto s : kraw)
    elo[s.se][s.fi] = 1;
  VI ziom;
  for(int i = 1 + f * 3;i < 4 + f * 3;i++)
    ziom.pb(i);
  int mask = 0;
  for(int i = 1;i <= 6;i++)
    for(int j = i + 1;j <= 6;j++)
      for(int k = j + 1;k <= 6;k++)
      {
        bool ok = 0;
        sort(all(ziom));
        do
        {
          if(elo[i][ziom[0]] and elo[j][ziom[1]] and elo[k][ziom[2]])
            ok = 1;
        } while(!ok and next_permutation(all(ziom)));
        if(ok)
        {
          mask |= maska[(f ? 126 : 0) ^ ((1<<i) + (1<<j) + (1<<k))];
        }
      }

  // for(int i = 0;i < SZ(kraw);i++)
  //   for(int j = i + 1;j < SZ(kraw);j++)
  //     if(kraw[i].fi != kraw[j].fi and kraw[i].se != kraw[j].se)
  //       for(int k = j + 1;k < SZ(kraw);k++)
  //         if(kraw[i].fi != kraw[k].fi and kraw[j].fi != kraw[k].fi and kraw[i].se != kraw[k].se and kraw[j].se != kraw[k].se)
  //           mask |= maska[(f ? 126 : 0) ^ ((1<<kraw[i].se) + (1<<kraw[j].se) + (1<<kraw[k].se))];
  return mask;
}

LL pot(LL a, LL w)
{
  if(!w) return 1;
  LL b = pot(a, w / 2);
  b = b * b % mod;
  if(w & 1)
    b = b * a % mod;
  return b;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  for(int i = 1;i <= n;i++)
    for(int j = 1;j <= n;j++)
      cin>>tab[i][j];
  int xd = 0;
  for(int i = 1;i <= 6;i++)
    for(int j = i + 1;j <= 6;j++)
      for(int k = j + 1;k <= 6;k++)
        maska[(1<<i) ^ (1<<j) ^ (1<<k)] = (1<<xd++);
  for(int i = n + 1;i <= 6;i++)
    tab[i][i] = 100;
  VPII kraw;
  n = 6;
  for(int i = 1;i <= n;i++)
    for(int j = 1;j <= n;j++)
      kraw.pb({i, j});
  for(int k = 0;k < 2;k++)
    for(int i = 0;i < (1<<18);i++)
    {
      LL p = 1LL;
      VPII xd;
      for(int j = 0;j < 18;j++)
        if((1<<j) & i)
        {
          p = p * tab[kraw[j + k * 18].fi][kraw[j + k * 18].se] % mod * pot(100, mod - 2) % mod;
          xd.pb(kraw[j + k * 18]);
        }
        else
        {
          p = p * (100 - tab[kraw[j + k * 18].fi][kraw[j + k * 18].se]) % mod * pot(100, mod - 2) % mod;
        }
      int cur = daj(xd, k);
      dp[cur][k] += p;
      dp[cur][k] %= mod;
    }
  LL res = 1;
  for(int i = 0;i < 20;i++)
    for(int j = 0;j < (1<<20);j++)
      if((1<<i) & j)
      {
        dp[j][0] += dp[j ^ (1<<i)][0];
        dp[j][0] %= mod;
      }
  for(int i = 0;i < (1<<20);i++)
    res = (res - dp[i][0] * dp[((1<<20) - 1) ^ i][1]) % mod;
  res += mod;
  res %= mod;
  cout<<res;
	return 0;
}


#include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

const int MOD = 1e9 + 7;

struct mod_int {
    int val;

    mod_int(long long v = 0) {
        if (v < 0)
            v = v % MOD + MOD;

        if (v >= MOD)
            v %= MOD;

        val = v;
    }

    static int mod_inv(int a, int m = MOD) {
        // https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Example
        int g = m, r = a, x = 0, y = 1;

        while (r != 0) {
            int q = g / r;
            g %= r; swap(g, r);
            x -= q * y; swap(x, y);
        }

        return x < 0 ? x + m : x;
    }

    explicit operator int() const {
        return val;
    }

    mod_int& operator+=(const mod_int &other) {
        val += other.val;
        if (val >= MOD) val -= MOD;
        return *this;
    }

    mod_int& operator-=(const mod_int &other) {
        val -= other.val;
        if (val < 0) val += MOD;
        return *this;
    }

    static unsigned fast_mod(uint64_t x, unsigned m = MOD) {
    #if !defined(_WIN32) || defined(_WIN64)
        return x % m;
    #endif
        // Optimized mod for Codeforces 32-bit machines.
        // x must be less than 2^32 * m for this to work, so that x / m fits in a 32-bit integer.
        unsigned x_high = x >> 32, x_low = (unsigned) x;
        unsigned quot, rem;
        asm("divl %4\n"
            : "=a" (quot), "=d" (rem)
            : "d" (x_high), "a" (x_low), "r" (m));
        return rem;
    }

    mod_int& operator*=(const mod_int &other) {
        val = fast_mod((uint64_t) val * other.val);
        return *this;
    }

    mod_int& operator/=(const mod_int &other) {
        return *this *= other.inv();
    }

    friend mod_int operator+(const mod_int &a, const mod_int &b) { return mod_int(a) += b; }
    friend mod_int operator-(const mod_int &a, const mod_int &b) { return mod_int(a) -= b; }
    friend mod_int operator*(const mod_int &a, const mod_int &b) { return mod_int(a) *= b; }
    friend mod_int operator/(const mod_int &a, const mod_int &b) { return mod_int(a) /= b; }

    mod_int& operator++() {
        val = val == MOD - 1 ? 0 : val + 1;
        return *this;
    }

    mod_int& operator--() {
        val = val == 0 ? MOD - 1 : val - 1;
        return *this;
    }

    mod_int operator++(int) { mod_int before = *this; ++*this; return before; }
    mod_int operator--(int) { mod_int before = *this; --*this; return before; }

    mod_int operator-() const {
        return val == 0 ? 0 : MOD - val;
    }

    bool operator==(const mod_int &other) const { return val == other.val; }
    bool operator!=(const mod_int &other) const { return val != other.val; }

    mod_int inv() const {
        return mod_inv(val);
    }

    mod_int pow(long long p) const {
        assert(p >= 0);
        mod_int a = *this, result = 1;

        while (p > 0) {
            if (p & 1)
                result *= a;

            a *= a;
            p >>= 1;
        }

        return result;
    }
};

const int N_MAX = 7;

int N;
mod_int probability[N_MAX][N_MAX];

int main() {
    cin >> N;

    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++) {
            int p;
            cin >> p;
            probability[i][j] = mod_int(p) / mod_int(100);
        }

    map<vector<bool>, mod_int> possible_masks;
    vector<bool> starting(1 << N, false);
    starting[0] = true;
    possible_masks[starting] = 1;
    vector<bool> new_possible;

    for (int left = 0; left < N; left++) {
        map<vector<bool>, mod_int> new_possible_masks;

        for (int current = 0; current < 1 << N; current++) {
            mod_int product = 1;

            for (int right = 0; right < N; right++)
                product *= (current >> right & 1) ? probability[left][right] : 1 - probability[left][right];

            for (auto &p : possible_masks) {
                const vector<bool> &possible = p.first;
                mod_int prob = p.second;
                new_possible.assign(1 << N, false);

                for (int mask = 0; mask < 1 << N; mask++)
                    if (possible[mask])
                        for (int i = 0; i < N; i++)
                            if ((current >> i & 1) != 0 && (mask >> i & 1) == 0)
                                new_possible[mask | 1 << i] = true;

                new_possible_masks[new_possible] += prob * product;
            }
        }

        possible_masks = new_possible_masks;
        cerr << possible_masks.size() << endl;
    }

    mod_int answer = 0;

    for (auto &p : possible_masks)
        if (p.first[(1 << N) - 1])
            answer += p.second;

    cout << (int) answer << '\n';
}


#include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

const int MOD = 1e9 + 7;

struct mod_int {
    int val;

    mod_int(long long v = 0) {
        if (v < 0)
            v = v % MOD + MOD;

        if (v >= MOD)
            v %= MOD;

        val = v;
    }

    static int mod_inv(int a, int m = MOD) {
        // https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Example
        int g = m, r = a, x = 0, y = 1;

        while (r != 0) {
            int q = g / r;
            g %= r; swap(g, r);
            x -= q * y; swap(x, y);
        }

        return x < 0 ? x + m : x;
    }

    explicit operator int() const {
        return val;
    }

    mod_int& operator+=(const mod_int &other) {
        val += other.val;
        if (val >= MOD) val -= MOD;
        return *this;
    }

    mod_int& operator-=(const mod_int &other) {
        val -= other.val;
        if (val < 0) val += MOD;
        return *this;
    }

    static unsigned fast_mod(uint64_t x, unsigned m = MOD) {
    #if !defined(_WIN32) || defined(_WIN64)
        return x % m;
    #endif
        // Optimized mod for Codeforces 32-bit machines.
        // x must be less than 2^32 * m for this to work, so that x / m fits in a 32-bit integer.
        unsigned x_high = x >> 32, x_low = (unsigned) x;
        unsigned quot, rem;
        asm("divl %4\n"
            : "=a" (quot), "=d" (rem)
            : "d" (x_high), "a" (x_low), "r" (m));
        return rem;
    }

    mod_int& operator*=(const mod_int &other) {
        val = fast_mod((uint64_t) val * other.val);
        return *this;
    }

    mod_int& operator/=(const mod_int &other) {
        return *this *= other.inv();
    }

    friend mod_int operator+(const mod_int &a, const mod_int &b) { return mod_int(a) += b; }
    friend mod_int operator-(const mod_int &a, const mod_int &b) { return mod_int(a) -= b; }
    friend mod_int operator*(const mod_int &a, const mod_int &b) { return mod_int(a) *= b; }
    friend mod_int operator/(const mod_int &a, const mod_int &b) { return mod_int(a) /= b; }

    mod_int& operator++() {
        val = val == MOD - 1 ? 0 : val + 1;
        return *this;
    }

    mod_int& operator--() {
        val = val == 0 ? MOD - 1 : val - 1;
        return *this;
    }

    mod_int operator++(int) { mod_int before = *this; ++*this; return before; }
    mod_int operator--(int) { mod_int before = *this; --*this; return before; }

    mod_int operator-() const {
        return val == 0 ? 0 : MOD - val;
    }

    bool operator==(const mod_int &other) const { return val == other.val; }
    bool operator!=(const mod_int &other) const { return val != other.val; }

    mod_int inv() const {
        return mod_inv(val);
    }

    mod_int pow(long long p) const {
        assert(p >= 0);
        mod_int a = *this, result = 1;

        while (p > 0) {
            if (p & 1)
                result *= a;

            a *= a;
            p >>= 1;
        }

        return result;
    }
};

const int N_MAX = 7;

int N;
mod_int probability[N_MAX][N_MAX];

int main() {
    cin >> N;

    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++) {
            int p;
            cin >> p;
            probability[i][j] = mod_int(p) / mod_int(100);
        }

    vector<vector<int>> masks_with_count(N_MAX + 1);
    vector<int> lookup(1 << N, -1);

    for (int mask = 0; mask < 1 << N; mask++) {
        int count = __builtin_popcount(mask);
        lookup[mask] = masks_with_count[count].size();
        masks_with_count[count].push_back(mask);
    }

    map<long long, mod_int> possible_masks;
    possible_masks[1 << lookup[0]] = 1;

    for (int left = 0; left < N; left++) {
        map<long long, mod_int> new_possible_masks;

        for (int current = 0; current < 1 << N; current++) {
            mod_int product = 1;

            for (int right = 0; right < N; right++)
                product *= (current >> right & 1) ? probability[left][right] : 1 - probability[left][right];

            for (auto &p : possible_masks) {
                long long possible = p.first;
                mod_int prob = p.second;

                long long new_possible = 0;

                for (int mask : masks_with_count[left])
                    if (possible >> lookup[mask] & 1)
                        for (int i = 0; i < N; i++)
                            if ((current >> i & 1) != 0 && (mask >> i & 1) == 0)
                                new_possible |= 1LL << lookup[mask | 1 << i];

                new_possible_masks[new_possible] += prob * product;
            }
        }

        possible_masks = new_possible_masks;
        cerr << possible_masks.size() << endl;
    }

    mod_int answer = 0;

    for (auto &p : possible_masks)
        if (p.first >> lookup[(1 << N) - 1] & 1)
            answer += p.second;

    cout << (int) answer << '\n';
}


#include <bits/stdc++.h>
using namespace std;
using LL = int64_t;
constexpr int MOD = 1E9 + 7;
int power(int a, int b) {
    int ans = 1;
    while (b > 0) {
        if (b & 1)
            ans = LL(ans) * a % MOD;
        a = LL(a) * a % MOD;
        b >>= 1;
    }
    return ans;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<vector<int>> p(n);
    for (auto &i : p) {
        i.resize(n);
        for (int &j : i) {
            cin >> j;
            j = LL(j) * power(100, MOD - 2) % MOD;
        }
    }
    vector<vector<int>> id(n + 1);
    vector<vector<int>> subsets(n + 1);
    for (int sz = 0; sz <= n; ++sz) {
        id[sz].resize(1 << n);
        for (int s = 0; s < (1 << n); ++s)
            if (__builtin_popcount(s) == sz) {
                id[sz][s] = subsets[sz].size();
                subsets[sz].push_back(s);
            }
    }
    vector<map<LL, int>> families(n + 1);
    families[0][1] = 1;
    for (int i = 1; i <= n; ++i) {
        for (int s = 0; s < (1 << n); ++s) {
            int pr = 1;
            for (int j = 0; j < n; ++j)
                if (s >> j & 1)
                    pr = LL(pr) * p[i - 1][j] % MOD;
                else
                    pr = LL(pr) * (1 + MOD - p[i - 1][j]) % MOD;
            for (auto [f, _p] : families[i - 1]) {
                LL mask = 0;
                for (int t : subsets[i])
                    for (int j = 0; j < n; ++j)
                        if ((t >> j & 1) && (s >> j & 1) && (f >> id[i - 1][t ^ 1 << j] & 1)) {
                            mask |= 1LL << id[i][t];
                            break;
                        }
                families[i][mask] = (families[i][mask] + LL(_p) * pr) % MOD;
            }
        }
    }
    cout << families[n][1] << "\n";
    return 0;
}


/*
Author: QAQ Automaton
Lang: C++
Prog: E.cpp
Mail: lk@qaq-am.com
Blog: https://www.qaq-am.com/
*/
#include<bits/stdc++.h>
#define int long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define DEBUG printf("Passing [%s] in LINE %d\n",__FUNCTION__,__LINE__)
#define Debug debug("Passing [%s] in LINE %d\n",__FUNCTION__,__LINE__)
#define all(x) x.begin(),x.end()
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const double eps=1e-8;
const double pi=acos(-1.0);
template<class T>int chkmin(T &a,T b){return a>b?a=b,1:0;}
template<class T>int chkmax(T &a,T b){return a<b?a=b,1:0;}
template<class T>T sqr(T a){return a*a;}
template<class T>T mmin(T a,T b){return a<b?a:b;}
template<class T>T mmax(T a,T b){return a>b?a:b;}
template<class T>T aabs(T a){return a<0?-a:a;}
template<class T>int dcmp(T a,T b){return a>b;}
template<int *a>int cmp_a(int x,int y){return a[x]<a[y];}
#define min mmin
#define max mmax
#define abs aabs
namespace io {
	const int SIZE = (1 << 21) + 1;
	char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr;
	// getchar
	#define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
	// print the remaining part
	inline void flush () {
		fwrite (obuf, 1, oS - obuf, stdout);
		oS = obuf;
	}
	// putchar
	inline void putc (char x) {
		*oS ++ = x;
		if (oS == oT) flush ();
	}
	// input a signed integer
	inline bool read (signed &x) {
		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;else if(c==EOF)return 0;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;
		return 1;
	}

	inline bool read (long long &x) {
		for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;else if(c==EOF)return 0;
		for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f;
		return 1;
	}
	inline bool read (char &x) {
		x=gc();
		return x!=EOF;
	}
	inline bool read(char *x){
		while((*x=gc())=='\n' || *x==' '||*x=='\r')if(*x==EOF)return 0;
		while(!(*x=='\n'||*x==' '||*x=='\r'||*x==EOF))*(++x)=gc();
		*x=0;
		return 1;
	}
	template<typename A,typename ...B>
	inline bool read(A &x,B &...y){
		return read(x)&&read(y...);
	}
	// print a signed integer
	inline bool write (signed x) {
		if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;
		while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
		while (qr) putc (qu[qr --]);
		return 0;
	}

	inline bool write (long long x) {
		if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x;
		while (x) qu[++ qr] = x % 10 + '0',  x /= 10;
		while (qr) putc (qu[qr --]);
		return 0;
	}
	inline bool write (char x) {
		putc(x);
		return 0;
	}
	inline bool write(const char *x){
		while(*x){putc(*x);++x;}
		return 0;
	}
	inline bool write(char *x){
		while(*x){putc(*x);++x;}
		return 0;
	}
	template<typename A,typename ...B>
	inline bool write(A x,B ...y){
		return write(x)||write(y...);
	}
	//no need to call flush at the end manually!
	struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io :: read;
using io :: putc;
using io :: write;
int inf;
struct _init_{
    _init_(){
        memset(&inf,0x3f,sizeof(inf));
    }
};
_init_ ___INIT__;
int a[11][11],n;
int f[11][131];
int is[131],i100;
const int p=1000000007;
int fpm(int a,int b){int c=1;for(;b;b>>=1,a=a*a%p)if(b&1)c=c*a%p;return c;}
struct lll{
	unsigned long long a,b;
	void set(int x){
		if(x<64)a|=1ULL<<x;
		else b|=1ULL<<(x-64);
	}
	void reset(){
		a=b=0;
	}
	lll &operator |=(lll ano){this->a|=ano.a;this->b|=ano.b;return *this;}
	bool operator ==(lll ano){return b==ano.b&&a==ano.a;}
	bool operator [](int ano){return !!(ano<64?a&(1ULL<<ano):b&(1ULL<<(ano-64)));}
};

bool operator <(const lll &a,const lll &b){return a.b<b.b||(a.b==b.b && a.a<b.a);}
bool operator >(const lll &a,const lll &b){return a.b>b.b||(a.b==b.b && a.a>b.a);}
map<lll,int> st[8];
lll mx;
int dfs(int x,lll w){
	if(x==n)return w==mx;
	if(st[x].count(w))return st[x][w];
	int ans=0;
	lll ng;

	lll s[n];
	for(int j=0;j<n;++j)s[j].reset();
	for(int i=0;i<1<<n;++i)if(w[i])for(int j=0;j<n;++j)if(!(i&(1<<j)))
		s[j].set(i|(1<<j));
	for(int i=0;i<1<<n;++i){
		ng=w;
		for(int j=0;j<n;++j)if(i&(1<<j))ng|=s[j];
		ans=(ans+f[x][i]*dfs(x+1,ng))%p;
	}
	return st[x][w]=ans;
}
lll stt;
signed main(){
#ifdef QAQAutoMaton
	freopen("E.in","r",stdin);
	freopen("E.out","w",stdout);
#endif
	read(n);
	for(int i=0;i<1<<n;++i)mx.set(i);
	stt.set(0);
	i100=fpm(100,p-2);
	for(int i=0;i<n;++i)for(int j=0;j<n;++j){
		read(a[i][j]);
		a[i][j]=a[i][j]*i100%p;
	}
	for(int i=0;i<n;++i)is[1<<i]=i;
	for(int i=0;i<n;++i){
		for(int j=0;j<1<<n;++j){
			f[i][j]=1;
			for(int k=0;k<n;++k)if(j&(1<<k))f[i][j]=f[i][j]*a[k][i]%p;
			else f[i][j]=f[i][j]*(p+1-a[k][i])%p;
		}
	}
	write(dfs(0,stt),'\n');
	return 0;
}


#include <algorithm>
#include <cassert>
#include <chrono>
#include <iostream>
#include <vector>
using namespace std;

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;

auto random_address = [] { char *p = new char; delete p; return (uint64_t) p; };

struct safe_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    uint64_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = splitmix64(chrono::steady_clock::now().time_since_epoch().count() * (random_address() | 1));
        return splitmix64(x ^ FIXED_RANDOM);
    }
};

const int MOD = 1e9 + 7;

struct mod_int {
    int val;

    mod_int(long long v = 0) {
        if (v < 0)
            v = v % MOD + MOD;

        if (v >= MOD)
            v %= MOD;

        val = v;
    }

    static int mod_inv(int a, int m = MOD) {
        // https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Example
        int g = m, r = a, x = 0, y = 1;

        while (r != 0) {
            int q = g / r;
            g %= r; swap(g, r);
            x -= q * y; swap(x, y);
        }

        return x < 0 ? x + m : x;
    }

    explicit operator int() const {
        return val;
    }

    mod_int& operator+=(const mod_int &other) {
        val += other.val;
        if (val >= MOD) val -= MOD;
        return *this;
    }

    mod_int& operator-=(const mod_int &other) {
        val -= other.val;
        if (val < 0) val += MOD;
        return *this;
    }

    static unsigned fast_mod(uint64_t x, unsigned m = MOD) {
#if !defined(_WIN32) || defined(_WIN64)
        return x % m;
#endif
        // Optimized mod for Codeforces 32-bit machines.
        // x must be less than 2^32 * m for this to work, so that x / m fits in a 32-bit integer.
        unsigned x_high = x >> 32, x_low = (unsigned) x;
        unsigned quot, rem;
        asm("divl %4\n"
            : "=a" (quot), "=d" (rem)
            : "d" (x_high), "a" (x_low), "r" (m));
        return rem;
    }

    mod_int& operator*=(const mod_int &other) {
        val = fast_mod((uint64_t) val * other.val);
        return *this;
    }

    mod_int& operator/=(const mod_int &other) {
        return *this *= other.inv();
    }

    friend mod_int operator+(const mod_int &a, const mod_int &b) { return mod_int(a) += b; }
    friend mod_int operator-(const mod_int &a, const mod_int &b) { return mod_int(a) -= b; }
    friend mod_int operator*(const mod_int &a, const mod_int &b) { return mod_int(a) *= b; }
    friend mod_int operator/(const mod_int &a, const mod_int &b) { return mod_int(a) /= b; }

    mod_int& operator++() {
        val = val == MOD - 1 ? 0 : val + 1;
        return *this;
    }

    mod_int& operator--() {
        val = val == 0 ? MOD - 1 : val - 1;
        return *this;
    }

    mod_int operator++(int) { mod_int before = *this; ++*this; return before; }
    mod_int operator--(int) { mod_int before = *this; --*this; return before; }

    mod_int operator-() const {
        return val == 0 ? 0 : MOD - val;
    }

    bool operator==(const mod_int &other) const { return val == other.val; }
    bool operator!=(const mod_int &other) const { return val != other.val; }

    mod_int inv() const {
        return mod_inv(val);
    }

    mod_int pow(long long p) const {
        assert(p >= 0);
        mod_int a = *this, result = 1;

        while (p > 0) {
            if (p & 1)
                result *= a;

            a *= a;
            p >>= 1;
        }

        return result;
    }
};

const int N_MAX = 10;

int N;
mod_int probability[N_MAX][N_MAX];

int main() {
    cin >> N;

    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++) {
            int p;
            cin >> p;
            probability[i][j] = mod_int(p) / mod_int(100);
        }

    vector<vector<int>> masks_with_count(N + 1);
    vector<int> lookup(1 << N, -1);

    for (int mask = 0; mask < 1 << N; mask++) {
        int count = __builtin_popcount(mask);
        lookup[mask] = masks_with_count[count].size();
        masks_with_count[count].push_back(mask);
    }

    gp_hash_table<long long, mod_int, safe_hash> possible_masks;
    possible_masks[1 << lookup[0]] = 1;

    for (int left = 0; left < N; left++) {
        gp_hash_table<long long, mod_int, safe_hash> new_possible_masks;
        vector<mod_int> products(1 << N, 1);

        for (int current = 0; current < 1 << N; current++)
            for (int right = 0; right < N; right++)
                products[current] *= (current >> right & 1) ? probability[left][right] : 1 - probability[left][right];

        vector<long long> new_bits(N, 0);
        vector<long long> new_possible(1 << N, 0);

        for (auto &p : possible_masks) {
            long long possible = p.first;
            mod_int prob = p.second;

            new_bits.assign(N, 0);

            for (int mask : masks_with_count[left])
                if (possible >> lookup[mask] & 1)
                    for (int i = 0; i < N; i++)
                        if ((mask >> i & 1) == 0)
                            new_bits[i] |= 1LL << lookup[mask | 1 << i];

            new_possible[0] = 0;

            for (int current = 1; current < 1 << N; current++) {
                new_possible[current] = new_possible[current & (current - 1)] | new_bits[__builtin_ctz(current)];
                new_possible_masks[new_possible[current]] += prob * products[current];
            }
        }

        possible_masks = new_possible_masks;
        cerr << possible_masks.size() << endl;
    }

    mod_int answer = 0;

    for (auto &p : possible_masks)
        if (p.first >> lookup[(1 << N) - 1] & 1)
            answer += p.second;

    cout << (int) answer << '\n';
}


#include <bits/stdc++.h>

#define f first
#define s second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<long long, long long> pll;
const int k = 1e9 + 7;
vector<ll> v[9];
ll n, b[1 << 9], p[9], a[9], i, j, m, X, M;
unordered_map<ll, ll> dp[8];
int main(){
	cin >> n;
	for(i = 0, j; i < (1 << n); i++){
		j = __builtin_popcount(i);
		b[i] = v[j].size();
		v[j].pb(i);
	}
	dp[0][1] = 1;
	for(i = 0; i < n; i++){
		for(j = 0; j < n; j++){
			cin >> p[j];
			p[j] = p[j] * 570000004 % k;
		}
		for(auto it : dp[i]){
			for(j = 0; j < n; j++)
				a[j] = 0;
			for(auto m : v[i])
				if((it.f >> b[m]) & 1)
					for(j = 0; j < n; j++)
						if(((m >> j) & 1) == 0)
							a[j] |= (1ll << b[m | (1 << j)]);
			for(m = 0; m < (1 << n); m++){
				X = 1, M = 0;
				for(j = 0; j < n; j++)
					if((m >> j) & 1)
						M |= a[j], X = X * p[j] % k;
					else
						X = X * (1 - p[j] + k) % k;
				dp[i + 1][M] = (dp[i + 1][M] + it.s * X) % k;
			}
		}
	}
	cout << dp[n][1];
	return 0;
}


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

using ll = long long;
ll modinv(ll a, ll m) {
	assert(m > 0);
	if (m == 1) return 0;
	a %= m;
	if (a < 0) a += m;
	assert(a != 0);
	if (a == 1) return 1;
	return m - modinv(m, a) * m / a;
}

template <int MOD_> struct modnum {
private:
	int v;
public:
	static const int MOD = MOD_;

	modnum() : v(0) {}
	modnum(ll v_) : v(int(v_ % MOD)) { if (v < 0) v += MOD; }
	explicit operator int () const { return v; }
	friend bool operator == (const modnum& a, const modnum& b) { return a.v == b.v; }
	friend bool operator != (const modnum& a, const modnum& b) { return a.v != b.v; }

	modnum operator ~ () const {
		modnum res;
		res.v = modinv(v, MOD);
		return res;
	}

	modnum& operator += (const modnum& o) {
		v += o.v;
		if (v >= MOD) v -= MOD;
		return *this;
	}
	modnum& operator -= (const modnum& o) {
		v -= o.v;
		if (v < 0) v += MOD;
		return *this;
	}
	modnum& operator *= (const modnum& o) {
		v = int(ll(v) * ll(o.v) % MOD);
		return *this;
	}
	modnum& operator /= (const modnum& o) {
		return *this *= (~o);
	}

	friend modnum operator + (const modnum& a, const modnum& b) { return modnum(a) += b; }
	friend modnum operator - (const modnum& a, const modnum& b) { return modnum(a) -= b; }
	friend modnum operator * (const modnum& a, const modnum& b) { return modnum(a) *= b; }
	friend modnum operator / (const modnum& a, const modnum& b) { return modnum(a) /= b; }
};

using num = modnum<int(1e9)+7>;

int main(){
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	const int n = 6;
	vector<vector<num> > p(n, vector<num>(n, 0));
	int _n;
	cin >> _n;
	for(int i = 0; i < n; i++) p[i][i] = 1;
	for(int i = 0; i < _n; i++){
		for(int j = 0; j < _n; j++){
			int a;
			cin >> a;
			p[i][j] = num(a) / num(100);
		}
	}
	const int f = 20;
	vector<vector<num> > sets(2, vector<num>(1 << f, 0));
	vector<vector<int> > masks(2);
	for(int i = 0; i < n; i++){
		for(int j = 0; j < i; j++){
			for(int k = 0; k < j; k++){
				masks[0].push_back((1 << i) ^ (1 << j) ^ (1 << k));
				masks[1].push_back(((1 << n) - 1) ^ masks[0].back());
			}
		}
	}
	assert(f == masks[0].size());
	for(int t = 0; t < 2; t++){
		for(int e = 0; e < (1 << (n/2 * n)); e++){
			num prob = 1;
			int edges[n/2];
			for(int i = 0; i < n/2; i++) edges[i] = 0;
			for(int i = 0; i < n/2 * n; i++){
				bool r = (e >> i) & 1;
				num pp = p[(i / n) * 2 + t][i % n];
				prob *= r ? pp : (1 - pp);
				edges[i/n] |= int(r) << (i % n);
			}
			int work_mask = 0;
			for(int a = 0; a < (int)masks[t].size(); a++){
				int mask = masks[t][a];
				int r[n/2];
				for(int i = 0; i < n/2; i++) r[i] = edges[i] & mask;
				if(r[0] && r[1] && r[2]){
					if(__builtin_popcount(r[0] | r[1] | r[2]) == 3){
						int x = __builtin_popcount(r[0] | r[1]);
						int y = __builtin_popcount(r[0] | r[2]);
						int z = __builtin_popcount(r[1] | r[2]);
						if(x >= 2 && y >= 2 && z >= 2){
							work_mask |= (1 << a);
						}
					}
				}
			}
			sets[t][work_mask] += prob;
		}
	}
	for(int i = 0; i < f; i++){
		for(int j = 0; j < (1 << f); j++){
			if((j >> i) & 1) continue;
			sets[0][j ^ (1 << i)] += sets[0][j];
		}
	}
	num ans = 0;
	for(int j = 0; j < (1 << f); j++){
		ans += sets[0][j] * sets[1][((1 << f) - 1) ^ j];
	}
	ans = 1 - ans;
	cout << (int)ans << '\n';
}


#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007;
inline int add(int a,int b)
{
	if((a+=b)>=mod)a-=mod;
	return a;
}
inline int mult(int a,int b)
{
	long long t=1ll*a*b;
	if(t>=mod)t%=mod;
	return t;
}
inline int dec(int a,int b)
{
	if((a-=b)<0)a+=mod;
	return a;
}
inline int power(int a,int b)
{
	int out=1;
	while(b)
	{
		if(b&1)out=mult(out,a);
		a=mult(a,a);
		b>>=1;
	}
	return out;
}
inline int lowbit(int x)
{
	return x&(-x);
}
int n,a[10][10],ch[70010][128],idcnt=0,q[10][128],dp[10][70010];
unordered_map<bitset<128>,int> id;
int dfs(bitset<128> s)
{
	if(id.find(s)!=id.end())return id[s];
	id[s]=++idcnt;
	for(int i=0;i<(1<<n);i++)
	{
		bitset<128> tmp=s;
		for(int j=0;j<(1<<n);j++)
		{
			if(!tmp[j])
			{
				int x=i&j;
				while(x)
				{
					int t=lowbit(x);
					if(s[j^t])
					{
						tmp[j]=1;
						break;
					}
					x-=t;
				}
			}
		}
		ch[id[s]][i]=dfs(tmp);
	}
	return id[s];
}
int main()
{
	scanf("%d",&n);
	dfs(1);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			scanf("%d",&a[i][j]);
			a[i][j]=mult(a[i][j],power(100,mod-2));
		}
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<(1<<n);j++)
		{
			q[i][j]=1;
			for(int k=0;k<n;k++)
			{
				if((j>>k)&1)q[i][j]=mult(q[i][j],a[i][k]);
				else q[i][j]=mult(q[i][j],dec(1,a[i][k]));
			}
		}
	}
	dp[0][1]=1;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=idcnt;j++)
		{
			for(int k=0;k<(1<<n);k++)
			{
				dp[i][ch[j][k]]=add(dp[i][ch[j][k]],mult(dp[i-1][j],q[i-1][k]));
			}
		}
	}
	bitset<128> bt;
	for(int i=0;i<(1<<n);i++)bt[i]=1;
	printf("%d\n",dp[n][id[bt]]);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int MAXN = 7;
const int MOD = 1e9 + 7;
const int E100 = 570000004;
typedef long long LL;
int n, g[MAXN][MAXN];
LL nxt[1<<MAXN][1<<MAXN];
int bitcnt[1<<MAXN];

vector<int> S[MAXN+1];
int id[1<<MAXN];
map<LL, int> dp[MAXN];
int solve(int i, LL msk) {
	if (msk == 0) return 0;
	if (i == n) return 1;
	if (dp[i].count(msk)) return dp[i][msk];
	LL ret = 0;
	for (int s = 0; s < (1<<n); ++s) {
		LL p = 1;
		for (int j = 0; j < n; ++j)
			if (s & (1 << j)) p = g[i][j] * p % MOD;
			else p = (1 - g[i][j]) * p % MOD;
		LL nmsk = 0;
		for (int j = 0; j < 35; ++j) if ((1LL << j) & msk) nmsk |= nxt[s][S[i][j]];
		ret = ret + p * solve(i+1, nmsk);
		ret %= MOD;
	}
	return dp[i][msk] = ret;
}

int main() {
	scanf("%d", &n);
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j) {
			scanf("%d", &g[i][j]);
			g[i][j] = g[i][j] * 1LL * E100 % MOD;
		}
	for (int i = 1; i < (1<<n); ++i)
		bitcnt[i] = bitcnt[i ^ (i & -i)] + 1;
	for (int i = 0; i < (1<<n); ++i) {
		id[i] = S[bitcnt[i]].size();
		S[bitcnt[i]].push_back(i);
	}
	for (int i = 1; i < (1<<n); ++i)
		for (int j = 0; j < (1<<n); ++j)
			for (int k = 0; k < n; ++k)
				if ((i & (1<<k)) && !(j & (1<<k)))
					nxt[i][j] |= 1LL << id[j|1<<k];
	int ans = solve(0, 1);
	ans = (ans % MOD + MOD) % MOD;
	cout << ans << endl;
}


#include<bits/stdc++.h>

typedef long long LL;

const int N=10;
const int M=25;
const int S=1048580;
const int MOD=1000000007;

int n,p[N][N],ma[N][N],bin[M],a[N],b[N],f[S],g[S],tot,id[70],pts[M][N],sta[M];
bool vis[N];

int ksm(int x,int y)
{
	int ans=1;
	while (y)
	{
		if (y&1) ans=(LL)ans*x%MOD;
		x=(LL)x*x%MOD;y>>=1;
	}
	return ans;
}

void init()
{
	bin[0]=1;
	for (int i=1;i<=20;i++) bin[i]=bin[i-1]*2;
	scanf("%d",&n);
	int inv=ksm(100,MOD-2);
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
			scanf("%d",&p[i][j]),p[i][j]=(LL)p[i][j]*inv%MOD;
	while (n<6) n++,p[n][n]=1;
}

bool get_match(int x)
{
	if (x>3) return 1;
	for (int i=1;i<=3;i++)
		if (!vis[i]&&ma[a[x]][b[i]])
		{
			vis[i]=1;
			bool flag=get_match(x+1);
			vis[i]=0;
			if (flag) return 1;
		}
	return 0;
}

void dfs2(int x,int y,int pro)
{
	if (x>3)
	{
		int s=0;
		for (int i=1;i<=tot;i++)
		{
			for (int j=1;j<=3;j++) b[j]=pts[i][j];
			if (get_match(1)) s+=bin[i-1];
		}
		(f[s]+=pro)%=MOD;
		return;
	}
	ma[a[x]][y]=0;
	if (y==n) dfs2(x+1,1,(LL)pro*(1-p[a[x]][y])%MOD);
	else dfs2(x,y+1,(LL)pro*(1-p[a[x]][y])%MOD);
	ma[a[x]][y]=1;
	if (y==n) dfs2(x+1,1,(LL)pro*p[a[x]][y]%MOD);
	else dfs2(x,y+1,(LL)pro*p[a[x]][y]%MOD);
}

void dfs1(int x,int y,int s)
{
	if (y==3)
	{
		id[s]=++tot;sta[tot]=s;
		for (int i=1;i<=3;i++) pts[tot][i]=a[i];
		return;
	}
	if (x>n) return;
	dfs1(x+1,y,s);
	a[y+1]=x;
	dfs1(x+1,y+1,s+bin[x-1]);
}

void pre()
{
	for (int i=0;i<tot;i++)
		for (int j=0;j<bin[tot];j++)
			if (j&bin[i]) (g[j]+=g[j^bin[i]])%=MOD;
}

int main()
{
	init();
	dfs1(1,0,0);
	a[1]=1;a[2]=2;a[3]=3;
	dfs2(1,1,1);
	for (int i=0;i<bin[tot];i++)
	{
		int t=0;
		for (int j=1;j<=tot;j++)
		{
			int rev=id[bin[n]-1-sta[j]];
			if (i&bin[j-1]) t+=bin[rev-1];
		}
		g[t]=f[i];f[i]=0;
	}
	a[1]=4;a[2]=5;a[3]=6;
	dfs2(1,1,1);
	pre();
	int ans=0;
	for (int i=0;i<bin[tot];i++)
		(ans+=(LL)f[i]*g[bin[tot]-1-i]%MOD)%=MOD;
	printf("%d\n",(1-ans+MOD)%MOD);
	return 0;
}


// 16

#ifndef LOCAL
#define NDEBUG 1
#endif
#include<bits/stdc++.h>
template<class F> struct Modular_ {
 using T=typename std::decay<decltype((F::get()))>::type;
 T val;
 explicit operator T() const { return val; }
 Modular_():val(){}
 template<class U> Modular_(U v):val(T(v%(F::get()))){ if(val<0)val+=(F::get()); }
 [[nodiscard]] bool operator ==(Modular_ b) const { return val == b.val; } [[nodiscard]] bool operator !=(Modular_ b) const { return val != b.val; } [[nodiscard]] bool operator <(Modular_ b) const { return val < b.val; } [[nodiscard]] bool operator >(Modular_ b) const { return val > b.val; } [[nodiscard]] bool operator <=(Modular_ b) const { return val <= b.val; } [[nodiscard]] bool operator >=(Modular_ b) const { return val >= b.val; }
 [[nodiscard]] friend Modular_ operator-(Modular_ x) { x.val=x.val?(F::get())-x.val:0; return x; }
 Modular_& operator+=(Modular_ m) { if ((val += m.val) >= (F::get())) val -= (F::get()); return *this; }
 Modular_& operator-=(Modular_ m) { if ((val -= m.val) < 0) val += (F::get()); return *this; }
 Modular_& operator*=(Modular_ m) {
  if(__builtin_constant_p(m.val)){
   switch(m.val){
    case 1: return *this;
    case 2: return *this+=*this;
    case 3: return *this+=*this+*this;
    case 0: return *this=0;
    case -1: return *this=-*this;
   }
  }else if(__builtin_constant_p(val)){
   return *this=m**this;
  }
  if(std::is_same<T, int>::value){
   val = int((int64_t)val*m.val%(F::get()));
  }else if(std::is_same<T, int64_t>::value){
   uint64_t result=
    (uint64_t)val*(uint64_t)m.val-
    uint64_t((long double)val*m.val/(F::get()))*(uint64_t)(F::get());
   result+=(F::get());
   if(result>=(F::get())){
    result-=(F::get());
    if(result>=(F::get())) result-=(F::get());
   }
   val=result;
  }else{
   assert(false);
  }
  return *this;
 }
 template<class U>
 [[nodiscard]] Modular_ pow(U p) const {
  Modular_ a=*this;
  Modular_ ans = 1; for (; p; p >>= 1, a *= a) if (p&1) ans *= a;
  return ans;
 }
 [[nodiscard]] Modular_ inv() const {
  T a=val,b=(F::get()), ax=1,bx=0;
  while(b){
   T q=a/b, t=a%b;
   a=b; b=t;
   t=ax-bx*q; ax=bx; bx=t;
  }
  assert(a==1);
  if(ax<0)ax+=(F::get());
  return ax;
 }
 Modular_& operator/=(Modular_ m) { return (*this) *= m.inv(); }
 [[nodiscard]] friend Modular_ operator +(Modular_ a, Modular_ b) { return a += b; } [[nodiscard]] friend Modular_ operator -(Modular_ a, Modular_ b) { return a -= b; } [[nodiscard]] friend Modular_ operator *(Modular_ a, Modular_ b) { return a *= b; } [[nodiscard]] friend Modular_ operator /(Modular_ a, Modular_ b) { return a /= b; }
};
template<class T, T x> struct TGetter{ static T get(){ return x; } };
template<int MOD> using Modular=Modular_<TGetter<int, MOD>>;
template<int const& MOD> using ModularP=Modular_<TGetter<int const&, MOD>>;
template<int64_t const& MOD> using ModularP64=Modular_<TGetter<int64_t const&, MOD>>;

using modular=Modular<1000000007>;

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int number; std::cin>>number;
	//std::vector<std::vector<modular>> probability(number, std::vector<modular>(number));
	std::vector<modular> probability(number*number);
	//for(auto& row: probability)
	for(auto& value: probability){
		int percentage; std::cin>>percentage;
		value=modular(1)/100*percentage;
	}

	std::vector<modular> total;

	int const middle=number/2;
	auto const maskValue=[&]{
		std::array<int, 1<<6> maskValue;
		assert(number<=6);
		int count=0;
		for(int matchMask=0; matchMask<(int)maskValue.size(); ++matchMask){
			maskValue[matchMask]=__builtin_popcount(matchMask)==middle ? count++: -1;
		}
		total.resize(1<<count);
		return maskValue;
	}();

	auto const process=[&](int left, int right, auto handle){
		auto const len=right-left;
		for(int edgeMask=0; edgeMask<(1<<(len*number)); ++edgeMask){
			modular totalProbability=1;

			// inefficient
			for(int tmp=edgeMask, i=left*number; i<right*number; ++i, tmp>>=1){
				totalProbability*=tmp&1 ?  probability[i]: 1-probability[i];
				if(totalProbability==0) goto continue_outer_2;
			}

			{ // compute matchSets and call handle
				// even more inefficient...?
				std::array<char, 3> data{};
				assert(len<=(int)data.size());
				int matchSets{};
				while(true){
					// process data
					int matchMask{};
					for(int index=0; index<len; ++index){
						if(not(edgeMask>>(index*number+data[index])&1)) goto continue_outer;
						if(matchMask&1<<data[index]) goto continue_outer;
						matchMask|=1<<data[index];
					}
					if(right==number) // second half, should invert
						matchMask^=(1<<number)-1;

					matchSets|=1<<maskValue[matchMask];

continue_outer:
					// increase data
					for(int i=len-1;;){
						if(i<0) goto break_outer;
						if(data[i]==number-1){data[i]=0; --i;}
						else{++data[i]; break;}
					}
				}
break_outer:;

				handle(matchSets, totalProbability);
			}

continue_outer_2:;
		}
	};
	assert(middle<number);
	process(0, middle,[&](int sets, modular probability){
		total[sets]+=probability;
	});
	for(int dim=1; dim<(int)total.size(); dim<<=1)
		for(int i=0; i<(int)total.size(); ++i)
			if(not(i&dim))
				total[i|dim]+=total[i];

	modular result{};
	process(middle, number,[&](int sets, modular probability){
		result+=probability*(total.back()-total[total.size()-1-sets]);
	});
	std::cout<<(int)result<<'\n';

}