Language: C++

#include <iostream>
#include <algorithm>
#include <cmath>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <string.h>
#include <stack>
#include <assert.h>
#include <bitset>
#include <self/utility>
#include <self/debug>
#include <vector>
namespace combinatorics
{
	int *fac;
	int *ifac;
	int __Tmod;
	inline int add(int a,int b)
	{
		return (a+b)%__Tmod;
	}
	inline int sub(int a,int b)
	{
		return (a-b+__Tmod)%__Tmod;
	}
	inline int mult(int a,int b)
	{
		return (1LL*a*b)%__Tmod;
	}
	inline ll fastpow(int basic,int x)
	{
		if(x==0) return 1;
		ll res=1;
		while(x)
		{
			if(x&1)	res*=basic;
			basic*=basic;
			x>>=1;
		}
		return res;
	}
	inline int inv(int x)
	{
		return fastpow(x,__Tmod-2);
	}
	void init(int n,int tmod)
	{
		__Tmod=tmod;
		fac=new int[n+5];
		ifac=new int[n+5];
		fac[0]=1;
		for(int i=1;i<=n;i++)
		{
			fac[i]=mult(fac[i-1],i);
		}
		ifac[n]=inv(fac[n]);
		for(int i=n-1;i>=0;i--)
		{
			ifac[i]=mult(ifac[i+1],i+1);
		}
	}
	inline int C(int n,int m)
	{
		return mult(mult(fac[n],ifac[m]),ifac[n-m]);
	}
	inline int Cat(int x)
	{
		return mult(C(x*2,x),inv(x+1));
	}
};
using namespace combinatorics;
using namespace std;
struct Graph
{
	vector <int> *edges;
	int n;
	int m;
	void init(int _n)
	{
		n=_n;
		m=0;
		edges=new vector <int> [n];
	}
	void feedEdges(vector <int> _edges[])
	{
		for(int i=0;i<n;i++)
		{
			edges[i]=_edges[i];
		}
	}
	void addEdge(int x,int y)
	{
		edges[x].push_back(y);
		m++;
	}
};
const int N=50+5;
const int LOGN=10;
namespace getParArraySpace
{
	void dfs(int x,int p,int arr[],Graph &g)
	{
		arr[x]=p;
		for(auto &u:g.edges[x])
		{
			if(u==p) continue;
			dfs(u,x,arr,g);
		}
	}
	void getParArray(Graph &g,int rt,int arr[])
	{
		dfs(rt,-1,arr,g);
	}
};
using getParArraySpace::getParArray;
namespace getDepArraySpace
{
	void dfs(int x,int p,int depth,int arr[],Graph &g)
	{
		arr[x]=depth;
		for(auto &u:g.edges[x])
		{
			if(u==p) continue;
			dfs(u,x,depth+1,arr,g);
		}
	}
	void getDepArray(Graph &g,int rt,int arr[])
	{
		dfs(rt,-1,0,arr,g);
	}
};
using getDepArraySpace::getDepArray;
namespace LCASpace
{
	int depth[N+5];
	int par[LOGN+1][N+5];
	void init(Graph &g)
	{
		getDepArray(g,0,depth);
		getParArray(g,0,par[0]);
		for(int k=0;k<LOGN-1;k++)
		{
			for(int i=0;i<g.n;i++)
			{
				if(par[k][i]==-1)
				{
					par[k+1][i]=-1;
				}
				else
				{
					par[k+1][i]=par[k][par[k][i]];
				}
			}
		}
	}
	int lca(int a,int b)
	{
		if(depth[a]<depth[b]) swap(a,b);
		int t=depth[a]-depth[b];
		for(int i=0;i<LOGN;i++)
		{
			if((t & (1<<i))) a=par[i][a];
		}
		if(a==b) return a;
		for(int i=LOGN-1;i>=0;i--)
		{
			if(par[i][a]!=par[i][b])
			{
				a=par[i][a];
				b=par[i][b];
			}
		}
		return par[0][a];
	}
};
using namespace std;
int n;
Graph g;
int m;
pii q[50];
int la[50];
int s[50];
int en=0;

int dfs(int x,int p)
{
	int ns=s[x];
	for(auto u:g.edges[x])
	{
		if(u==p) continue;
		int t=dfs(u,x);
		if(t>=1) en++;
		ns+=t;
	}
	return ns;
}

ll solve(int mask)
{
	en=0;
	memset(s,0,sizeof(s));
	for(int i=0;i<m;i++)
	{
		if((1<<i) & mask) continue;
		s[q[i].first]++;
		s[q[i].second]++;
		s[la[i]]-=2;
	}
	dfs(0,-1);
	return fastpow(2,n-1-en);
}

int main()
{
//	freopen("input.txt","r",stdin);
	cin>>n;
	g.init(n);
	for(int i=0;i<n-1;i++)
	{
		int x,y;
		cin>>x>>y;
		x--;
		y--;
		g.addEdge(x,y);
	}
	cin>>m;
	for(int i=0;i<m;i++)
	{
		int x,y;
		cin>>x>>y;
		x--;
		y--;
		q[i]=mp(x,y);
	}
	LCASpace::init(g);
	for(int i=0;i<m;i++)
	{
		la[i]=LCASpace::lca(q[i].first,q[i].second);
	}
	ll res=0;
	for(int mask=0;mask<(1<<m);mask++)
	{
		if(__builtin_popcount(mask)&1) res+=solve(mask);else res-=solve(mask);
	}
	cout<<res<<endl;
	return 0;
}

Compiler output:
a.cc:15:10: fatal error: self/utility: No such file or directory
   15 | #include <self/utility>
      |          ^~~~~~~~~~~~~~
compilation terminated.