#include <bits/stdc++.h>
#define vint vector <int>
#define pb push_back
#define clr(a) memset(a, 0, sizeof a)
#define fir first
#define sec second
#define mkp make_pair
#define hash_t unsigned long long
#define vhash vector <hash_t>
using namespace std;

const int MaxN = 1010, MaxM = 2010;
const hash_t base = 300007;
hash_t rand_val[MaxN];

class Graph {
public:
	int en[MaxN], next[MaxM], to[MaxM], tot;
	int lab[MaxN];
	void add_edge(int x, int y) {
		next[++tot] = en[x];
		en[x] = tot;
		to[tot] = y;
	}
	void clear() {
		clr(en);
		tot = 0;
		clr(lab);
	}
}	Gu, Gv;
typedef pair <hash_t, int> h_node;
struct Status {
	int ker;
	vector <h_node> u, v;
};
vector <Status> Su, Sv;
vector < pair <int, int> > ans;
vint stk;

int n, total;
bool vis[MaxN], done[MaxN];

void read_graph(Graph &G) {
	int m;
	scanf("%d", &m);
	map <int, int> hash;
	int total = 0;
	for (int i = 1; i <= m; ++i) {
		int u, v;
		scanf("%d%d", &u, &v);
		if (!hash.count(u)) hash[u] = ++total;
		if (!hash.count(v)) hash[v] = ++total;
		u = hash[u];
		v = hash[v];
		G.add_edge(u, v);
		G.add_edge(v, u);
	}
}

int size[MaxN], mx[MaxN];
int dfs_size(Graph &G, int now) {
	vis[now] = 1;
	size[now] = 1;
	mx[now] = 0;
	stk.pb(now);
	for (int i = G.en[now]; i; i = G.next[i])
		if (!vis[G.to[i]]) {
			int tmp = dfs_size(G, G.to[i]);
			size[now] += tmp;
			mx[now] = max(mx[now], tmp);
		}
	return size[now];
}

pair <int, int> get_gra(Graph &G, int root, int u) {
	clr(vis);
	vis[u] = 1;
	stk.clear();
	int sz = dfs_size(G, root);
	pair <int, int> ret(0, 0);
	int mn = sz;
	for (auto i : stk) {
		mx[i] = max(mx[i], sz - size[i]);
		mn = min(mn, mx[i]);
	}
	for (auto i : stk)
		if (mx[i] == mn) {
			if (ret.fir == 0) ret.fir = i;
			else ret.sec = i;
		}
	return ret;
}

hash_t vec_hash(vhash &s) {
	sort(s.begin(), s.end());
	hash_t ret = 0;
	for (uint i = 0; i < s.size(); ++i)
		ret = (ret * base + s[i]) ^ (s[i] * base + rand_val[i]);
	return ret;
}

hash_t dfs_hash(Graph &G, int now) {
	vis[now] = done[now] = 1;
	vhash v;
	for (int i = G.en[now]; i; i = G.next[i])
		if (!vis[G.to[i]]) v.pb(dfs_hash(G, G.to[i]));
	return vec_hash(v);
}

hash_t get_hash(Graph &G, int root, int u = 0) {
	pair <int, int> gra = get_gra(G, root, u);
	if (gra.sec == 0) {
		clr(vis);
		vis[u] = 1;
		return dfs_hash(G, gra.fir);
	} else {
		vhash v;
		clr(vis);
		vis[u] = 1;
		vis[gra.sec] = vis[gra.fir] = 1;
		v.pb(dfs_hash(G, gra.fir));
		v.pb(dfs_hash(G, gra.sec));
		return vec_hash(v);
	}
	return 0;
}

int relabel(Graph &G, int now, int flag = 0) {
	if (flag) stk.pb(now);
	vis[now] = 1;
	G.lab[now] = ++total;
	for (int i = G.en[now]; i; i = G.next[i])
		if (!vis[G.to[i]])
			ans.pb(mkp(G.lab[now], relabel(G, G.to[i], flag)));
	return G.lab[now];
}

h_node set_xor(vector <h_node> &u, vector <h_node> &v) {
	if (u.size() < v.size() || u.size() > v.size() + 1) return mkp(0, -1);
	multiset <hash_t> s;
	h_node ret(0, 0);
	for (auto i : v) s.insert(i.fir);
	for (auto i : u) {
		auto t = s.find(i.fir);
		if (t == s.end()) {
			if (ret.fir != 0) return mkp(0, -1);
			else ret = i;
		} else s.erase(t);
	}
	if (u.size() == v.size() && ret.fir != 0) return mkp(0, -1);
	return ret;
}

bool check(Status Su, Status Sv) {

	h_node com_u, com_v;
	com_u = set_xor(Su.u, Sv.v);
	com_v = set_xor(Sv.u, Su.v);
	if (com_u.sec == -1 || com_v.sec == -1 || com_u.fir != com_v.fir) return 0;

	total = 2;

	int u = Su.ker, v = Sv.ker;
	for (int i = Gu.en[u]; i; i = Gu.next[i])
		if (Gu.to[i] != com_u.sec) {
			clr(vis);
			vis[Su.ker] = 1;
			ans.pb(mkp(1, relabel(Gu, Gu.to[i])));
		}

	for (int i = Gv.en[v]; i; i = Gv.next[i])
		if (Gv.to[i] != com_v.sec) {
			clr(vis);
			vis[Sv.ker] = 1;
			ans.pb(mkp(2, relabel(Gv, Gv.to[i])));
		}

	if (com_u.fir == 0) ans.pb(mkp(1, 2));
	else {
		stk.clear();
		clr(vis);
		vis[Su.ker] = 1;
		ans.pb(mkp(1, relabel(Gu, com_u.sec, 1)));

		clr(vis);
		vis[Sv.ker] = 1;
		hash_t hv = dfs_hash(Gv, com_v.sec);

		for (auto i : stk) {
			clr(vis);
			vis[Su.ker] = 1;
			if (dfs_hash(Gu, i) == hv) {
				ans.pb(mkp(2, Gu.lab[i]));
				break;
			}
		}
	}
	return 1;
}

void work(Graph &G, vector <Status> &S) {
	for (int u = 1; u < n; ++u) {
		Status now;
		now.ker = u;

		clr(done);
		done[u] = 1;
		for (int i = G.en[u]; i; i = G.next[i])
			now.u.pb(mkp(get_hash(G, G.to[i], u), G.to[i]));
		for (int i = 1; i < n; ++i)
			if (!done[i]) now.v.pb(mkp(get_hash(G, i, u), i));
		S.pb(now);
	}
}

void solve() {
	ans.clear();
	Gu.clear();
	Gv.clear();
	Su.clear();
	Sv.clear();

	scanf("%d%*d", &n);
	read_graph(Gu);
	read_graph(Gv);
	for (int i = 0; i <= n; ++i) rand_val[i] = ((hash_t)rand() << 15) ^ rand();

	work(Gu, Su);
	work(Gv, Sv);
	for (auto i : Su)
		for (auto j : Sv)
			if (check(i, j)) {
				for (auto e : ans) printf("%d %d\n", e.fir, e.sec);
				return;
			}
	puts("NO");
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) solve();
	return 0;
}


const char Directory[300] = "/Users/carlosjosetoribio/NetBeansProjects/Runner/dist/Debug/GNU-MacOSX/runner";

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cstdio>

using namespace std;
typedef pair<int,int> PII;
typedef long long Long;
int seat[20], N;
int fixe[20];
Long memo[1<<18][17];
Long cnt(int mask = 0, int id = 0)
{
    if(id==N)return 1;
    if(memo[mask][id]!=-1)return memo[mask][id];
    for(int i = 0; i < N; ++i)
        if(fixe[i]==id)
            return memo[mask][id] = cnt(mask , id+1);
    Long ways = 0;
    for(int i = 0; i < N; ++i)
    {
        if(mask & seat[i])
        {
            if(fixe[i]==-1)continue;
            else if(fixe[i]<id)continue;
        }
        if(mask & (1<<i))continue;
        ways += cnt(mask | (1<<i) , id+1);
    }
    return memo[mask][id] = ways;
}

int main(int argc, char** argv) {
    if (strcmp(argv[0], Directory) == 0) {
        freopen("in.txt", "r", stdin);
    }

    int M;
    Long Y;
    cin>>N>>Y>>M;
    memset(seat,0,sizeof(seat));
    for(int i = 0; i < N; ++i)
    {
        int a,b;
        cin>>a>>b;
        a--;b--;
        seat[a] |= (1<<b);
    }
    Y -= 2000;
    memset(fixe,-1,sizeof(fixe));
    memset(memo,-1,sizeof(memo));
    int C = cnt();
    if(C < Y)
    {
        puts("The times have changed");
    }
    else
    {
        int mask = 0;
        for(int i = 0; i < N; ++i)
        {
            mask ^= (1<<i);
            for(int j = 0; j < N; ++j)
            {
                fixe[i] = j;
                memset(memo,-1,sizeof(memo));
                int t = cnt(mask);
                if(t >= Y)break;
                else Y-= t;
                fixe[i] = -1;
            }
        }
        for(int i = 0; i < N ; ++i)
            if(i<N-1)cout<<fixe[i]+1<<" ";
            else cout<<fixe[i]+1<<endl;
    }
    return 0;
}

/*
 * File:   E.cpp
 * Author: carlosjosetoribio
 *
 * Created on August 24, 2011, 4:03 AM
 */


#include<iostream>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<vector>

#define PB push_back
#define WAIT cout<<flush, system("PAUSE")
using namespace std;
typedef long double ld;
#define MAX  22
#define MAXM (1<<18)

ll N, P, M, a, b;
ll A[MAX];
bool E[MAX][MAX];
ll lo[MAX], all, prev, last;
ll dp[MAXM];

bool used[MAX], brn[MAXM];
ll pos[MAX];
void calc(){
   memset(dp, 0, sizeof(dp));

   dp[0]=1;
   for(ll m=1; m<all; m++){
      ll sz = __builtin_popcount(m);

      if (!brn[sz-1]){
         for(ll I=0; I<N; I++) if (m&(1<<I)){
            if ((m & lo[I]) == 0)
               dp[m] += dp[m-(1<<I)];
         }
      }else{
         if ((m&(1<<pos[sz-1])) == 0)
            continue;

         ll I = pos[sz-1];
         if ((m & lo[I]) == 0)
            dp[m] += dp[m-(1<<I)];
      }
   }
}

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

   cin >> N >> P >> M;
   P -= 2000;
   while(M--){
      cin >> a >> b;
      E[a-1][b-1] = true;
   }
   for(ll p=0; p<N; p++)
      for(ll I=0; I<N; I++)
         for(ll K=0; K<N; K++)
            E[I][K] |= E[I][p]&&E[p][K];

   for(ll I=0; I<N; I++){
      for(ll K=0; K<N; K++) if (E[I][K]){
         if (I==K){
            cout << "The times have changed" << endl;
            return 0;
         }
         lo[I] |= (1<<K);
      }
   }

   all = (1<<(N));
   calc();

   if (dp[all-1] < P){
      cout << "The times have changed" << endl;
      return 0;
   }

   for(ll I=0; I<N; I++){
      prev = last = 0;

      for(ll c=0; c<N; c++) if (!used[c]){
         A[I] = c;
         pos[c] = I;
         brn[c] = true;

         calc();

         if (dp[all-1] >= P){
            A[I] = c;
            used[c] = true;
            break;
         }

         brn[c] = false;
         P -= dp[all-1];
      }
   }

   for(ll I=0; I<N; I++) cout<<A[I]+1<<" ";
   cout<<endl;
   //WAIT;
}


#include <iostream>
#include <string.h>

using namespace std;

long long year, dp[70000];
int n, m, need[17], ans[17], bits_cnt[70000];
bool used[17];

long long calc(int state) {
    if (state == (1 << n)-1) {
        dp[state] = 1;
        return 1;
    }
    if (dp[state] > -1) {
        return dp[state];
    }

    if (bits_cnt[state] == -1) {
        int usd = 0;
        for (int i = 0; i < n; ++i) {
            if (state & (1 << i)) {
                ++usd;
            }
        }
        bits_cnt[state] = usd;
    }

    long long sum = 0;
    for (int i = 0; i < n; ++i) {
        if (!(state & (1 << i))) {
            if ((state & need[i]) != need[i]) {
                continue;
            }
            if (ans[i] == 0 || ans[i] == bits_cnt[state]+1) {
                sum += calc(state | (1 << i));
            }
        }
    }
    dp[state] = sum;

    return sum;
}

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

    memset(bits_cnt, -1, bits_cntof(bits_cnt));
    memset(dp, -1, bits_cntof(dp));

    cin >> n >> year >> m;
    year -= 2000;
    for (int i = 0; i < m; ++i) {
        int x, y;
        cin >> x >> y;
        --x;
        --y;
        need[y] = need[y] | (1 << x);
    }

    if (calc(0) < year) {
        cout << "The times have changed";
    } else {
        for (int j = 0; j < n; ++j) {
            for (int i = 1; i < n+1; ++i) {
                if (!used[i]) {
                    ans[j] = i;
                    memset(dp, -1, bits_cntof(dp));
                    auto k = calc(0);
                    if (k < year) {
                        year -= k;
                    } else {
                        used[i] = true;
                        break;
                    }
                 }
            }
        }

        for (int i = 0; i < n; ++i) {
            cout << ans[i] << ' ';
        }
    }

    return 0;
}


#include <iostream>
#include <string.h>

using namespace std;

long long year, dp[70000];
int n, m, need[17], ans[17], size[70000];
bool used[17];

long long calc(int state) {
    if (state == (1 << n)-1) {
        dp[state] = 1;
        return 1;
    }
    if (dp[state] > -1) {
        return dp[state];
    }

    if (size[state] == -1) {
        int usd = 0;
        for (int i = 0; i < n; ++i) {
            if (state & (1 << i)) {
                ++usd;
            }
        }
        size[state] = usd;
    }

    long long sum = 0;
    for (int i = 0; i < n; ++i) {
        if (!(state & (1 << i))) {
            if ((state & need[i]) != need[i]) {
                continue;
            }
            if (ans[i] == 0 || ans[i] == size[state]+1) {
                sum += calc(state | (1 << i));
            }
        }
    }
    dp[state] = sum;

    return sum;
}

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

    memset(size, -1, sizeof(size));
    memset(dp, -1, sizeof(dp));

    cin >> n >> year >> m;
    year -= 2000;
    for (int i = 0; i < m; ++i) {
        int x, y;
        cin >> x >> y;
        --x;
        --y;
        need[y] = need[y] | (1 << x);
    }

    if (calc(0) < year) {
        cout << "The times have changed";
    } else {
        for (int j = 0; j < n; ++j) {
            for (int i = 1; i < n+1; ++i) {
                if (!used[i]) {
                    ans[j] = i;
                    memset(dp, -1, sizeof(dp));
                    auto k = calc(0);
                    if (k < year) {
                        year -= k;
                    } else {
                        used[i] = true;
                        break;
                    }
                 }
            }
        }

        for (int i = 0; i < n; ++i) {
            cout << ans[i] << ' ';
        }
    }

    return 0;
}


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

