

/*
有谁知道这道题结论是怎么来的?
晚上问问学数学的孩子23333
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long LL;
LL n,m,d;
LL gcd(LL x,LL y)
{
return x%y?gcd(y,x%y):y;
}
int main()
{
freopen("line.in","r",stdin);
freopen("line.out","w",stdout);
cin>>n>>m;
d=gcd(n,m);
n/=d;
m/=d;
if((n+m)&1)cout<<"1/2"<<endl;
else cout<<(n*m+1)/2<<"/"<<n*m<<endl;
return 0;
}



/*
数据水...
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100007
using namespace std;
int n,m,opt,x,y,z,ans,cnt;
int col[N];
inline int read()
{
int x=0,f=1;char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
inline void solve(int l,int r,int flag)
{
for(int i=l;i<=r;i++) col[i]=flag;
}
inline void find(int x)
{
int L=1,R=n;
if(col[x]==1) printf("0
");
else
{
for(int i=x-1;i>=1;i--) if(col[i]){L=i+1;break;}
for(int i=x+1;i<=n;i++) if(col[i]){R=i-1;break;}
if(L==1 || R==n){printf("INF
");}
else printf("%d
",R-L+1);
}
}
int main()
{
freopen("explore.in","r",stdin);
freopen("explore.out","w",stdout);
n=read();m=read();
for(int i=1;i<=m;i++)
{
opt=read();
if(opt==1)
{
x=read();y=read();
solve(x,y,1);
}
else if(opt==2)
{
x=read();y=read();
solve(x,y,0);
}
else x=read(),find(x);
}
return 0;
}
70暴力
/*
二分+线段树
By LXT 林欣彤
*/
#include<complex>
#include<cstdio>
using namespace std;
const int N=1e5+7;
int n,m;
int Fog[N<<2],lazy[N<<2];
int qread()
{
int x=0;
char ch=getchar();
while(ch<'0' || ch>'9')ch=getchar();
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x;
}
void PushUp(int rt)
{
Fog[rt]=(Fog[rt<<1]==1) || (Fog[rt<<1|1]==1);
}
void PushDown(int rt)
{
if(lazy[rt])
{
Fog[rt<<1]=Fog[rt<<1|1]=lazy[rt];
lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
lazy[rt]=0;
}
}
void Modify(int l,int r,int rt,int nowl,int nowr,int v)
{
if(nowl<=l && r<=nowr)
{
Fog[rt]=lazy[rt]=v;
return;
}
int mid=l+r>>1;
PushDown(rt);
if(nowl<=mid)Modify(l,mid,rt<<1,nowl,nowr,v);
if(mid<nowr)Modify(mid+1,r,rt<<1|1,nowl,nowr,v);
PushUp(rt);
}
int Query(int l,int r,int rt,int nowl,int nowr)
{
if(nowl<=l && r<=nowr)return Fog[rt];
int mid=l+r>>1;
PushDown(rt);
if(nowl<=mid)if(Query(l,mid,rt<<1,nowl,nowr)==1)return 1;
if(mid<nowr)if(Query(mid+1,r,rt<<1|1,nowl,nowr)==1)return 1;
return 2;
}
int main()
{
freopen("explore.in","r",stdin);
freopen("explore.out","w",stdout);
scanf("%d%d",&n,&m);
int p,l,r;
while(m--)
{
p=qread();l=qread();
if(p==3)
{
if(Query(1,n,1,l,l)==1){puts("0");continue;}
int L=1,R=l,res1=l,res2=l;
while(L<=R)
{
int mid=L+R>>1;
if(Query(1,n,1,mid,l)==2)
res1=mid,R=mid-1;
else L=mid+1;
}
L=l;R=n;
while(L<=R)
{
int mid=L+R>>1;
if(Query(1,n,1,l,mid)==2)
res2=mid,L=mid+1;
else R=mid-1;
}
if(res1==1 || res2==n)puts("INF");
else printf("%d
",res2-res1+1);
}
else
{
r=qread();
Modify(1,n,1,l,r,p);
}
}
fclose(stdin);fclose(stdout);
return 0;
}


#include<complex>
#include<cstdio>
#include<iostream>
using namespace std;
const int N=1e5+7;
struct node{
int u,v,w,nxt;
}e[N<<1];
int n,m,Enum,tim,tot;
long long ans=1ll<<60;
int front[N],in[N],b[N],c[N],fat[N],Log[N],Smin[N][18];
bool a[N];
int qread()
{
int x=0;
char ch=getchar();
while(ch<'0' || ch>'9')ch=getchar();
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x;
}
void Insert(int u,int v,int w)
{
e[++Enum].u=u;
e[Enum].v=v;
e[Enum].w=w;
e[Enum].nxt=front[u];
front[u]=Enum;
}
int find(int x)
{
if(fat[x]!=x)fat[x]=find(fat[x]);
return fat[x];
}
void dfs1(int num)
{
if(num==n-1)
{
long long res=0;
for(int i=1;i<n;i++)
res+=b[i]*e[i<<1].w;
for(int i=1;i<=n;i++)
fat[i]=i;
for(int i=1;i<n;i++)
if(!b[i])
{
int r1=find(e[i<<1].u),r2=find(e[i<<1].v);
fat[r2]=r1;
}
for(int i=1;i<=m;i++)
for(int j=i+1;j<=m;j++)
if(find(c[i])==find(c[j]))return;
ans=min(ans,res);
return;
}
b[num+1]=0;dfs1(num+1);
b[num+1]=1;dfs1(num+1);
}
void Solve1()
{
dfs1(0);
cout<<ans<<endl;
}
void dfs(int x,int from,int w)
{
Smin[++tim][0]=w;
if(a[x])b[++tot]=tim;
for(int i=front[x];i;i=e[i].nxt)
{
int v=e[i].v;
if(v==from)continue;
dfs(v,x,e[i].w);
}
}
int Query(int l,int r)
{
int k=Log[r-l+1];
return min(Smin[l][k],Smin[r-(1<<k)+1][k]);
}
void ST()
{
for(int i=2;i<=tim;i++)
Log[i]=Log[i>>1]+1;
for(int j=1;j<=Log[tim];j++) for(int i=tim-(1<<j-1);i;i--)
Smin[i][j]=min(Smin[i][j-1],Smin[i+(1<<j-1)][j-1]);
}
void Solve2()
{
for(int i=1;i<=n;i++)
if(in[i]==1)
{
dfs(i,0,0x3f3f3f3f);
break;
}
ST();
long long res=0;
for(int i=2;i<=tot;i++)
res+=Query(b[i-1]+1,b[i]);
cout<<res<<endl;
}
int main()
{
// freopen("apple.in","r",stdin);
// freopen("apple.out","w",stdout);
scanf("%d%d",&n,&m);
int u,v,w;
for(int i=1;i<n;i++)
{
u=qread()+1;v=qread()+1;w=qread();
Insert(u,v,w);Insert(v,u,w);
in[u]++;in[v]++;
}
for(int i=1;i<=m;i++)
c[i]=qread()+1,a[c[i]]=1;
int k=0;
for(int i=1;i<=n;i++) if(in[i]==2)k++;
if(k==n-2)Solve2();
else Solve1();
fclose(stdin);fclose(stdout);
return 0;
}
60暴力
/*
形 DP。首先任取一个有苹果的结点为根,构建整棵树,接下来自底向上进行动态
规划。设 f[u]表示以 u 为根的子树中苹果互不连通,且子树中的苹果不与树外的苹果连通的
最小代价。g[u]表示以 u 为根的子树中苹果互不连通所需的最小代价
那么当 u 上有苹果时,
g[u] = sum (f[v]) (v 为 u 的所有子节点) ;
f[u] = g[u] + pre[u] (pre[u]为 u 与其父节点连边的权值) 。
当 u 上无苹果时,
设 s[u] = sum (f[v]) (v 为 u 的所有子节点)
则 g[u] = min (s[u] - f[v] + g[v])
f[u] = min(s[u], g[u] + pre[u])
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#define ll long long
#define M 200010
using namespace std;
const ll inf = 10000000000000000ll;
ll f[M], g[M], p[M];
ll nxt[M], head[M], ver[M], to[M], cnt, n, k, sz[M];
bool is[M];
int sta[M];
int read()
{
int nm = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f;
}
void push(int vi, int vj, int v)
{
cnt++, nxt[cnt] = head[vi], head[vi] = cnt, to[cnt] = vj, ver[cnt] = v;
}
void dfs1(int now, int fa)
{
if(is[now]) sz[now] = 1;
for(int i = head[now]; i; i = nxt[i])
{
int vj = to[i];
if(vj == fa) continue;
dfs1(vj, now);
sz[now] += sz[vj];
}
}
void dfs2(int now, int fa)
{
if(sz[now]) f[now] = g[now] = inf;
ll tot = 0;
for(int i = head[now]; i; i = nxt[i])
{
int vj = to[i];
if(vj == fa) continue;
if(sz[vj])
{
dfs2(vj, now);
tot += g[vj];
}
}
ll tot2 = 0, maxx = 0;
for(int i = head[now]; i; i = nxt[i])
{
int vj = to[i];
if(vj == fa || !sz[vj]) continue;
ll op = min(ver[i], f[vj] - g[vj]);
tot2 += op;
maxx = max(maxx, op);
}
if(is[now]) f[now] = inf, g[now] = tot + tot2;
else f[now] = tot + tot2, g[now] = tot + tot2 - maxx;
}
int main()
{
freopen("apple.in", "r", stdin);
freopen("apple.out", "w", stdout);
n = read(), k = read();
for(int i = 1; i < n; i++)
{
int vi = read(), vj = read(), v = read();
push(vi, vj, v);
push(vj, vi, v);
}
for(int i = 1; i <= k; i++) is[read()] = true;
dfs1(0, 0);
dfs2(0, 0);
cout << min(f[0], g[0]) << "
";
return 0;
}