#define clz(n) __builtin_clz(n)
typedef double ld;
const int N=1<<17;
struct C{
	ld x,y;
	inline C operator - (const C&a)const{return (C){x-a.x,y-a.y};}
	inline C operator + (const C&a)const{return (C){x+a.x,y+a.y};}
	inline void operator += (const C&a){x+=a.x;y+=a.y;}
	inline C operator * (const ld&a)const{return (C){x*a,y*a};}
	inline C operator / (const ld&a)const{return (C){x/a,y/a};}
	inline C operator * (const C&a)const{return (C){x*a.x-y*a.y,x*a.y+y*a.x};}
	inline C conj()const{return (C){x,-y};}
}s1[N],omg_[N],s2[N],s3[N];
int n_,lgn_;
int rev_[N];
void FFT_init(int n){
	lgn_=31-clz(n);n_=1<<lgn_;
	rev_[0]=0;omg_[0]=(C){1,0};
	for(int i=1;i<n_;i<<=1)omg_[i]=(C){cos(2.*i*M_PI/n_),sin(2.*i*M_PI/n_)};
	for(int i=1;i<n_;i++){
		omg_[i]=omg_[i^(i&-i)]*omg_[i&-i];
		rev_[i]=rev_[i/2]>>1|(i&1)<<(lgn_-1);
	}
}
C ww[N];
void FFT(C*a){
	for(int i=0;i<n_;i++)if(rev_[i]<i)swap(a[i],a[rev_[i]]);
	register int t;
	for(int i=0;i<lgn_;i++){
		t=1<<i;
		for(register int j=0;j<t;++j)ww[j]=omg_[j<<(lgn_-i-1)];
		for(register int j=0;j<n_;j+=t<<1){
			register C* at=a+j,*bt=a+j+t;
			for(register int k=0;k<t;++k){
				C s=bt[k]*ww[k];
				bt[k]=at[k]-s;
				at[k]+=s;
			}
		}
	}
}
int n,m,mod;
typedef long long ll;
inline void reduce(int&x){x+=x>>31&mod;}
void mul(int*a,int*b,int*c){
	memset(s1,0,sizeof s1);memset(s2,0,sizeof s2);
	for(int i=0;i<=n;i++)
		if(i&1)s1[i/2].y=a[i];
		else s1[i/2].x=a[i];
	for(int i=0;i<=n;i++)
		if(i&1)s2[i/2].y=b[i];
		else s2[i/2].x=b[i];
	FFT(s1);FFT(s2);
	for(int i=0;i<n_;i++){
		int j=(n_-1)&(n_-i);
		s3[i]=(s1[i]*s2[i]*(C){4,0}-(s1[i]-s1[j].conj())*(s2[i]-s2[j].conj())*(((i&n_>>1)?(C){1,0}-ww[i^n_>>1]:ww[i]+(C){1,0})))*(C){0.25,0};
	}
	FFT(s3);reverse(s3+1,s3+n_);
	for(int i=0;i<=n;i++)c[i]=(ll)(i&1?s3[i>>1].y/n_+0.5:s3[i>>1].x/n_+0.5)%mod;
}
int f[2][N],g[2][N],tmp[N];
int ans;
void solve(int L){
	if(!L)return;
	solve(L/2);memset(g,0,sizeof g);
	for(int i=1;i<=n;++i)tmp[i]=(f[0][i]+f[1][i])%mod;
	for(int op=0;op<=1;++op){
		mul(f[op^(L>>1&1)],tmp,g[op]);
		for(int i=1;i<=n;++i)
			reduce(g[op][i]+=f[op][i]-mod),
			reduce(g[op][i]+=f[op^(L>>1&1)][i]-mod);
	}
	if(L&1){
		for(int i=n;i>=2;--i)
			reduce(g[1][i]+=(g[0][i-1]+g[1][i-1])%mod-mod);
		reduce(g[1][1]+=1-mod);
	}
	memcpy(f,g,sizeof f);
	for(int i=1;i<=n;i+=2)reduce(ans+=f[1][i]-mod);
}

int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n>>m>>mod;FFT_init(2*n+2);
	solve(m/2);
	cout<<ans<<'\n';
	return 0;
}


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

const int p1 = 998244353, p2 = 469762049, Maxn = 1 << 17 | 5;
int maxn, maxa, mod, rev[Maxn];
long long tot;
void get_rev(int len)
{
	for (int i = 0; i < len; i++)
		rev[i] = (rev[i >> 1] >> 1) | ((i & 1) * (len >> 1));
}
long long fast_pow(long long x, long long y, long long p)
{
	long long ans = 1, now = x;
	while (y)
	{
		if (y & 1) ans = ans * now % p;
		now = now * now % p;
		y >>= 1;
	}
	return ans;
}
void NTT(long long now[], int len, int p, bool type = false)
{
	long long inv3 = fast_pow(3, p - 2, p);
	for (int i = 0; i < len; i++)
		if (i < rev[i]) swap(now[i], now[rev[i]]);
	for (int i = 1; i < len; i <<= 1)
	{
		long long w = fast_pow(type ? inv3 : 3, (p - 1) / (i << 1), p);
		for (int j = 0; j < len; j += (i << 1))
		{
			long long l = 1;
			for (int k = j; k < i + j; k++, l = l * w % p)
			{
				long long x = now[i + k] * l % p, y = now[k];
				now[k] = (x + y) % p;
				now[i + k] = (y - x + p) % p;
			}
		}
	}
	if (type)
	{
		long long inv = fast_pow(len, p - 2, p);
		for (int i = 0; i < len; i++)
			now[i] = now[i] * inv % p;
	}
}
void multi(long long x[], long long y[], long long result[], int len, int p)
{
	NTT(x, len, p), NTT(y, len, p);
	for (int i = 0; i < len; i++)
		result[i] = x[i] * y[i] % p;
	NTT(result, len, p, true);
}
void multi(long long x[], long long y[], long long result[], int len)
{
	get_rev(len);
	static long long tmp1[Maxn], tmp2[Maxn], tmpx[Maxn], tmpy[Maxn];
	for (int i = 0; i < len; i++)
		tmpx[i] = x[i], tmpy[i] = y[i];
	multi(tmpx, tmpy, tmp1, len, p1);
	for (int i = 0; i < len; i++)
		tmpx[i] = x[i], tmpy[i] = y[i];
	multi(tmpx, tmpy, tmp2, len, p2);
	__int128 l = (__int128) p1 * p2;
	for (int i = 0; i < len; i++)
		result[i] = (tmp1[i] * (__int128) p2 * fast_pow(p2, p1 - 2, p1) + tmp2[i] * (__int128) p1 * fast_pow(p1, p2 - 2, p2)) % l % mod;
}
void poly_pow(int y, int len)
{
	int now = 0;
	static long long ans[2][Maxn];
	memset(ans[0], 0, sizeof(long long[len << 1]));
	memset(ans[1], 0, sizeof(long long[len << 1]));
	static long long tmp[Maxn], result[2][Maxn];
	for (int j = 20; j >= 0; j--)
	{
		memset(tmp, 0, sizeof(long long[len << 1]));
		for (int i = 0; i < len; i++)
			tmp[i] = (ans[0][i] + ans[1][i]) % mod;
		tmp[0]++;
		for (int p = 0; p <= 1; p++)
			multi(tmp, ans[(now & 1) ^ p], result[p], len << 1);
		for (int p = 0; p <= 1; p++)
			for (int i = 0; i < len; i++)
				(ans[p][i] += result[p][i]) %= mod;
		now <<= 1;
		if (y & (1 << j))
		{
			for (int i = len - 1; i; i--)
				(ans[1][i] += ans[0][i - 1] + ans[1][i - 1]) %= mod;
			ans[1][1]++;
			now++;
		}
		if (now != y)
			for (int i = 1; i <= maxn; i += 2)
				(tot += ans[1][i]) %= mod;
	}
}
int lower(int x)
{
	int tmp = 1;
	for (; tmp < x; tmp <<= 1);
	return tmp;
}
int main()
{
	scanf("%d%d%d", &maxn, &maxa, &mod);
	poly_pow(maxa, lower(maxn + 1));
	printf("%lld", tot);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long

template <typename T>
struct modequa{
private:
	T remain, moder;

	// ÕâÑù¿ÉÒÔ±£Ö¤ |x| <= |b|, |y| <= |a|
	T extendedeuclid(T a, T b, T &x, T &y){
		T p;
		if (b){
			T ret = extendedeuclid(b, a % b, x, y);
			p = y, y = x - a / b * y, x = p;
			return ret;
		}
		x = 1, y = 0;
		return a;
	}

	ll getone(int n){return 1;}
	__int128 getone(ll n){return 1;}

public:
	modequa <T>(){}
	modequa <T>(T remain, T moder) : remain(remain), moder(moder){}
	T getremain(){return remain;}
	T getmoder(){return moder;}

	void setcandidates(T remain, T moder){
		this -> remain = remain;
		this -> moder = moder;
	}

	modequa <T> crt(const modequa <T> &p){
		T x, y;
		auto one = getone(remain);
		if (!moder || !p.moder) return {0, 0};
		T gcd = extendedeuclid(moder, p.moder, x, y);
		if ((p.remain - remain) % gcd) return {0, 0};
		T lcm = moder / gcd * p.moder;
		T ans = (p.remain - remain) / gcd;
		ans = one * ans * x % lcm * moder % lcm;
		ans += remain;
		ans += ans < 0 ? lcm : ans >= lcm ? -lcm : 0;
		return {ans, lcm};
	}
};

// Èç¹ûÄ£Êý²»ÊÇÖÊÊý£¬ÄÇÃ´»ù±¾¾ÍÖ»ÄÜ×ö¼Ó¼õ³ËºÍÇóµ¼ÁËorz
struct Poly{
private:
	const static int MAX = 17;

	static int numinv[1 << MAX];
	int a[1 << MAX];
	int length;
	int moder, root, invroot;
	// ³£ÓÃµÄÁ½×éÄ£ÊýÎª ((119 << 23) + 1, 3, 332748118) ºÍ ((479 << 21) + 1, 3, 334845270)

	int powermod(int a, int exp, int moder){
		int ret = 1;
		for ( ; exp; exp >>= 1){
			if (exp & 1){
				ret = 1ll * a * ret % moder;
			}
			a = 1ll * a * a % moder;
		}
		return ret;
	}

	void initinv(){
		numinv[1] = 1;
		for (int i = 2; i < 1 << MAX; ++ i){
			numinv[i] = (moder - 1ll * (moder / i) * numinv[moder % i] % moder) % moder;
		}
	}

	void NTT(int *a, int length, int type, int moder, int root){
		int len = -1;
		for (int x = length; x; ++ len, x >>= 1);
		for(int i = 1, j = 0; i < length - 1; ++ i){
			for(int s = length; j ^= s >>= 1, ~j & s; );
			if(i < j){
				std::swap(a[i], a[j]);
			}
		}
		for (int i = 1; i <= len; ++ i){
			int unit = powermod(root, moder - 1 >> i, moder);
			for (int j = 0; j < length; j += 1 << i){
				int w = 1;
				for (int k = j, szk = 1 << i - 1; k < j + szk; ++ k){
					int s = a[k], t = 1ll * w * a[k + szk] % moder;
					a[k] = s + t >= moder ? s + t - moder : s + t;
					a[k + szk] = s - t < 0 ? s - t + moder : s - t;
					w = 1ll * w * unit % moder;
				}
			}
		}
		if (type == 1) return;
		int inv = powermod(length, moder - 2, moder);
		for (int i = 0; i < length; ++ i){
			a[i] = 1ll * a[i] * inv % moder;
		}
	}

public:
	Poly() : length(-1){
		memset(a, 0, sizeof(a));
	}

	// Èç¹ûÄ£Êý·ÇNTTÖÊÊý root ºÍ invroot Ëæ±ãÉè¾ÍºÃÀ±~
	Poly(int moder, int root, int invroot):moder(moder), root(root), invroot(invroot), length(-1){
		memset(a, 0, sizeof(a));
	}

	void clear(){
		memset(a, 0, sizeof(int) * (length + 1));
		length = -1;
		moder = root = invroot = 0;
	}

	void setmoder(int moder, int root, int invroot){
		clear();
		this -> moder = moder, this -> root = root, this -> invroot = invroot;
	}

	void setlength(int length){
		if (length >= this -> length){
			this -> length = length;
			return;
		}
		memset(a + length + 1, 0, sizeof(int) * (this -> length - length));
		this -> length = length;
	}

	void setvalue(int sit, int value){
		a[sit] = (value % moder + moder) % moder;
		length = std::max(sit, length);
		for ( ; ~length && !a[length]; -- length)
			;
	}

	int getvalue(int sit){return a[sit];}
	int getlength(){return length;}
	int getmoder(){return moder;}

	// Ïàµ±ÓÚ³ËÒÔ x ^ dis
	void leftshift(int dis){
		for (int i = length + dis; i >= dis; -- i){
			a[i] = a[i - dis];
		}
		memset(a, 0, sizeof(int) * dis);
		length += dis;
	}

	// Ïàµ±ÓÚ³ýÒÔ x ^ dis
	void rightshift(int dis){
		if (dis > length) return setmoder(moder, root, invroot);
		for (int i = 0; i <= length - dis; ++ i){
			a[i] = a[i + dis];
		}
		memset(a + length - dis + 1, 0, sizeof(int) * dis);
		length = length - dis >= 0 ? length - dis : -1;
	}

	int value(int x){
		int now = 1, ret = 0;
		for (int i = 0; i <= length; ++ i){
			ret = (ret + 1ll * a[i] * now) % moder;
			now = 1ll * now * x % moder;
		}
		return ret;
	}

	void assign(Poly &q){
		memset(a, 0, sizeof(int) * (length + 1));
		memcpy(a, q.a, sizeof(int) * (q.length + 1));
		length = q.length, moder = q.moder, root = q.root, invroot = q.invroot;
	}

	void neg(){
		for (int i = 0; i <= length; ++ i){
			a[i] = a[i] ? moder - a[i] : 0;
		}
	}

	void add(Poly &q){
		if (moder != q.moder) assert(("Invalid polynomial addition!", 0));
		if (!~length) return assign(q);
		if (!~q.length) return;
		length = std::max(length, q.length);
		for (int i = 0; i <= length; ++ i){
			a[i] = a[i] + q.a[i];
			a[i] -= a[i] >= moder ? moder : 0;
		}
		for ( ; ~length && !a[length]; -- length)
			;
	}

	void minus(Poly &q){
		if (moder != q.moder) assert(("Invalid polynomial subtraction!", 0));
		if (!~length) return assign(q);
		if (!~length) return;
		length = std::max(length, q.length);
		for (int i = 0; i <= length; ++ i){
			a[i] = a[i] - q.a[i];
			a[i] += a[i] < 0 ? moder : 0;
		}
		for ( ; ~length && !a[length]; -- length)
			;
	}

	void mult(Poly &q){
		static int multmoder[2] = {998244353, 1004535809};
		static int multroot[2] = {3, 3};
		static int multinvroot[2] = {332748118, 334845270};
		static int aux[1 << MAX], aux1[1 << MAX];
		if (moder != q.moder) assert(("Invalid polynomial multiplication!", 0));
		if (!~length || !~q.length) return setmoder(moder, root, invroot);
		int n = length + q.length;
		int lengthans = 1;
		for ( ; lengthans <= n; lengthans <<= 1)
			;
		memcpy(aux, q.a, sizeof(int) * lengthans);
		memcpy(aux1, q.a, sizeof(int) * lengthans);
		NTT(a, lengthans, 1, multmoder[0], multroot[0]);
		NTT(aux, lengthans, 1, multmoder[0], multroot[0]);
		for (int i = 0; i < lengthans; ++ i){
			aux[i] = 1ll * aux[i] * a[i] % multmoder[0];
		}
		NTT(a, lengthans, -1, multmoder[0], multinvroot[0]);
		NTT(aux, lengthans, -1, multmoder[0], multinvroot[0]);
		NTT(a, lengthans, 1, multmoder[1], multroot[1]);
		NTT(aux1, lengthans, 1, multmoder[1], multroot[1]);
		for (int i = 0; i < lengthans; ++ i){
			aux1[i] = 1ll * aux1[i] * a[i] % multmoder[1];
		}
		NTT(aux1, lengthans, -1, multmoder[1], multinvroot[1]);
		memset(a, 0, sizeof(int) * lengthans);
		length = n;
		for(int i = 0; i <= length; ++ i){
			modequa <ll> equa(aux[i], multmoder[0]), equb(aux1[i], multmoder[1]);
			equa.crt(equb);
			a[i] = equa.getremain() % moder;
		}
	}

	void mult(int q){
		for (int i = 0; i <= length; ++ i){
			a[i] = 1ll * a[i] * q % moder;
		}
	}
};

int Poly::numinv[1 << Poly::MAX] = {};

const int N = 100;

int maxn, maxa, moder;
Poly a, b, ret1, ret2;
int q[N];

int main(){
	scanf("%d%d%d", &maxn, &maxa, &moder);
	if (maxa == 1){
		return printf("0\n"), 0;
	}
	int cnt = 0;
	for (maxa >>= 1; maxa; maxa >>= 1){
		q[cnt ++] = maxa;
	}
	std::reverse(q, q + cnt);
	int ans = 1;
	a.setmoder(moder, 0, 0);
	b.setmoder(moder, 0, 0);
	a.setvalue(0, 1);
	b.setvalue(1, 1);
	a.setlength(maxn);
	b.setlength(maxn);
	for (int i = 0; i < cnt - 1; ++ i){
		ret1.assign(a);
		ret1.add(b);
		ret1.mult(q[i] & 1 ? b : a);
		if (q[i] & 1 ? b.getvalue(0) : a.getvalue(0)){
			ret1.minus(b);
		}
		else{
			ret1.add(a);
		}
		ret1.setlength(maxn);
		ret2.assign(a);
		ret2.add(b);
		ret2.mult(q[i] & 1 ? a : b);
		if (q[i] & 1 ? a.getvalue(0) : b.getvalue(0)){
			ret2.minus(a);
		}
		else{
			ret2.add(b);
		}
		ret2.setlength(maxn);
		if (q[i + 1] & 1){
			for (int i = 1; i <= maxn; ++ i){
				a.setvalue(i, ret1.getvalue(i));
			}
			for (int i = 1; i <= maxn; ++ i){
				b.setvalue(i, (ret2.getvalue(i) + ret1.getvalue(i - 1) + ret2.getvalue(i - 1)) % moder);
			}
		}
		else{
			a.assign(ret1);
			b.assign(ret2);
		}
		for (int i = 1; i <= maxn; ++ i){
			if (i & 1){
				ans = (ans + b.getvalue(i)) % moder;
			}
		}
	}
	return printf("%d\n", ans), 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define rep(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
typedef long double ld;
const ld PI=3.141592653589793238;
const int N=70010;
//const int N=20;
int n,mod;
int digit,L;
int ans;

struct complex{
	ld x,y;
	complex(){}
	complex(ld x,ld y):x(x),y(y){}
	complex operator + (complex p){return complex(x+p.x,y+p.y);}
	complex operator - (complex p){return complex(x-p.x,y-p.y);}
	complex operator * (complex p){return complex(x*p.x-y*p.y,x*p.y+y*p.x);}
};

complex g[2][N],h[2][N];complex Root[N],IRoot[N];int R[N];
int f[2][N],tmp[2][N];

void DFT(complex a[],complex w[]){
	int i,j,k;complex x,y;
	rep(i,0,digit-1)	if(i>R[i])	swap(a[i],a[R[i]]);
	for(i=1;i<digit;i<<=1){
		for(j=0;j<digit;j+=(i<<1)){
			for(k=0;k<i;k++){
				x=a[j+k];y=a[j+k+i]*w[digit/(i<<1)*k];
				a[j+k]=x+y;a[j+k+i]=x-y;
			}
		}
	}
}

void init(){
	int i;
	for(digit=1,L=0;digit<=n*2;digit<<=1,L++);
	rep(i,1,digit-1)	R[i]=R[i>>1]>>1|((i&1)<<(L-1));
	Root[0]=complex(1,0);rep(i,1,digit-1)	Root[i]=complex(cos(2*PI*i/(ld)digit),sin(2*PI*i/(ld)digit));
	IRoot[0]=complex(1,0);rep(i,1,digit-1)	IRoot[i]=complex(cos(2*PI*i/(ld)digit),sin(-2*PI*i/(ld)digit));
}

void solve(int m){
	//f(m,n,p)
	int i,j;
	if(m==1){f[1][1]=1;f[0][1]=0;f[0][0]=1;ans=1;return;}
	solve(m>>1);
	rep(i,0,digit-1)	g[0][i]=complex(f[0][i],0);
	rep(i,0,digit-1)	g[1][i]=complex(f[1][i],0);
	DFT(g[0],Root);
	DFT(g[1],Root);
	//printf("%d\n",m);
	/*rep(i,0,n){
		tmp[0][i]=tmp[1][i]=0;
		rep(j,0,i){
			tmp[0][i]+=(f[0][j]+f[1][j])*f[m>>1&1][i-j];
			tmp[1][i]+=(f[0][j]+f[1][j])*f[!(m>>1&1)][i-j];
		}
	}
	rep(i,0,digit-1)	printf("%d ",tmp[0][i]);printf("\n");
	rep(i,0,digit-1)	printf("%d ",tmp[1][i]);printf("\n");
	rep(i,0,digit)	tmp[0][i]=tmp[1][i]=0;*/
	rep(i,0,digit-1){
		h[0][i]=(g[0][i]+g[1][i])*g[m>>1&1][i];
		h[1][i]=(g[0][i]+g[1][i])*g[!(m>>1&1)][i];
	}
	DFT(h[0],IRoot);
	DFT(h[1],IRoot);
	//rep(i,0,digit-1)	printf("%d ",(int)(h[0][i].x/(ld)digit+0.3));printf("\n");
	//rep(i,0,digit-1)	printf("%d ",(int)(h[1][i].x/(ld)digit+0.3));printf("\n");
	rep(i,0,n){
		tmp[0][i]=(f[0][i]+(ll)(h[0][i].x/(ld)digit+0.3)-1ll*(f[0][i]+f[1][i])*f[m>>1&1][0])%mod;
		tmp[1][i]=(f[1][i]+(ll)(h[1][i].x/(ld)digit+0.3)-1ll*(f[0][i]+f[1][i])*f[!(m>>1&1)][0])%mod;
	}
	rep(i,0,n)	{f[0][i]=tmp[0][i];f[1][i]=tmp[1][i];}
	//rep(i,0,n)	printf("%d ",f[0][i]);printf("\n");
	//rep(i,0,n)	printf("%d ",f[1][i]);printf("\n");
	if(m&1)	for(i=n;i>=1;i--)	{f[1][i]=(f[1][i]+f[1][i-1]+f[0][i-1])%mod;}
	for(i=1;i<=n;i+=2)	ans=(ans+f[1][i])%mod;
	//rep(i,0,n)	printf("%d ",f[0][i]);printf("\n");
	//rep(i,0,n)	printf("%d ",f[1][i]);printf("\n");
	//printf("ans=%d\n",ans);
}

void test(){
	static complex a[20];
	int i;
	n=3;init();
	rep(i,0,n)	a[i]=complex(1,0);
	DFT(a,Root);
	rep(i,0,digit-1)	a[i]=a[i]*a[i];
	DFT(a,IRoot);
	rep(i,0,digit-1)	printf("%d ",(int)(a[i].x/(ld)digit+0.3));
}

int main(){
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	int m;//test();
	scanf("%d%d%d",&n,&m,&mod);
	init();
	solve(m>>1);
	ans=(ans+mod)%mod;
	printf("%d\n",ans);
}


#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int n;
int miin;
int x,y,k,l;
int t[100010];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin>>n>>k>>l;
    x=0;
    y=0;
    for (int i=0;i<n;i++)
    {
        char a;
        cin>>a;
        if (a=='0')
            x++;
        else
            y++;
    }
    for (int i=1;i<y+1;i++)
    {
        t[i]=i*k+l*(pow((n-i)/i,2)*i+2*((n-i)%i)*((n-i)/i)+(n-i)%i);
    }
    miin=t[1];
    for (int i=2;i<y+1;i++)
        miin=min(miin,t[i]);
    cout<<miin;
    return 0;
}


#include <iostream>
#include <string>

using namespace std;

int main()
{
	long long n, c1, c2;
	cin >> n >> c1 >> c2;

	string s;
	cin >> s;

	long long sc = 0, b = 0;
	for(int i = 0; i < s.size(); i ++)
		if(s[i] == '0')
			sc ++;
		else
			b ++;
	long long ans = 1000000000000;

	for(int i = 1; i <= b; i ++)
		  ans = min(ans, c1 + c2 * (n / i + n % i - 1) *  (n / i + n % i - 1) + (i - 1) *
			  (c1 + c2 * (n / i - 1) * (n / i - 1)));
	cout << ans << endl;

}


 #include<iostream>
#include<fstream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<map>
#include<string>
#include<stack>
#include<vector>
#include<set>
#include<iomanip>

using namespace std;
using namespace std;

void main() {
#if defined(_DEBUG)
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	cout << fixed << setprecision(15);
	long long n,c1,c2;
	cin >> n>>c1>>c2;
	long long d = 0, v = 0;
	for (int i = 0; i  < n; i++)
	{
		char f;
		cin >> f;
		if (f =='1')
	     v++;
		else
		 d++;
	}
	long long min =100000000000000000000;
	for (int i = v; i >0 ;i--)
	{
		long long s = n / i;
		long long m = n % i;
		if (c1*i + c2*(s - 1)*(s - 1) * (i - m) + c2*(s*s)*m < min)
			min = c1*i + c2*(s - 1)*(s - 1) * (i - m) + c2*(s*s)*m;
	}
	cout << min;
}


#include<bits/stdc++.h>
using namespace std;
#define fast ios_base::sync_with_stdio(false); cin.tie(0);
#define rep(i,n,m) for(int i=n;i<m;i++)
#define pre(i,n,m) for(int i=n-1;i>=m;i--)
#define vii vector<int>
#define vi vector<vii>
#define pi pair<int,int>
#define mi unordered_map<int,int>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define sz(xx) (int)xx.size()
#define all(yy) yy.begin(),yy.end()
#define rall(yyy) yyy.rbegin(),yyy.rend()
#define f first
#define s second
#define ll long long
#define ld long double
#define hell 100000000000LL
#define callable 998244353
const int mod=1e9+7;
template<typename T1,typename T2> inline void chkmin(T1 &x, T2 y) { if(y<x) x=y; };
template<typename T1,typename T2> inline void chkmax(T1 &x,T2 y) { if(y>x) x=y; };
int gcd(int x,int y)
{
	return(y==0?x:gcd(y,x%y));
}
inline int mul(int a,int b)
{
	return(1ll*a*b)%callable;
}
inline int sub(int a,int b)
{
	a-=b;
	if(a<0)
	a+=mod;
	if(a>=mod)
	a-=mod;
	return a;
}
inline int add(int a,int b)
{
	a+=b;
	if(a>=mod)
	a-=mod;
	if(a<0)
	a+=mod;
	return a;
}
inline int expo(int a,int b)
{
	int values=1;
	while(b)
	{
		if(b&1)
		values=mul(values,a);
		a=mul(a,a);
		b>>=1;
	}
	return values%mod;
}
const int MAXN=1e5+100;
ll n,c1,c2,
inline ll call(ll sss,ll cnt)
{
	return cnt*(c1+c2*(sss-1)*(sss-1));
}
ll can(ll g)
{
	ll k,r;
	k=n/g;
	r=n%g;
	ll ss=g-r;
	ll bb=r;
	return call(k,ss)+call(k+1,bb);
}
void solve()
{
	ll val=0;
	cin>>n>>c1>>c2;
	rep(i,0,n)
	{
		char c;
		cin>>c;
		if(c=='1')
		++val;
	}
	ll res=1e18;
	pre(i,val+1,1)
	{
		ll cur=can(i);
		if(cur<res)
		res=cur;
	}
	cout<<res<<endl;
}
int main()
{
	int t=1;
	//cin>>t;
	while(t--)
	{
		solve();
    }
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1E6+5;
int n,m,size,head[maxn];
inline int read()
{
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	int s=ch-'0';ch=getchar();
	while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
	return s;
}
struct edge
{
	int to,next,w;
}E[maxn*2];
inline void add(int u,int v)
{
	E[++size].to=v;
	E[size].next=head[u];
	head[u]=size;
}
bool vis[maxn];
int f[maxn];
int TI,tmp[maxn];
inline void bfs(int S)
{
	queue<int>Q;
	Q.push(S);
	vis[S]=1;
	f[S]=0;
	while(!Q.empty())
	{
		int u=Q.front();
		Q.pop();
		++TI;
		for(int i=head[u];i;i=E[i].next)
		{
			int v=E[i].to;
			if(f[v]!=-1)
				tmp[f[v]]=TI;
			if(!vis[v])
			{
				vis[v]=1;
				Q.push(v);
			}
		}
		int pos=0;
		while(tmp[pos]==TI)
			++pos;
		f[u]=pos;
	}
}
vector<int>wait[12555];
int gg[maxn];
bool cmp(int x,int y)
{
	return f[x]>f[y];
}
inline void solve()
{
	for(int i=1;i<=n;++i)
		wait[f[i]].push_back(i);
//	for(int i=1;i<=n;++i)
//		cout<<f[i]<<" ";cout<<endl;
	for(int e=n;e>=0;--e)
		for(int q=0;q<wait[e].size();++q)
		{
			int u=wait[e][q];
			gg[u]=1;
			int tot=0;
			for(int i=head[u];i;i=E[i].next)
			{
				int v=E[i].to;
				if(gg[v]||f[v]==0)
					continue;
				tmp[++tot]=v;
			}
			sort(tmp+1,tmp+tot+1,cmp);
			for(int i=1;i<=tot;++i)
			{
				int v=tmp[i];
				int k=min(2,min(f[u],f[v]));
				f[u]-=k,f[v]-=k;
				E[i].w=k;
			}
		}
	vector<int>A;
	for(int u=1;u<=n;++u)
	{
		assert(f[u]<=1);
		if(f[u])
			A.push_back(u);
	}
	cout<<A.size()<<'\n';
	for(int i=0;i<A.size();++i)
		cout<<A[i]<<" ";
	if(A.size()!=0)
		cout<<'\n';
	for(int u=1;u<=n;++u)
		for(int i=head[u];i;i=E[i].next)
		{
			int v=E[i].to;
			if(u>=v)
				cout<<u<<" "<<v<<" "<<E[i].w<<'\n';
		}
}
int main()
{
	ios::sync_with_stdio(false);
	n=read(),m=read();
	for(int i=1;i<=m;++i)
	{
		int x=read(),y=read();
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=n;++i)
		f[i]=-1;
	for(int i=1;i<=n;++i)
		if(!vis[i])
			bfs(i);
	solve();
	return 0;
}


/*
读题不规范，爆零两行泪。
数据不清空，爆零两行泪。
多测不读完，爆零两行泪。
边界不特判，爆零两行泪。
贪心不证明，爆零两行泪。
D P 顺序错，爆零两行泪。
大小少等号，爆零两行泪。
变量不统一，爆零两行泪。
越界不判断，爆零两行泪。
调试不注释，爆零两行泪。
溢出不 l l，爆零两行泪。
*/
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define X first
#define Y second
const int N=12500,M=1000000;
int n,m;
vector<pair<int,int> > nei[N+1];
int a[N+1],b[N+1];
int ansv[N+1],anse[M+1];
int val[N+1];
bool hav[N+1];
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		a[i]=x,b[i]=y;
		nei[x].pb(mp(y,i));nei[y].pb(mp(x,i));
		anse[i]=1;
	}
	for(int i=1;i<=n;i++){
		int dec=0;
		for(int j=0;j<nei[i].size();j++){
			int x=nei[i][j].X;
			if(x<i)hav[val[x]]=true;
			if(x<i&&!ansv[x])dec++;
		}
		for(int j=nei[i].size()-dec;;j++)if(!hav[j]){val[i]=j;break;}
		int now=val[i]-nei[i].size();
		for(int j=0;j<nei[i].size();j++){
			int x=nei[i][j].X,y=nei[i][j].Y;
			if(x<i)hav[val[x]]=false;
			if(x<i&&!ansv[x]&&now<0)now++,ansv[x]++,anse[y]--;
			if(x<i&&ansv[x]&&now>0)now--,ansv[x]--,anse[y]++;
		}
	}
	vector<int> v;
	for(int i=1;i<=n;i++)if(ansv[i])v.pb(i);
	cout<<v.size()<<"\n";
	for(int i=0;i<v.size();i++)cout<<v[i]<<" \n"[i+1==v.size()];
	for(int i=1;i<=m;i++)printf("%d %d %d\n",a[i],b[i],anse[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1E6+5;
int n,m,size,head[maxn];
inline int read()
{
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	int s=ch-'0';ch=getchar();
	while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
	return s;
}
struct edge
{
	int to,next,w;
}E[maxn*2];
inline void add(int u,int v)
{
	E[++size].to=v;
	E[size].next=head[u];
	head[u]=size;
}
bool vis[maxn];
int f[maxn];
int TI,tmp[maxn];
inline void bfs(int S)
{
	queue<int>Q;
	Q.push(S);
	vis[S]=1;
	f[S]=0;
	while(!Q.empty())
	{
		int u=Q.front();
		Q.pop();
		++TI;
		for(int i=head[u];i;i=E[i].next)
		{
			int v=E[i].to;
			if(f[v]!=-1)
				tmp[f[v]]=TI;
			if(!vis[v])
			{
				vis[v]=1;
				Q.push(v);
			}
		}
		int pos=0;
		while(tmp[pos]==TI)
			++pos;
		f[u]=pos;
	}
}
vector<int>wait[12555];
int gg[maxn];
inline void solve()
{
	for(int i=1;i<=n;++i)
		wait[f[i]].push_back(i);
	for(int e=n;e>=0;--e)
		for(int q=0;q<wait[e].size();++q)
		{
			int u=wait[e][q];
			gg[u]=1;
			for(int i=head[u];i;i=E[i].next)
			{
				int v=E[i].to;
				if(gg[v])
					continue;
				int k=min(2,min(f[u],f[v]));
				f[u]-=k,f[v]-=k;
				E[i].w=k;
			}
		}
	vector<int>A;
	for(int u=1;u<=n;++u)
	{
		assert(f[u]<=1);
		if(f[u])
			A.push_back(u);
	}
	cout<<A.size()<<'\n';
	for(int i=0;i<A.size();++i)
		cout<<A[i]<<" ";
	if(A.size()!=0)
		cout<<'\n';
	for(int u=1;u<=n;++u)
		for(int i=head[u];i;i=E[i].next)
		{
			int v=E[i].to;
			if(u>=v)
				cout<<u<<" "<<v<<" "<<E[i].w<<'\n';
		}
}
int main()
{
	ios::sync_with_stdio(false);
	n=read(),m=read();
	for(int i=1;i<=m;++i)
	{
		int x=read(),y=read();
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=n;++i)
		f[i]=-1;
	for(int i=1;i<=n;++i)
		if(!vis[i])
			bfs(i);
	solve();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=1E6+5;
int n,m,size,head[maxn];
inline int read()
{
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	int s=ch-'0';ch=getchar();
	while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
	return s;
}
struct edge
{
	int to,next,w;
}E[maxn*2];
inline void add(int u,int v)
{
	E[++size].to=v;
	E[size].next=head[u];
	head[u]=size;
}
bool vis[maxn];
int f[maxn];
int TI,tmp[maxn];
inline void bfs(int S)
{
	queue<int>Q;
	Q.push(S);
	vis[S]=1;
	f[S]=0;
	while(!Q.empty())
	{
		int u=Q.front();
		Q.pop();
		++TI;
		for(int i=head[u];i;i=E[i].next)
		{
			int v=E[i].to;
			if(f[v]!=-1)
				tmp[f[v]]=TI;
			if(!vis[v])
			{
				vis[v]=1;
				Q.push(v);
			}
		}
		int pos=0;
		while(tmp[pos]==TI)
			++pos;
		f[u]=pos;
	}
}
vector<int>wait[12555];
inline void solve()
{
	for(int i=1;i<=n;++i)
		wait[f[i]].push_back(i);
	for(int e=n;e>=0;--e)
		for(int q=0;q<wait[e].size();++q)
		{
			int u=wait[e][q];
			for(int i=head[u];i;i=E[i].next)
			{
				int v=E[i].to;
				if(u<v)
					continue;
				int k=min(2,min(f[u],f[v]));
				f[u]-=k,f[v]-=k;
				E[i].w=k;
			}
		}
	vector<int>A;
	for(int u=1;u<=n;++u)
	{
		assert(f[u]<=1);
		if(f[u])
			A.push_back(u);
	}
	cout<<A.size()<<'\n';
	for(int i=0;i<A.size();++i)
		cout<<A[i]<<" ";
	if(A.size()!=0)
		cout<<'\n';
	for(int u=1;u<=n;++u)
		for(int i=head[u];i;i=E[i].next)
		{
			int v=E[i].to;
			if(u>=v)
				cout<<u<<" "<<v<<" "<<E[i].w<<'\n';
		}
}
int main()
{
	ios::sync_with_stdio(false);
	n=read(),m=read();
	for(int i=1;i<=m;++i)
	{
		int x=read(),y=read();
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=n;++i)
		f[i]=-1;
	for(int i=1;i<=n;++i)
		if(!vis[i])
			bfs(i);
	solve();
	return 0;
}


#include<bits/stdc++.h>
#define maxn 10010
using namespace std;
typedef double ldb;
const ldb eps=1e-7;
struct edge{
	int r,nxt;
	ldb w;
}e[maxn<<1];
int fr[maxn],to[maxn],n,m,a[maxn],b[maxn],c[maxn],d[maxn];
int q[maxn],l,r,cur[maxn],dep[maxn],head[maxn],esz,S,T;
void addedge(int u,int v,ldb w){
	e[++esz].r=v;e[esz].nxt=head[u];head[u]=esz;e[esz].w=w;
	e[++esz].r=u;e[esz].nxt=head[v];head[v]=esz;e[esz].w=0;
}
bool bfs(){
	for(int i=S;i<=T;++i)cur[i]=head[i],dep[i]=0;
	q[r++]=S,dep[S]=1;
	while(l<r){
		int u=q[l++];
		for(int t=head[u];t;t=e[t].nxt)if(e[t].w>eps&&!dep[e[t].r])
			dep[e[t].r]=dep[u]+1,q[r++]=e[t].r;
	}
	return dep[T]!=0;
}
ldb find(int u,ldb flow){
	if(u==T)return flow;
	ldb used=0,a=0;
	for(int& t=cur[u];t;t=e[t].nxt)if(e[t].w>eps&&dep[e[t].r]==dep[u]+1){
		a=find(e[t].r,min(flow-used,e[t].w));
		used+=a,e[t].w-=a,e[t^1].w+=a;
		if(used==flow)return used;
	}
	return used;
}
ldb dinic(){
	ldb ans=0;
	while(bfs())
		ans+=find(S,1e20);
	return ans;
}
ldb sol(ldb t){
	ldb sum=0;
	esz=1,S=0,T=n+1;
	for(int i=S;i<=T;++i)head[i]=0;
	for(int i=1;i<=m;++i){
		ldb l=a[i]*t+b[i],r=c[i]*t+d[i];
		addedge(S,to[i],l);
		addedge(fr[i],T,l);
		addedge(fr[i],to[i],r-l);
		sum+=l;
	}
	return sum-dinic();
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i)
		scanf("%d%d%d%d%d%d",&fr[i],&to[i],&a[i],&b[i],&c[i],&d[i]);
	ldb l=0,r=1;
	for(int i=0;i<50;++i){
		ldb mid1=(l+l+r)/3,mid2=(l+r+r)/3;
		ldb f1=sol(mid1),f2=sol(mid2);
		if(f1>f2)l=mid1;
		else r=mid2;
	}
//	printf("[%.5lf,%.5lf]",l,sol(l));
	ldb l1=0,r1=l;
	for(int i=0;i<50;++i){
		ldb mid=(l1+r1)/2;
		if(sol(mid)<eps)r1=mid;
		else l1=mid;
	}
	ldb l2=l,r2=1;
	for(int i=0;i<50;++i){
		ldb mid=(l2+r2)/2;
		if(sol(mid)<eps)l2=mid;
		else r2=mid;
	}
//	printf("[%.7lf,%.7lf]",l1,l2);
	printf("%.10lf",(l2-l1));
}


#include <bits/stdc++.h>

using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
// head

typedef double db;
const db EPS = 1e-9;
const db inf=1e20;
inline int sign(db a) { return a < -EPS ? -1 : a > EPS; }
inline int cmp(db a, db b){ return sign(a-b); }

const int N=101000;
int ts,u[N],v[N],a[N],b[N],c[N],d[N],n,m;
typedef db flowt;
namespace flow {
	const int M=100000,N=1000;
	int y[M],nxt[M],gap[N],fst[N],c[N],pre[N],q[N],dis[N];
	int slope[M];
	flowt f[M];
	int S,T,tot,Tn;
	void init(int s,int t,int tn) {
		tot=1;
		memset(fst,0,sizeof(fst));
		S=s;T=t;Tn=tn;
	}
	void add(int u,int v,int c,flowt c1,flowt c2=0) {
		tot++;y[tot]=v;f[tot]=c1;nxt[tot]=fst[u];fst[u]=tot;
		slope[tot]=c;
		tot++;y[tot]=u;f[tot]=c2;nxt[tot]=fst[v];fst[v]=tot;
		slope[tot]=0;
	}
	flowt sap() {
		int u=S,t=1;flowt flow=0;
		rep(i,0,Tn) c[i]=fst[i],dis[i]=Tn,gap[i]=0;
		q[0]=T;dis[T]=0;pre[S]=0;
		rep(i,0,t) {
			int u=q[i];
			for (int j=fst[u];j;j=nxt[j]) if (dis[y[j]]>dis[u]+1&&fabs(f[j^1])>EPS)
				q[t++]=y[j],dis[y[j]]=dis[u]+1;
		}
		rep(i,0,Tn) gap[dis[i]]++;
		while (dis[S]<=Tn) {
			while (c[u]&&(fabs(f[c[u]])<EPS||dis[y[c[u]]]+1!=dis[u])) c[u]=nxt[c[u]];
			if (c[u]) {
				pre[y[c[u]]]=c[u]^1;
				u=y[c[u]];
				if (u==T) {
					flowt minf=inf;
					for (int p=pre[T];p;p=pre[y[p]]) minf=min(minf,f[p^1]);
					for (int p=pre[T];p;p=pre[y[p]]) f[p^1]-=minf,f[p]+=minf;
					flow+=minf;u=S;
				}
			} else {
				if (!(--gap[dis[u]])) break;
				int mind=Tn;
				c[u]=fst[u];
				for (int j=fst[u];j;j=nxt[j]) if (fabs(f[j])>EPS&&dis[y[j]]<mind)
					mind=dis[y[j]],c[u]=j;
				dis[u]=mind+1;
				gap[dis[u]]++;
				if (u!=S) u=y[pre[u]];
			}
		}
		q[0]=S; t=1;
		rep(i,0,Tn) dis[i]=Tn;
		dis[S]=0;
		rep(i,0,t) {
			int u=q[i];
			for (int j=fst[u];j;j=nxt[j]) if (dis[y[j]]>dis[u]+1&&fabs(f[j])>EPS) {
				dis[y[j]]=dis[u]+1;
				q[t++]=y[j];
			}
		}
		ts=0;
		rep(i,0,Tn) for (int j=fst[i];j;j=nxt[j]) if (dis[i]<Tn&&dis[y[j]]>=Tn) ts+=slope[j];
		return flow;
	}
};

db bel[N];
int sl[N];
int check(double t) {
	rep(i,1,n+1) bel[i]=0,sl[i]=0;
	flow::init(0,n+1,n+2);
	rep(i,0,m) {
		db l=a[i]*t+b[i],r=c[i]*t+d[i];
		flow::add(u[i],v[i],c[i]-a[i],r-l);
		bel[u[i]]+=l; bel[v[i]]-=l;
		sl[u[i]]+=a[i]; sl[v[i]]-=a[i];
	}
	db sf=0;
	int ss=0;
	rep(i,1,n+1) if (bel[i]>0) {
		sf+=bel[i]; flow::add(i,n+1,sl[i],bel[i]);
		ss+=sl[i];
	} else flow::add(0,i,-sl[i],-bel[i]);
	db r=flow::sap();
	if (ts==ss) {
		if (cmp(r,sf)==-1) return 2;
		else return 1;
	} else if (ts>ss) return 0;
	else return 2;
}
double gao(int ty) {
	double l=0,r=1;
	while (clock()<0.85*ty*CLOCKS_PER_SEC) {
		double md=(l+r)*0.5;
		if (check(md)>=ty) r=md; else l=md;
	}
	return 0.5*(l+r);
}
int main() {
	scanf("%d%d",&n,&m);
	rep(i,0,m) scanf("%d%d%d%d%d%d",u+i,v+i,a+i,b+i,c+i,d+i);
	db l=gao(1),r=gao(2);
	printf("%.10f\n",r-l);
}


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

const int NMAX = 1005;
const int MMAX = 2005;

const double EPS = 1e-8;

template <class CapacityType>
class MaxFlow {
private:
    static constexpr int NIL = -1;
    static constexpr long double EPS = 1e-8;

    static constexpr int INF =
    std::numeric_limits<int> :: max() / 2;

    template <class type>
    int cmp(type x) {
        if (-EPS < x and x < EPS)
            return 0;
        return x < 0 ? -1 : 1;
    }

    struct Edge {
        int nod, nxt;
        CapacityType cap;

        Edge() :
        nod(0), nxt(0), cap(0) {};
        Edge(int _nod, int _nxt, CapacityType _cap) :
        nod(_nod), nxt(_nxt), cap(_cap) {};
    }; std::vector<Edge> lst;

    std::vector<bool> oki; int ptr = 0;
    std::vector<int> beg, que, adj, dis;

    bool bfs(const int src, const int dst) {
        std::fill(dis.begin(), dis.end(), (CapacityType)INF);
        dis[src] = 0; que[0] = src;

        for (int qbg = 0, qen = 0; qbg <= qen; ++qbg) {
            const int x = que[qbg];

            for (int it = beg[x]; it != NIL; it = lst[it].nxt) {
                const int y = lst[it].nod;

                if (cmp(lst[it].cap) > 0 and dis[y] == INF)
                    dis[y] = dis[x] + 1, que[++qen] = y;
            }
        }

        return dis[dst] != INF;
    }

    CapacityType dfs(const int x, const int dst, const CapacityType cap) {
        if (!cmp(cap) or x == dst)
            return cap;

        for (; adj[x] != NIL; adj[x] = lst[adj[x]].nxt) {
            const int y = lst[adj[x]].nod;

            if (cmp(lst[adj[x]].cap) > 0 and dis[y] == dis[x] + 1) {
                const CapacityType aux = dfs(y, dst, std::min(cap, lst[adj[x]].cap));

                if (cmp(aux)) {
                    lst[adj[x]].cap -= aux;
                    lst[adj[x] ^ 1].cap += aux;
                    return aux;
                }
            }
        }

        return 0;
    }

    void fill(const int x) {
        oki[x] = true;

        for (int it = beg[x]; it != NIL; it = lst[it].nxt) {
            const int y = lst[it].nod;

            if (cmp(lst[it].cap) > 0 and !oki[y])
                fill(y);
        }
    }
public:
    MaxFlow(int szn, int szm) {
        dis.resize(szn); beg.resize(szn);
        que.resize(szn); adj.resize(szn);
        oki.resize(szn); lst.resize(szm); // m != n

        std::fill(beg.begin(), beg.end(), (int)NIL);
    }

    inline void addDirectedEdge(const int x, const int y, const CapacityType cap) {
        lst[ptr] = Edge(y, beg[x], cap); beg[x] = ptr++;
        lst[ptr] = Edge(x, beg[y],  0 ); beg[y] = ptr++;
    }

    inline void addUndirectedEdge(const int x, const int y, const CapacityType cap) {
        lst[ptr] = Edge(y, beg[x], cap); beg[x] = ptr++;
        lst[ptr] = Edge(x, beg[y], cap); beg[y] = ptr++;
    }

    CapacityType getMaxFlow(const int src, const int dst) {
        CapacityType aux, ans = 0;

        while (bfs(src, dst)) {
            copy(beg.begin(), beg.end(), adj.begin());

            do {
                aux = dfs(src, dst, INF);
                ans += aux;
            } while (cmp(aux));
        }

        return ans;
    }

    CapacityType getMinCut(const int src, const int dst, std::vector<int> &ans) {
        std::fill(oki.begin(), oki.end(), false);
        CapacityType sol = getMaxFlow(src, dst); fill(src);

        ans.clear();
        for (int i = 0; i < oki.size(); ++i)
            if (oki[i]) ans.push_back(i);

        return sol;
    }
};

struct edge {
    int x, y, a, b, c, d; } edl[MMAX];

inline long double sign(long double x)
{
    if (-EPS < x and x < +EPS)
        return 0;
    return x < 0 ? -1 : 1;
}

long double check(long double t, int n, int m)
{
    int src = n + 1, dst = n + 2; long double sum = 0;
    MaxFlow<long double> myNetwork(n + 5, m * 6 + 5);

    for (int i = 1; i <= m; ++i) {
        int x = edl[i].x, y = edl[i].y;
        long double le = t * edl[i].a + edl[i].b,
                    ri = t * edl[i].c + edl[i].d;

        sum += le;
        myNetwork.addDirectedEdge(x, y, ri - le);
        myNetwork.addDirectedEdge(src, y, le);
        myNetwork.addDirectedEdge(x, dst, le);
    }

    return sum - myNetwork.getMaxFlow(src, dst);
}

long double solve(long double le, long double ri, int n, int m)
{
    long double ans = 0;
    for (int i = 1; i <= 70; ++i) {
        long double md = (le + ri) / 2.0;

        if (sign(check(md, n, m)) <= 0) {
            ans += fabs(md - le);
            le = md;
        } else
            ri = md;
    }
    return ans;
}

void debug(void)
{
    MaxFlow<double> myNetwork(4, 6);

    myNetwork.addDirectedEdge(1, 2, 0.5);
    myNetwork.addDirectedEdge(2, 3, 0.3);

    cerr << myNetwork.getMaxFlow(1, 3);

    exit(0);
}

int main(void)
{
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);

    // debug();

    int n, m;
    cin >> n >> m;

    for (int i = 1; i <= m; ++i) {
        cin >> edl[i].x >> edl[i].y;
        cin >> edl[i].a >> edl[i].b >> edl[i].c >> edl[i].d;
    }

    /*
    for (double x = 0.0; x <= 1.00001; x += 0.05) {
        cout << setprecision(2) << fixed << x << " ";
        cout << setprecision(10) << fixed << check(x, n, m) << endl;
    }
    */

    long double le = 0.0, ri = 1.0;
    for (int i = 1; i <= 70; ++i) {
        long double md1 = le + (ri - le) / 3.0,
        md2 = ri - (ri - le) / 3.0;

        long double ans1 = check(md1, n, m),
        ans2 = check(md2, n, m);

        if (sign(ans1) <= 0 and sign(ans2) <= 0) {
            cout << setprecision(10) << fixed;
            cout << solve((md1 + md2) / 2.0, 1.0, n, m) + solve((md1 + md2) / 2.0, 0.0, n, m);
            break;
        }

        if (ans1 < ans2) ri = md2;
        else             le = md1;
    }

    return 0;
}


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

namespace Dinic {
	typedef long long F;
	const F INF = 1LL<<60;

	const int N = 1100;
	const int M = 11000;

	int fst[N], nxt[M], to[M];
	F cap[M];
	int dis[N], q[N], ptr[N];
	int V, E;

	void init() {
		memset(fst, -1, sizeof fst);
		V = E = 0;
	}
	inline int add_node() { V++; return V-1; }
	inline void add_edge(int u, int v, F c) {
		to[E] = v, cap[E] = c, nxt[E] = fst[u], fst[u] = E++;
		to[E] = u, cap[E] = 0, nxt[E] = fst[v], fst[v] = E++;
	}
	inline bool bfs(int S, int T, int n) {
		memset(dis, -1, sizeof(int) * n);
		int h = 0, t = 0;
		dis[S] = 0, q[t++] = S;
		while (h < t) {
			int u = q[h++];
			for (int e = fst[u]; ~e; e = nxt[e]) if (cap[e] > 0 && dis[to[e]] == -1) {
				dis[to[e]] = dis[u] + 1, q[t++] = to[e];
				if (to[e] == T) return 1;
			}
		}
		return (dis[T] != -1);
	}
	F dfs(int u, int T, F f) {
		if (u == T) return f;
		for (int &e = ptr[u]; ~e; e = nxt[e]) if (cap[e] > 0 && dis[to[e]] > dis[u]) {
			F ret = dfs(to[e], T, min(f, cap[e]));
			if (ret > 0) {
				cap[e] -= ret, cap[e ^ 1] += ret;
				return ret;
			}
		}
		return 0;
	}
	F max_flow(int S, int T, int n = V) {
		F ret = 0;
		while (bfs(S, T, n)) {
			memcpy(ptr, fst, sizeof(int) * n);
			for (F cur; (cur = dfs(S, T, INF)) > 0; ret += cur);
		}
		return ret;
	}
}

long long ssum[1100], tsum[1100];

int main() {
	int n, m; scanf("%d%d", &n, &m);
	struct Edge {
		int u, v, a, b, c, d;
		void input() { scanf("%d%d%d%d%d%d", &u, &v, &a, &b, &c, &d); }
	} e[2200];
	for (int i = 1; i <= m; i++) e[i].input();
	int st = 0;
	int ans = 0;
	for (int j = 0; j < 2; j++) {
		int en = 1<<23;
		while (st < en) {
			Dinic::init();
			int mid = st + en >> 1;
			for (int i = 1; i <= n; i++) ssum[i] = tsum[i] = 0;
			for (int i = 1; i <= m; i++) {
				int u = e[i].u, v = e[i].v;
				long long l = e[i].a * 1LL * mid + ((long long)e[i].b << 23);
				long long r = e[i].c * 1LL * mid + ((long long)e[i].d << 23);
				ssum[v] += l, tsum[u] += l;
				Dinic::add_edge(u, v, r - l);
			}
			for (int i = 1; i <= n; i++) {
				if (ssum[i]) Dinic::add_edge(0, i, ssum[i]);
				if (tsum[i]) Dinic::add_edge(i, n+1, tsum[i]);
			}
			long long tot = 0;
			for (int i = 1; i <= n; i++) tot += ssum[i];
			long long ret = Dinic::max_flow(0, n+1, n+2);
			if (j == 0) {
				if (ret == tot) en = mid;
				else st = mid+1;
			} else {
				if (ret == tot) st = mid;
				else en = mid-1;
			}
		}
		if (j == 0) ans -= st;
		else ans += st;
	}
	printf("%.10lf\n", ans * 1.0 / (1<<23));
	return 0;
}


// Created by Nikolay Budin

#ifdef DEBUG
#  define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define ff first
#define ss second
#define szof(x) ((int)x.size())
#ifndef LOCAL
#  define cerr __get_ce
#endif

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef unsigned long long ull;

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

int const INF = (int)1e9 + 1e3;
ll const INFL = (ll)1e18 + 1e6;
#ifdef LOCAL
	mt19937 tw(9450189);
#else
	mt19937 tw(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif
uniform_int_distribution<ll> ll_distr;
ll rnd(ll a, ll b) { return ll_distr(tw) % (b - a + 1) + a; }

void solve() {
	int n;
	cin >> n;
	vector<int> color(n);
	for (int& num : color) {
		cin >> num;
	}
	vector<vector<int>> graph(n);
	for (int i = 0; i < n - 1; ++i) {
		int a, b;
		cin >> a >> b;
		--a; --b;
		graph[a].push_back(b);
		graph[b].push_back(a);
	}

	int ans = INF;

	int cnt1 = 0, cnt2 = 0;
	{
		vector<bool> used(n);
		function<void(int)> dfs = [&](int v) {
			used[v] = true;
			for (int to : graph[v]) {
				if (color[to] == color[v] && !used[to]) {
					dfs(to);
				}
			}
		};
		for (int i = 0; i < n; ++i) {
			if (!used[i]) {
				dfs(i);
				if (color[i] == 1) {
					++cnt1;
				}
				if (color[i] == 2) {
					++cnt2;
				}

			}
		}
	}

	ans = min(ans, 1 + cnt2);
	ans = min(ans, 1 + cnt1);

	for (int qwe = 0; qwe < 2; ++qwe) {
		vector<int> sz(n);
		const int MAX_SZ = 1000;
		function<vector<int>(int, int)> dfs = [&](int v, int p) {
			vector<int> dp;
			if (color[v] == 1 || color[v] == 0) {
				dp = {1};
			} else {
				dp = {INF, 2};
			}
			sz[v] = 1;
			for (int to : graph[v]) {
				if (to != p) {
					vector<int> tmp = dfs(to, v);
					sz[v] += sz[to];
					vector<int> next_dp(min(sz[v] + 2, MAX_SZ), INF);
					for (int i = 0; i < szof(next_dp); ++i) {
						int dp_val = INF;
						if (i < szof(dp)) {
							dp_val = dp[i];
						} else {
							if ((color[v] == 1 || color[v] == 0) && i % 2 == 0) {
								dp_val = i + 1;
							}
							if ((color[v] == 2 || color[v] == 0) && i % 2 == 1) {
								dp_val = i + 1;
							}
						}
						for (int j = 0; j < szof(tmp); ++j) {
							next_dp[i] = min(next_dp[i], dp_val + tmp[j] - min(i, j) - 1);
						}
					}
					swap(next_dp, dp);
				}
			}
			return dp;
		};

		auto dp = dfs(0, 0);
		ans = min(ans, *min_element(dp.begin(), dp.end()));

		for (int& num : color) {
			if (num == 1) {
				num = 2;
			} else if (num == 2) {
				num = 1;
			}
		}
	}

	cout << ans << "\n";
}

int main() {
#ifdef LOCAL
	auto start_time = clock();
	cerr << setprecision(3) << fixed;
#endif
	cout << setprecision(15) << fixed;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int test_count = 1;
	cin >> test_count;
	for (int test = 1; test <= test_count; ++test) {
		solve();
	}

#ifdef LOCAL
	auto end_time = clock();
	cerr << "Execution time: " << (end_time - start_time) * (int)1e3 / CLOCKS_PER_SEC << " ms\n";
#endif
}


// Created by Nikolay Budin

#ifdef DEBUG
#  define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define ff first
#define ss second
#define szof(x) ((int)x.size())
#ifndef LOCAL
#  define cerr __get_ce
#endif

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef unsigned long long ull;

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

int const INF = (int)1e9 + 1e3;
ll const INFL = (ll)1e18 + 1e6;
#ifdef LOCAL
	mt19937 tw(9450189);
#else
	mt19937 tw(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif
uniform_int_distribution<ll> ll_distr;
ll rnd(ll a, ll b) { return ll_distr(tw) % (b - a + 1) + a; }

void solve() {
	int n;
	cin >> n;
	vector<int> color(n);
	for (int& num : color) {
		cin >> num;
	}
	vector<vector<int>> graph(n);
	for (int i = 0; i < n - 1; ++i) {
		int a, b;
		cin >> a >> b;
		--a; --b;
		graph[a].push_back(b);
		graph[b].push_back(a);
	}

	int ans = INF;

	int cnt1 = 0, cnt2 = 0;
	{
		vector<bool> used(n);
		function<void(int)> dfs = [&](int v) {
			used[v] = true;
			for (int to : graph[v]) {
				if (color[to] == color[v] && !used[to]) {
					dfs(to);
				}
			}
		};
		for (int i = 0; i < n; ++i) {
			if (!used[i]) {
				dfs(i);
				if (color[i] == 1) {
					++cnt1;
				}
				if (color[i] == 2) {
					++cnt2;
				}

			}
		}
	}

	ans = min(ans, 1 + cnt2);
	ans = min(ans, 1 + cnt1);

	for (int qwe = 0; qwe < 2; ++qwe) {
		vector<int> sz(n);
		const int MAX_SZ = 500;
		function<vector<int>(int, int)> dfs = [&](int v, int p) {
			vector<int> dp;
			if (color[v] == 1 || color[v] == 0) {
				dp = {1};
			} else {
				dp = {INF, 2};
			}
			sz[v] = 1;
			for (int to : graph[v]) {
				if (to != p) {
					vector<int> tmp = dfs(to, v);
					sz[v] += sz[to];
					vector<int> next_dp(min(sz[v] + 2, MAX_SZ), INF);
					for (int i = 0; i < szof(next_dp); ++i) {
						int dp_val = INF;
						if (i < szof(dp)) {
							dp_val = dp[i];
						} else {
							if ((color[v] == 1 || color[v] == 0) && i % 2 == 0) {
								dp_val = i + 1;
							}
							if ((color[v] == 2 || color[v] == 0) && i % 2 == 1) {
								dp_val = i + 1;
							}
						}
						for (int j = 0; j < szof(tmp); ++j) {
							next_dp[i] = min(next_dp[i], dp_val + tmp[j] - min(i, j) - 1);
						}
					}
					swap(next_dp, dp);
				}
			}
			return dp;
		};

		auto dp = dfs(0, 0);
		ans = min(ans, *min_element(dp.begin(), dp.end()));

		for (int& num : color) {
			if (num == 1) {
				num = 2;
			} else if (num == 2) {
				num = 1;
			}
		}
	}

	cout << ans << "\n";
}

int main() {
#ifdef LOCAL
	auto start_time = clock();
	cerr << setprecision(3) << fixed;
#endif
	cout << setprecision(15) << fixed;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int test_count = 1;
	cin >> test_count;
	for (int test = 1; test <= test_count; ++test) {
		solve();
	}

#ifdef LOCAL
	auto end_time = clock();
	cerr << "Execution time: " << (end_time - start_time) * (int)1e3 / CLOCKS_PER_SEC << " ms\n";
#endif
}


// Created by Nikolay Budin

#ifdef DEBUG
#  define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define ff first
#define ss second
#define szof(x) ((int)x.size())
#ifndef LOCAL
#  define cerr __get_ce
#endif

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef unsigned long long ull;

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

int const INF = (int)1e9 + 1e3;
ll const INFL = (ll)1e18 + 1e6;
#ifdef LOCAL
	mt19937 tw(9450189);
#else
	mt19937 tw(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif
uniform_int_distribution<ll> ll_distr;
ll rnd(ll a, ll b) { return ll_distr(tw) % (b - a + 1) + a; }

void solve() {
	int n;
	cin >> n;
	vector<int> color(n);
	for (int& num : color) {
		cin >> num;
	}
	vector<vector<int>> graph(n);
	for (int i = 0; i < n - 1; ++i) {
		int a, b;
		cin >> a >> b;
		--a; --b;
		graph[a].push_back(b);
		graph[b].push_back(a);
	}

	int ans = INF;

	for (int qwe = 0; qwe < 2; ++qwe) {
		vector<int> sz(n);
		function<vector<int>(int, int)> dfs = [&](int v, int p) {
			vector<int> dp;
			if (color[v] == 1 || color[v] == 0) {
				dp = {1};
			} else {
				dp = {INF, 2};
			}
			sz[v] = 1;
			for (int to : graph[v]) {
				if (to != p) {
					vector<int> tmp = dfs(to, v);
					sz[v] += sz[to];
					vector<int> next_dp(sz[v] + 2, INF);
					for (int i = 0; i < szof(next_dp); ++i) {
						int dp_val = INF;
						if (i < szof(dp)) {
							dp_val = dp[i];
						} else {
							if ((color[v] == 1 || color[v] == 0) && i % 2 == 0) {
								dp_val = i + 1;
							}
							if ((color[v] == 2 || color[v] == 0) && i % 2 == 1) {
								dp_val = i + 1;
							}
						}
						for (int j = 0; j < szof(tmp); ++j) {
							next_dp[i] = min(next_dp[i], dp_val + tmp[j] - min(i, j) - 1);
						}
					}
					swap(next_dp, dp);
				}
			}
			return dp;
		};

		auto dp = dfs(0, 0);
		ans = min(ans, *min_element(dp.begin(), dp.end()));

		for (int& num : color) {
			if (num == 1) {
				num = 2;
			} else if (num == 2) {
				num = 1;
			}
		}
	}

	cout << ans << "\n";
}

int main() {
#ifdef LOCAL
	auto start_time = clock();
	cerr << setprecision(3) << fixed;
#endif
	cout << setprecision(15) << fixed;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int test_count = 1;
	cin >> test_count;
	for (int test = 1; test <= test_count; ++test) {
		solve();
	}

#ifdef LOCAL
	auto end_time = clock();
	cerr << "Execution time: " << (end_time - start_time) * (int)1e3 / CLOCKS_PER_SEC << " ms\n";
#endif
}


// Created by Nikolay Budin

#ifdef DEBUG
#  define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define ff first
#define ss second
#define szof(x) ((int)x.size())
#ifndef LOCAL
#  define cerr __get_ce
#endif

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef unsigned long long ull;

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

int const INF = (int)1e9 + 1e3;
ll const INFL = (ll)1e18 + 1e6;
#ifdef LOCAL
	mt19937 tw(9450189);
#else
	mt19937 tw(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif
uniform_int_distribution<ll> ll_distr;
ll rnd(ll a, ll b) { return ll_distr(tw) % (b - a + 1) + a; }

void solve() {
	int n;
	cin >> n;
	vector<int> color(n);
	for (int& num : color) {
		cin >> num;
	}
	vector<vector<int>> graph(n);
	for (int i = 0; i < n - 1; ++i) {
		int a, b;
		cin >> a >> b;
		--a; --b;
		graph[a].push_back(b);
		graph[b].push_back(a);
	}

	int ans = INF;

	int cnt1 = 0, cnt2 = 0;
	{
		vector<bool> used(n);
		function<void(int)> dfs = [&](int v) {
			used[v] = true;
			for (int to : graph[v]) {
				if (color[to] == color[v] && !used[to]) {
					dfs(to);
				}
			}
		};
		for (int i = 0; i < n; ++i) {
			if (!used[i]) {
				dfs(i);
				if (color[i] == 1) {
					++cnt1;
				}
				if (color[i] == 2) {
					++cnt2;
				}

			}
		}
	}

	ans = min(ans, 1 + cnt2);
	ans = min(ans, 1 + cnt1);

	for (int qwe = 0; qwe < 2; ++qwe) {
		vector<int> sz(n);
		const int MAXSZ = 10000;
		vector<vector<int>> dp(n, vector<int>(MAXSZ, INF));
		vector<int> next_dp(MAXSZ, INF);
		function<void(int, int)> dfs = [&](int v, int p) {
			// vector<int> dp;
			if (color[v] == 1 || color[v] == 0) {
				dp[v][0] = 1;
				dp[v][2] = 3;
			} else {
				// dp = {INF, 2};
				dp[v][1] = 2;
			}
			sz[v] = 1;
			for (int to : graph[v]) {
				if (to != p) {
					dfs(to, v);
					int mem_sz = sz[v] + 2;
					sz[v] += sz[to];
					// vector<int> next_dp(min(MAXSZ, sz[v] + 2), INF);
					int tmp_sz = min(MAXSZ, sz[v] + 2);
					for (int i = 0; i < tmp_sz; ++i) {
						int dp_val = INF;
						if (i < mem_sz) {
							dp_val = dp[v][i];
						} else {
							if ((color[v] == 1 || color[v] == 0) && i % 2 == 0) {
								dp_val = i + 1;
							}
							if ((color[v] == 2 || color[v] == 0) && i % 2 == 1) {
								dp_val = i + 1;
							}
						}
						for (int j = 0; j < sz[to] + 2 && j < MAXSZ; ++j) {
							next_dp[i] = min(next_dp[i], dp_val + dp[to][j] - min(i, j) - 1);
						}
					}
					swap(next_dp, dp[v]);
					fill(next_dp.begin(), next_dp.begin() + min(MAXSZ, mem_sz), INF);
				}
			}
			// return dp;
		};

		dfs(0, 0);
		ans = min(ans, *min_element(dp[0].begin(), dp[0].end()));

		for (int& num : color) {
			if (num == 1) {
				num = 2;
			} else if (num == 2) {
				num = 1;
			}
		}
	}

	cout << ans << "\n";
}

int main() {
#ifdef LOCAL
	auto start_time = clock();
	cerr << setprecision(3) << fixed;
#endif
	cout << setprecision(15) << fixed;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int test_count = 1;
	cin >> test_count;
	for (int test = 1; test <= test_count; ++test) {
		solve();
	}

#ifdef LOCAL
	auto end_time = clock();
	cerr << "Execution time: " << (end_time - start_time) * (int)1e3 / CLOCKS_PER_SEC << " ms\n";
#endif
}


#define _CRT_SECURE_NO_WARNINGS
#include "bits/stdc++.h"

using namespace std;
typedef long long ll;
typedef double db;
typedef vector<string> VS;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VLL;
typedef vector<VLL> VVLL;
typedef vector<VVLL> VVVLL;
typedef pair<ll,ll> PLL;
typedef map<ll,ll> MLL;
typedef set<ll> SLL;
typedef queue<ll> QLL;

#define rep(x,l,u) for(ll x = l; x < u; x++)
#define rrep(x,l,u) for(ll x = l; x >= u; x--)
#define fe(x,a) for (auto x : a)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define mst(x,v) memset(x, v, sizeof(x))
#define sz(x) (ll)x.size()
#define lg(x) (ll)x.length()
#define fi first
#define se second
#define pb push_back

#define umap unordered_map
#define uset unordered_set
#define mset multiset
#define pqueue priority_queue

struct FASTINPUT {
	void f(string & s) { char buf[400005]; ll a = scanf("%s", buf); a++; s = buf; }
	void f(ll & x) { ll a = scanf("%lld", &x); a++; }
	void f(int & x) { ll a = scanf("%d", &x); a++; }
	void f(double & x) { ll a = scanf("%lf", &x); a++; }
	template <typename A, typename B> void f(pair<A,B> & p) { f(p.first); f(p.second); }
	template <typename A> void f(vector<A> & x) { for (auto & y : x) f(y); }

	void read() {}
	template <typename Head, typename... Tail> void read(Head & H, Tail & ... T) { f(H); read(T...); }
};

struct FASTOUTPUT {
	void f(string s) { printf("%s", s.c_str()); }
	void f(ll x) { printf("%lld", x); }
	void f(int x) { printf("%d", x); }
	void f(double x) { printf("%.20f", x); }
	void f(char x) { printf("%c", x); }
	void f(const char* a) { printf("%s", a); }
	template <typename A> void f(vector<A> & x) { for (auto & y : x) { f(y); f(" ");}  }

	void print() {}
	template <typename Head, typename... Tail> void print(Head H, Tail ... T) { f(H); print(T...); }
};

struct DEBUG {
	string open = "[", close = "]", sep = ", ";

	string f(string s) { return s; }
	string f(char c) { return string(1, c); }
	string f(int x) { return to_string(x); }
	string f(ll x) { return to_string(x); }
	string f(db x) { return to_string(x); }
	string f(const char* a) { return a; }
	template <typename A, typename B> string f(pair<A,B> p) { return open + f(p.first) + sep + f(p.second) + close; }
	template <typename A> string f(A v) { string s = open; for (auto a : v) { if (s != open) { s += sep; } s += f(a); } s += close; return s; }

	void show() {cout << endl;}
	template <typename Head, typename... Tail> void show(Head H, Tail... T) { cout << " " << f(H); show(T...); }
};

#define fin(...) do { FASTINPUT inp; inp.read(__VA_ARGS__); } while (false)
#define fout(...) do { FASTOUTPUT out; out.print(__VA_ARGS__); } while (false)
#define debug(...) do { DEBUG deb; cout << "[" << #__VA_ARGS__ << "]:", deb.show(__VA_ARGS__); } while (false)

VLL di = {0,0,1,-1,1,-1,1,-1};
VLL dj = {1,-1,0,0,-1,-1,1,1};
ll ob(ll i, ll n) { return i < 0 || i >= n; } // out of bounds
ll tp(ll x) { return (1LL<<x); }
ll roundup(ll a, ll b) { return a % b ? a/b + 1 : a/b; }
template <typename A, typename B> ll exist(A a, B b) { return a.find(b) != a.end(); }
vector<string> ssplit(string s) { vector<string> ans; stringstream ss; ss << s; while (ss >> s) ans.pb(s); return ans; }
void makemod(ll & x, ll m) { x %= m; x += m; x %= m; }
ll powmod(ll a, ll b, ll m) { if (b == 0) return 1;	ll h = powmod(a, b/2, m); ll ans = h*h%m; return b%2 ? ans*a%m : ans; }
bool isvowel(char ch) { return (ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u'); }
ll sign(ll x) {	return x > 0 ? 1 : x < 0 ? -1 : 0; }

void upmin(ll & x, ll v) { x = min(x, v); }
void upmax(ll & x, ll v) { x = max(x, v); }

const VLL mods = {(ll)1e9 + 7, 998244353, (ll)1e6 + 3, (ll)1e18 + 5};
const ll mod = mods[0];
const ll inf = mods[3];
const db eps = 1e-10;
const db pi = acos(0) * 2;
const string nl = "\n";

void dfs(ll at, ll color, ll k, VVLL & E, VLL & vis) {
	if (vis[at]) return;
	vis[at] = color;
	fe(to, E[at]) {
		dfs(to, color, k, E, vis);
	}
}

void solve() {
	ll n, k = 20;
	string a, b;
	fin(n, a, b);

	VVLL E(k);

	// count number of unique c->d transforms.
	// 26 x 26 adj matrix.
	// if there is a->b, b->z, a->z, that can become 2 transforms
	VLL reach(k);
	rep(i,0,n) {
		ll x = a[i] - 'a', y = b[i] - 'a';
		reach[x] |= tp(y);
		E[x].pb(y);
		E[y].pb(x);
	}

	// each component is solved - find the largest directed acyclic graph
	VLL dp(tp(k));
	dp[0] = 1; // the set of nothing is acyclic
	ll ans = 0;
	rep(i,0,tp(k)) {
		if (dp[i]) {
			upmax(ans, __builtin_popcount(i));
		}

		rep(j,0,k) {
			// going to fill in spot j
			if (tp(j) & i) continue;
			if ((reach[j] & i) == 0) dp[tp(j) | i] |= dp[i];
		}
	}

	VLL vis(k);
	ll color = 0;
	rep(i,0,k) {
		if (vis[i] == 0) dfs(i, ++color, k, E, vis);
	}

	fout(2 * k - color - ans, nl);
}

signed main() {
	ll t = 1;
	fin(t);
	rep(i,0,t) solve();
	return 0;
}


#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn = 1e5+10;
char A[maxn],B[maxn];
int f[30],to[30];
int findx(int x){
    return f[x]==x?x:f[x]=findx(f[x]);
}
void unite(int x,int y){
    x = findx(x);
    y = findx(y);
    if(x==y) return ;
    f[x]=y;
}
bool dp[1<<21];
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n;
        scanf("%d",&n);
        scanf("%s%s",A+1,B+1);
        for(int i=0;i<20;i++) f[i]=i,to[i]=0;
        for(int i=1;i<=n;i++){
            int x = A[i]-'a', y = B[i]-'a';
            to[x]|=(1<<y);
            unite(x,y);
        }
        int ans = 40;
        for(int i=0;i<20;i++) if(findx(i)==i) ans--;
        memset(dp,false,sizeof(dp));
        dp[0]=true;
        int maxs = 0;
        for(int s=0;s<(1<<20);s++){
            if(!dp[s]) continue;
            int cur = 0;
            for(int i=0;i<20;i++){
            	int tmp = 1<<i;
            	if(tmp&s) cur++;
                if(to[i]&s) continue;
                dp[s|tmp]=true;
            }
            maxs=max(maxs,cur);
        }
        printf("%d\n",ans-maxs);
    }
    return 0;
}

/*
2
4
cabc
abcb
 */


#include <cassert>
#undef assert

#include <algorithm>
#include <set>
#include <array>
#include <bitset>
#include <iostream>
#include <tuple>
#include <utility>
#include <vector>

#define STRING_IMPL(...) #__VA_ARGS__
#define STRING(...) STRING_IMPL(__VA_ARGS__)

#ifdef DEBUG
#include <execinfo.h>

#define debug(...) debug_impl("[" __FILE__ ":" STRING(__LINE__) "] " #__VA_ARGS__ " = ", __VA_ARGS__)
#define optimize(...) do { assert(__VA_ARGS__); } while (0)
#define assert(...) void(static_cast<bool>(__VA_ARGS__) ? void() : assert_failed(__FILE__, __LINE__, #__VA_ARGS__))

void print_backtrace() {
	void *array[50];

	auto const size = backtrace(array, 50);
	auto messages = backtrace_symbols(array, size);

	for (int i = 1; i < size && messages != NULL; ++i)
		std::cerr << "[bt]: (" << i << ") " << messages[i] << '\n';

	free(messages);
}

void assert_failed(char const file[], size_t line, char const cond[]) {
	std::cerr << file << ':' << line << ": assert(" << cond << ") failed.\n";
	print_backtrace();
	exit(EXIT_FAILURE);
}
#else
#define debug(...) void()
#define optimize(...) do { if (!(__VA_ARGS__)) __builtin_unreachable(); } while (0)
#define assert(...) void()
#endif

template <class... T>
void debug_impl(char const s[], T&&... vals) {
	std::cerr << s;
	std::size_t n{0};
	((std::cerr << std::forward<T>(vals) << (++n != sizeof...(vals) ? ", " : "")), ...);
	std::cerr << '\n';
}

template <typename... Ts>
std::ostream& operator<<(std::ostream &os, std::tuple<Ts...> const &theTuple) {
	os << '(';
	std::apply([&os](Ts const&... tupleArgs) {
			std::size_t n{0};
			((os << tupleArgs << (++n != sizeof...(Ts) ? ", " : "")), ...);
		}, theTuple);
	return os << ')';
}

template <class T>
void print_iters(std::ostream &os, T begin, T end) {
	if (begin != end)
		for (;;) {
			os << *begin;
			if (++begin == end) break;
			os << ", ";
		}
}

template <class T, class A>
auto& operator<<(std::ostream &os, std::vector<T, A> const &c) {
	os << '[';
	print_iters(os, begin(c), end(c));
	return os << ']';
}

template <class T, size_t N>
auto& operator<<(std::ostream &os, std::array<T, N> const &c) {
	os << '[';
	print_iters(os, begin(c), end(c));
	return os << ']';
}

template <class T, class C, class A>
auto& operator<<(std::ostream &os, std::set<T, C, A> const &c) {
	os << '{';
	print_iters(os, begin(c), end(c));
	return os << '}';
}

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

auto& operator<<(std::ostream &os, uint8_t i) { return os << unsigned(i); }
auto& operator<<(std::ostream &os,  int8_t i) { return os << int(i);      }

template <class T, class A>
auto& operator>>(std::istream &is, std::vector<T, A> &v) {
	for (auto &x : v) is >> x;
	return is;
}

template <class T, size_t N>
auto& operator>>(std::istream &is, std::array<T, N> &a) {
	for (auto &x : a) is >> x;
	return is;
}

template <class T, class U>
auto& operator>>(std::istream &is, std::pair<T, U> &p) {
	return is >> p.first >> p.second;
}

template <class T, class... Args>
T read(Args&&... args) {
	T val(std::forward<Args>(args)...);
	std::cin >> val;
	assert(std::cin.good());
	return val;
}

/* * * * * * * * * * * * * * * *\
 * Solution by Casarin Filippo *
 * Date: 24-07-2020            *
\* * * * * * * * * * * * * * * */

constexpr size_t S = 20;

int32_t solve(std::string const &A, std::string const &B) {
	std::array<std::bitset<S>, S> pair_original {};
	std::bitset<S> Lgen;

	for (size_t i = 0; i < size(A); ++i)
		if (A[i] != B[i]) {
			Lgen.set(A[i] - 'a');
			Lgen.set(B[i] - 'a');
			pair_original[A[i] - 'a'].set(B[i] - 'a');
		}

	uint32_t sol = S * S;
	std::vector<size_t> L;

	for (size_t i = 0; i < S; ++i)
		if (Lgen.test(i))
			L.push_back(i);

	debug(L);

	do {
		uint32_t cnt = 0;
		auto pair = pair_original;

		for (size_t i = 0; i+1 < size(L); ++i) {
			pair[L[i]].reset(L[i]);
			cnt += pair[L[i]].any();
			pair[L[i+1]] |= pair[L[i]];
		}

		pair[L.back()].reset(L.back());
		cnt += pair[L.back()].count();

		sol = std::min(sol, cnt);
	} while (next_permutation(begin(L), end(L)));

	return sol;
}

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

	auto T = read<uint32_t>();
	while (T--) {
		auto const N = read<size_t>();
		auto const A = read<std::string>();
		auto const B = read<std::string>();
		assert(size(A) == N && size(B) == N);
		std::cout << solve(A, B) << '\n';
	}
}


#include <cassert>
#undef assert

#include <algorithm>
#include <set>
#include <array>
#include <bitset>
#include <iostream>
#include <tuple>
#include <utility>
#include <vector>

#define STRING_IMPL(...) #__VA_ARGS__
#define STRING(...) STRING_IMPL(__VA_ARGS__)

#ifdef DEBUG
#include <execinfo.h>

#define debug(...) debug_impl("[" __FILE__ ":" STRING(__LINE__) "] " #__VA_ARGS__ " = ", __VA_ARGS__)
#define optimize(...) do { assert(__VA_ARGS__); } while (0)
#define assert(...) void(static_cast<bool>(__VA_ARGS__) ? void() : assert_failed(__FILE__, __LINE__, #__VA_ARGS__))

void print_backtrace() {
	void *array[50];

	auto const size = backtrace(array, 50);
	auto messages = backtrace_symbols(array, size);

	for (int i = 1; i < size && messages != NULL; ++i)
		std::cerr << "[bt]: (" << i << ") " << messages[i] << '\n';

	free(messages);
}

void assert_failed(char const file[], size_t line, char const cond[]) {
	std::cerr << file << ':' << line << ": assert(" << cond << ") failed.\n";
	print_backtrace();
	exit(EXIT_FAILURE);
}
#else
#define debug(...) void()
#define optimize(...) do { if (!(__VA_ARGS__)) __builtin_unreachable(); } while (0)
#define assert(...) void()
#endif

template <class... T>
void debug_impl(char const s[], T&&... vals) {
	std::cerr << s;
	std::size_t n{0};
	((std::cerr << std::forward<T>(vals) << (++n != sizeof...(vals) ? ", " : "")), ...);
	std::cerr << '\n';
}

template <typename... Ts>
std::ostream& operator<<(std::ostream &os, std::tuple<Ts...> const &theTuple) {
	os << '(';
	std::apply([&os](Ts const&... tupleArgs) {
			std::size_t n{0};
			((os << tupleArgs << (++n != sizeof...(Ts) ? ", " : "")), ...);
		}, theTuple);
	return os << ')';
}

template <class T>
void print_iters(std::ostream &os, T begin, T end) {
	if (begin != end)
		for (;;) {
			os << *begin;
			if (++begin == end) break;
			os << ", ";
		}
}

template <class T, class A>
auto& operator<<(std::ostream &os, std::vector<T, A> const &c) {
	os << '[';
	print_iters(os, begin(c), end(c));
	return os << ']';
}

template <class T, size_t N>
auto& operator<<(std::ostream &os, std::array<T, N> const &c) {
	os << '[';
	print_iters(os, begin(c), end(c));
	return os << ']';
}

template <class T, class C, class A>
auto& operator<<(std::ostream &os, std::set<T, C, A> const &c) {
	os << '{';
	print_iters(os, begin(c), end(c));
	return os << '}';
}

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

auto& operator<<(std::ostream &os, uint8_t i) { return os << unsigned(i); }
auto& operator<<(std::ostream &os,  int8_t i) { return os << int(i);      }

template <class T, class A>
auto& operator>>(std::istream &is, std::vector<T, A> &v) {
	for (auto &x : v) is >> x;
	return is;
}

template <class T, size_t N>
auto& operator>>(std::istream &is, std::array<T, N> &a) {
	for (auto &x : a) is >> x;
	return is;
}

template <class T, class U>
auto& operator>>(std::istream &is, std::pair<T, U> &p) {
	return is >> p.first >> p.second;
}

template <class T, class... Args>
T read(Args&&... args) {
	T val(std::forward<Args>(args)...);
	std::cin >> val;
	assert(std::cin.good());
	return val;
}

/* * * * * * * * * * * * * * * *\
 * Solution by Casarin Filippo *
 * Date: 24-07-2020            *
\* * * * * * * * * * * * * * * */

constexpr size_t S = 20;

int32_t solve(std::string const &A, std::string const &B) {
	std::array<std::bitset<S>, S> pair_original {};
	std::vector<size_t> L;

	for (size_t i = 0; i < size(A); ++i)
		if (A[i] != B[i]) {
			L.push_back(A[i] - 'a');
			L.push_back(B[i] - 'a');
			pair_original[A[i] - 'a'].set(B[i] - 'a');
		}

	uint32_t sol = S * S;
	sort(begin(L), end(L));
	L.erase(unique(begin(L), end(L)), end(L));

	debug(L);

	do {
		uint32_t cnt = 0;
		auto pair = pair_original;

		for (size_t i = 0; i+1 < size(L); ++i) {
			pair[L[i]].reset(L[i]);
			cnt += pair[L[i]].any();
			pair[L[i+1]] |= pair[L[i]];
		}

		pair[L.back()].reset(L.back());
		cnt += pair[L.back()].count();

		sol = std::min(sol, cnt);
	} while (next_permutation(begin(L), end(L)));

	return sol;
}

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

	auto T = read<uint32_t>();
	while (T--) {
		auto const N = read<size_t>();
		auto const A = read<std::string>();
		auto const B = read<std::string>();
		assert(size(A) == N && size(B) == N);
		std::cout << solve(A, B) << '\n';
	}
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<algorithm>
#include<cstring>

using namespace std;
typedef long long ll;
typedef pair<int, int> pnt;
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define sz(a) ((int)(a).size())

ll a[100];
ll b[100];
ll ans[100];

int main() {
	#ifdef home
    	freopen("a.in", "r", stdin);
	    freopen("a.out", "w", stdout);
	#endif
	int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < n; i++) {
    	int x;
    	scanf("%d", &x);
    	int cnt = 0;
    	while (x > 0) {
    		if (x % 2 == 1) {
    			a[cnt]++;
    		}
    		x /= 2;
    		cnt++;
    	}
    }
    ll Ans = 0;
    for (int i = 0; i < m; i++) {
    	int x;
    	scanf("%d", &x);
    	b[x]++;
    }
    ll tk = 0;
    for (int i = 60; i >= 0; i--) {
    	tk = tk * 2 + a[i];
    	ll dd = min(tk, b[i]);
    	ans[i] += dd;
    	tk -= dd;
    	b[i] -= dd;
    	Ans += dd;
    }
    for (int i = 60; i >= 0; i--) {
    	if (ans[i] > 0) {
    		ll sum = 0;
    		for (int j = 0; j < i; j++) {
    			sum += b[j];
    		}
    		if (sum > 1) {
    			ans[i]--;
    			Ans--;
    			tk = 1;
    			for (int j = i - 1; j >= 0; j--) {
    				tk = tk * 2;
			    	ll dd = min(tk, b[j]);
			    	ans[j] += dd;
			    	tk -= dd;
			    	b[j] -= dd;
			    	Ans += dd;
    			}
    		}
    	}
    }
    cout<<Ans<<endl;
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <map>

using namespace std;

#define pb push_back
#define mp make_pair
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define sz(x) ((int)(x).size())

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

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

  int n, m;
  while (scanf("%d%d", &n, &m) >= 1) {
    vi bs(m);
    multiset<int> as;
    for (int i = 0; i < n; i++) {
      int x;
      scanf("%d", &x);
      as.insert(x);
    }
    for (int i = 0; i < m; i++)
      scanf("%d", &bs[i]), bs[i] = 1 << bs[i];
    sort(bs.begin(), bs.end());
    reverse(bs.begin(), bs.end());

    int ans = 0;
    for (int i = 0; i < sz(bs); i++) {
      multiset<int>::iterator it = as.lower_bound(bs[i]);
      if (it == as.end()) continue;
      ans++;
      as.erase(it);
    }
    printf("%d\n", ans);
  }
  return 0;
}


#include <cassert>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <ctime>

using namespace std;

template <typename T> T sqr(T x) { return x * x; }
template <typename T> T gcd(T a, T b) { return b == 0? a : gcd(b, a % b); }
template <typename T> T abs(T x) { return x < 0? -x : x; }

const int MAXK = 31;

int f[MAXK];
int g[MAXK];
int ans;
int n, m;

int main()
{
	#ifdef MJUDGE
		assert(freopen("in", "r", stdin));
		assert(freopen("out", "w", stdout));
	#endif

	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++)
	{
		int x;
		scanf("%d", &x);
		for (int j = 0; j < MAXK; j++)
			if ((1 << j) & x)
				f[j] += 1;
	}
	for (int i = 0; i < m; i++)
	{
		int x;
		scanf("%d", &x);
		if (x >= MAXK)
			continue;
		g[x] += 1;
	}

	ans = 0;
	for (int i = 0; i < MAXK; i++)
		for (int j = 0; j <= i; j++)
		{
			long long x = min(f[i] * (long long)(1 << (i - j)), (long long)g[j]);
			if (x == 0)
				continue;
			ans += x;
			g[j] -= x;
			long long m = (x + (1 << (i - j)) - 1) / (1 << (i - j));
			f[i] -= m;
			x = (m * (1 << (i - j)) - x) << j;
			//cout << i << " " << j << " " << m << " " << x << endl;
			for (int z = 0; z < MAXK; z++)
				if ((1 << z) & x)
					f[z] += 1;
		}
	printf("%d\n", ans);
	fprintf(stderr, "Time execute: %.3lfs\n", clock() / (double)CLOCKS_PER_SEC);
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/STACK:128000000")
#define _USE_MATH_DEFINES
#include<iostream>
#include<vector>
#include<string>
#include<stack>
#include<algorithm>
#include<cmath>
#include<set>
#include<queue>
#include<sstream>
#include<utility>
#include<map>
#include<ctime>
#include<cstdio>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
const long double PI = 3.14159265358979323846;
const long double gammama = 0.57721566490153286060;
//const long double eps = 1e-5;
//const int INF = 50000;
//const int N = 1000 * 1000 * 1000 + 10;

ll up(ll a, ll b) {
    ll q = a / b;
    if (a % b != 0)
        ++q;
    return q;
}

vector<int> c(30, 0);
void add(ll a) {
    int ind = 0;
    while(a) {
        if (a & 1)
            ++c[ind];
        ++ind;
        a /= 2;
    }
}

int main() {
	//ios_base::sync_with_stdio(0);
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
    int n, r, c;
    cin >> n >> r >> c;
    vector<string> words(n);
    vector<int> sum(n);
    for (int i = 0; i < n; ++i) {
        cin >> words[i];
        sum[i] = words[i].size();
        if (i)
            sum[i] += sum[i - 1];
    }
    vector<int> d(n, -1);
    int cur = 0;
    for (int i = 0; i < n; ++i) {
        if (words[i].size() > c)
            continue;
        int j = i;
        if (i)
            j = max(j, d[i - 1]);
        cur = sum[j];
        if (i)
            cur -= sum[i - 1];
        cur += j - i;
        while(j + 1 < n) {
            if (cur + words[j + 1].size() + 1 <= c)
                ++j;
            else
                break;
        }
        d[i] = j;
    }
    vector<int> a(n);
    for (int i = n - 1; i >= 0; --i) {
        if (d[i] ==
    }
    return 0;
}


#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <bitset>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define li		long long
#define rep(i,to)	for(li i=0;i<((li)to);i++)
#define pb		push_back
#define sz(v)		((li)v.size())

li gcd(li a,li b){
	if(a%b==0) return b;
	return gcd(b,a%b);
}
int main(){
	li n;
	cin>>n;
	if(n>50) while(true);
	if(n>10){	vector<int> v; while(true) v.pb(1); }
	li res=1;
	li cnt=0;
	li add=0;
	while(n%2==0) add++,n/=2;
	while(res<n) cnt++,res*=2;
	li child=cnt*res;
	li tmp=gcd(child,n);
	child/=tmp;
	n/=tmp;
	child+=add*n;
	cout<<child<<"/"<<n<<endl;
}


//98B long-arithmetic Hewr
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define fo(i,a,b) for (int i = a; i <= b; ++i)
#define fd(i,a,b) for (int i = a; i >= b; --i)
#define fe(i,x) for (int i = g[x], y = E[i].y; i; i = E[i].l, y = E[i].y)
#define forall(i, x) for (typeof((x).begin()) i = (x).begin(); i != (x).end(); ++i)
#define pb push_back
#define SIZE(x) ((int) (x).size())
#define MP make_pair
#define fi first
#define se second
#define UNIQUE(x) x.resize(unique(x.begin(), x.end()) - x.begin())
#define clr(a,x) memset(&a, x, sizeof(a))
#define move(a,b) memcpy(&b, &a, sizeof(a))
#define Plus(a,b) (((LL) (a) + (b)) % mo)
#define Minus(a,b) ((((LL) (a) - (b) ) % mo + mo) % mo)
#define Mul(a,b) ((LL) (a) * (b) % mo)
#define updmin(a,b) (a = min(a, b))
#define updmax(a,b) (a = max(a, b))
#define sqr(x) ((x) * (x))

typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
typedef vector<int> VI;

const double eps = 1e-10;
const int oo = ~0u >> 2, mo = (int) 1e4;
const int ml = 100, mn = 11000;

struct high{
    int n, a[ml];
    high(){ clr(a, 0), n = 1; }
    high(int x){
        clr(a, 0), n = 0;
        do { a[++n] = x % mo, x /= mo; } while (x);
    }

    void cut(){
        while (n > 1 && !a[n]) --n;
    }

    int cmp(high p){
        if (n > p.n) return 1;
        if (n < p.n) return -1;
        fd (i, n, 1) if (a[i] > p.a[i]) return 1;
        else if (a[i] < p.a[i]) return -1;
        return 0;
    }
    void div2(){
        int g = 0;
        fd (i, n, 1) g = g * mo + a[i], a[i] = g / 2, g %= 2;
        cut();
    }
    high operator +(high p){
        high ret = *(new high());
        int g = 0; ret.n = max(n, p.n) + 1;
        fo (i, 1, ret.n) g += a[i] + p.a[i], ret.a[i] = g % mo, g /= mo;
        ret.cut();
        return ret;
    }
    high operator -(high p){
        high ret = *(new high());
        int g = 0; ret.n = n;
        fo (i, 1, ret.n){
            ret.a[i] = g + a[i] - p.a[i];
            if (ret.a[i] < 0) g = -1, ret.a[i] += mo; else g = 0;
        }
        ret.cut();
        return ret;
    }
    high operator *(high p){
        high ret = *(new high());
        ret.n = n + p.n + 1;
        fo (i, 1, n){
            int g = 0;
            fo (j, 1, p.n + 1){
                LL s = (LL) a[i] * p.a[j] + ret.a[i + j - 1] + g;
                ret.a[i + j - 1] = s % mo, g = s / mo;
            }
        }
        ret.cut();
        return ret;
    }
    high operator /(high p){
        high d = *(new high()), R = *(new high());
        d.n = n;
        fd (i, n, 1){
            R = R * *(new high(mo)) + *(new high(a[i]));
            int l = 0, r = mo - 1;
            while (l <= r){
                int m = (l + r) / 2;
                high t = p * *(new high(m));
                int c = R.cmp(t);
                if (!c){
                    d.a[i] = m;
                    break;
                }
                if (c > 0) d.a[i] = m, l = m + 1;
                else r = m - 1;
            }
            R = R - p * *(new high(d.a[i]));
        }
        d.cut();
        return d;
    }
    high operator %(high p){
        high R = *(new high());
        fd (i, n, 1){
            R = R * *(new high(mo)) + *(new high(a[i]));
            int l = 0, r = mo - 1, d;
            while (l <= r){
                int m = (l + r) / 2;
                high t = p * *(new high(m));
                int c = R.cmp(t);
                if (!c){
                    d = m;
                    break;
                }
                if (c > 0) d = m, l = m + 1;
                else r = m - 1;
            }
            R = R - p * *(new high(d));
        }
        R.cut();
        return R;
    }

    void print(){
        printf("%d", a[n]);
        fd (i, n - 1, 1) printf("%04d", a[i]);
    }
};

high GCD(high a, high b){
    high two = *(new high(1));
    while (b.n > 1 || b.a[1]){
        while (!(a.a[1] & 1) && !(b.a[1] & 1))
            a.div2(), b.div2(), two = two + two;
        while (!(a.a[1] & 1)) a.div2();
        while (!(b.a[1] & 1)) b.div2();
        if (a.cmp(b) > 0) swap(a, b);
        b = b - a;
    }
    two = two * a;
    return two;
}

high LCM(high a, high b){
    high t = GCD(a, b);
    return a / t * b;
}

struct rec{
    high a, b;
    rec(){ a = *(new high(0)), b = *(new high(1)); }
    rec(int x){ a = *(new high(x)), b = *(new high(1)); }
    rec(int x, int y){ a = *(new high(x)), b = *(new high(y)); }

    void simplify(){
        high t = GCD(a, b);
        a = a / t, b = b / t;
    }

    rec operator +(rec p){
        rec ret;
        ret.b = LCM(b, p.b);
        ret.a = a * (ret.b / b) + p.a * (ret.b / p.b);
        ret.simplify();
        return ret;
    }
    rec operator -(rec p){
        rec ret;
        ret.b = LCM(b, p.b);
        ret.a = a * (ret.b / b) - p.a * (ret.b / p.b);
        ret.simplify();
        return ret;
    }
    rec operator *(rec p){
        rec ret;
        ret.a = a * p.a, ret.b = b * p.b;
        ret.simplify();
        return ret;
    }
    rec operator /(rec p){
        rec ret;
        ret.a = a * p.b, ret.b = b * p.a;
        ret.simplify();
        return ret;
    }
} k, b, Ans;

struct mem{
    rec k, b;
    bool flag;
} f[mn];

int n, m;

int main(){
    cin >> n;
    if (n == 1){
        printf("0/1");
        return 0;
    }
    m = 1, k = *(new rec(1)), b = *(new rec(0));
    do {
        f[m].k = k, f[m].b = b, f[m].flag = 1;
        m *= 2;
        if (m == n){
            Ans = b + *(new rec(1));
            break;
        } else
        if (m < n){
            b = b + k;
        } else {
            rec t = *(new rec(m - n, m));
            m -= n, b = b + k, k = k * t;
        }
        if (f[m].flag){
            rec t1 = f[m].k - k, t2 = b - f[m].b;
            Ans = t2 / t1;
            Ans = k * Ans + b;
            break;
        }
    } while (n != m);
    Ans.simplify();
    Ans.a.print();
    printf("/");
    Ans.b.print();
    printf("\n");
}


#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <bitset>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define li		long long
#define rep(i,to)	for(li i=0;i<((li)to);i++)
#define pb		push_back
#define sz(v)		((li)v.size())

li gcd(li a,li b){
	if(a%b==0) return b;
	return gcd(b,a%b);
}
int main(){
	li n;
	cin>>n;
	if(n==10) while(true);
	if(n>6){	vector<int> v; while(true) v.pb(1); }
	li res=1;
	li cnt=0;
	li add=0;
	while(n%2==0) add++,n/=2;
	while(res<n) cnt++,res*=2;
	li child=cnt*res;
	li tmp=gcd(child,n);
	child/=tmp;
	n/=tmp;
	child+=add*n;
	cout<<child<<"/"<<n<<endl;
}


//98B long-arithmetic Hewr
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define fo(i,a,b) for (int i = a; i <= b; ++i)
#define fd(i,a,b) for (int i = a; i >= b; --i)
#define fe(i,x) for (int i = g[x], y = E[i].y; i; i = E[i].l, y = E[i].y)
#define forall(i, x) for (typeof((x).begin()) i = (x).begin(); i != (x).end(); ++i)
#define pb push_back
#define SIZE(x) ((int) (x).size())
#define MP make_pair
#define fi first
#define se second
#define UNIQUE(x) x.resize(unique(x.begin(), x.end()) - x.begin())
#define clr(a,x) memset(&a, x, sizeof(a))
#define move(a,b) memcpy(&b, &a, sizeof(a))
#define Plus(a,b) (((LL) (a) + (b)) % mo)
#define Minus(a,b) ((((LL) (a) - (b) ) % mo + mo) % mo)
#define Mul(a,b) ((LL) (a) * (b) % mo)
#define updmin(a,b) (a = min(a, b))
#define updmax(a,b) (a = max(a, b))
#define sqr(x) ((x) * (x))

typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
typedef vector<int> VI;

const double eps = 1e-10;
const int oo = ~0u >> 2, mo = (int) 1e4;
const int ml = 100, mn = 11000;

struct high{
	int n, a[ml];
	high(){ clr(a, 0), n = 1; }
	high(int x){
		clr(a, 0), n = 0;
		do { a[++n] = x % mo, x /= mo; } while (x);
	}
	void init(int x){
		clr(a, 0), n = 0;
		do { a[++n] = x % mo, x /= mo; } while (x);
	}

	void cut(){
		while (n > 1 && !a[n]) --n;
	}

	int cmp(high p){
		if (n > p.n) return 1;
		if (n < p.n) return -1;
		fd (i, n, 1) if (a[i] > p.a[i]) return 1;
		else if (a[i] < p.a[i]) return -1;
		return 0;
	}
	void div2(){
		int g = 0;
		fd (i, n, 1) g = g * mo + a[i], a[i] = g / 2, g %= 2;
		cut();
	}
	high operator +(high p){
		high ret; ret.init(0);
		int g = 0; ret.n = max(n, p.n) + 1;
		fo (i, 1, ret.n) g += a[i] + p.a[i], ret.a[i] = g % mo, g /= mo;
		ret.cut();
		return ret;
	}
	high operator -(high p){
		high ret; ret.init(0);
		int g = 0; ret.n = n;
		fo (i, 1, ret.n){
			ret.a[i] = g + a[i] - p.a[i];
			if (ret.a[i] < 0) g = -1, ret.a[i] += mo; else g = 0;
		}
		ret.cut();
		return ret;
	}
	high operator *(high p){
		high ret; ret.init(0);
		ret.n = n + p.n + 1;
		fo (i, 1, n){
			int g = 0;
			fo (j, 1, p.n + 1){
				LL s = (LL) a[i] * p.a[j] + ret.a[i + j - 1] + g;
				ret.a[i + j - 1] = s % mo, g = s / mo;
			}
		}
		ret.cut();
		return ret;
	}
	high operator /(high p){
		high d, R, tmp; d.init(0), R.init(0);
		d.n = n;
		fd (i, n, 1){
			tmp.init(mo), R = R * tmp;
			tmp.init(a[i]), R = R + tmp;
			int l = 0, r = mo - 1;
			while (l <= r){
				int m = (l + r) / 2;
				tmp.init(m);
				high t = p * tmp;
				int c = R.cmp(t);
				if (!c){
					d.a[i] = m;
					break;
				}
				if (c > 0) d.a[i] = m, l = m + 1;
				else r = m - 1;
			}
			tmp.init(d.a[i]), R = R - p * tmp;
		}
		d.cut();
		return d;
	}
	high operator %(high p){
		high R, tmp; R.init(0);
		fd (i, n, 1){
			tmp.init(mo), R = R * tmp;
			tmp.init(a[i]), R = R + tmp;
			int l = 0, r = mo - 1, d;
			while (l <= r){
				int m = (l + r) / 2;
				tmp.init(m);
				high t = p * tmp;
				int c = R.cmp(t);
				if (!c){
					d = m;
					break;
				}
				if (c > 0) d = m, l = m + 1;
				else r = m - 1;
			}
			tmp.init(d), R = R - p * tmp;
		}
		R.cut();
		return R;
	}

	void print(){
		printf("%d", a[n]);
		fd (i, n - 1, 1) printf("%04d", a[i]);
	}
};

high GCD(high a, high b){
	high two; two.init(1);
	while (b.n > 1 || b.a[1]){
		while (!(a.a[1] & 1) && !(b.a[1] & 1))
			a.div2(), b.div2(), two = two + two;
		while (!(a.a[1] & 1)) a.div2();
		while (!(b.a[1] & 1)) b.div2();
		if (a.cmp(b) > 0) swap(a, b);
		b = b - a;
	}
	two = two * a;
	return two;
}

high LCM(high a, high b){
	high t = GCD(a, b);
	return a / t * b;
}

struct rec{
	high a, b;
	rec(){ a.init(0), b.init(1); }
	rec(int x){ a.init(x), b.init(1); }
	rec(int x, int y){ a.init(x), b.init(y); }

	void simplify(){
		high t = GCD(a, b);
		a = a / t, b = b / t;
	}

	rec operator +(rec p){
		rec ret;
		ret.b = LCM(b, p.b);
		ret.a = a * (ret.b / b) + p.a * (ret.b / p.b);
		ret.simplify();
		return ret;
	}
	rec operator -(rec p){
		rec ret;
		ret.b = LCM(b, p.b);
		ret.a = a * (ret.b / b) - p.a * (ret.b / p.b);
		ret.simplify();
		return ret;
	}
	rec operator *(rec p){
		rec ret;
		ret.a = a * p.a, ret.b = b * p.b;
		ret.simplify();
		return ret;
	}
	rec operator /(rec p){
		rec ret;
		ret.a = a * p.b, ret.b = b * p.a;
		ret.simplify();
		return ret;
	}
} k, b, Ans;

struct mem{
	rec k, b;
	bool flag;
} f[mn];

int n, m;

int main(){
	cin >> n;
	if (n == 1){
		printf("0/1");
		return 0;
	}
	m = 1, k = *(new rec(1)), b = *(new rec(0));
	do {
		f[m].k = k, f[m].b = b, f[m].flag = 1;
		m *= 2;
		if (m == n){
			Ans = b + *(new rec(1));
			break;
		} else
		if (m < n){
			b = b + k;
		} else {
			rec t; t.a.init(m - n), t.b.init(m);
			m -= n, b = b + k, k = k * t;
		}
		if (f[m].flag){
			rec t1 = f[m].k - k, t2 = b - f[m].b;
			Ans = t2 / t1;
			Ans = k * Ans + b;
			break;
		}
	} while (n != m);
	Ans.simplify();
	Ans.a.print();
	printf("/");
	Ans.b.print();
	printf("\n");
}