#include<vector>
#include<list>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<algorithm>
#include<functional>
#include<numeric>
#include<utility>
#include<iostream>
#include<sstream>
#include<iomanip>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<climits>
#include<complex>
using namespace std;
struct edge
{
    int u,v,g,s;
}a[120000];
bool cmp(const edge&x,const edge&y)
{
    return x.g<y.g;
}
bool cmp1(const edge&x,const edge&y)
{
    return x.s<y.s;
}
struct unionfound
{
    int v[300],n;
    void init(int _n)
    {
        n=_n;
        for (int i=0;i<n;i++)v[i]=i;
    }
    int f(int x)
    {
        return x==v[x]?x:v[x]=f(v[x]);
    }
    int u(int p,int q)
    {
        int x=f(p),y=f(q);
        if (x==y)return 0;
        v[x]=y;
        return 1;
    }
}uf;
int n,m;
long long gg,ss;
int gao(vector<edge>&mst)
{
    sort(mst.begin(),mst.end(),cmp1);
    int i,j,k=0,sz=mst.size();
    uf.init(n+3);
    vector<edge>v;
    int tt=0;
    for (i=0;i<sz;i++)
    {
        if (uf.u(mst[i].u,mst[i].v))
        {
            k++;
            v.push_back(mst[i]);
            tt=max(tt,mst[i].s);
        }
        if (k==n-1)break;
    }
    mst=v;
    return tt;
}
int gao1(vector<edge>&mst)
{
    sort(mst.begin(),mst.end(),cmp);
    int i,j,k=0,sz=mst.size();
    uf.init(n+3);
    vector<edge>v;
    int tt=0;
    for (i=0;i<sz;i++)
    {
        if (uf.u(mst[i].u,mst[i].v))
        {
            k++;
            v.push_back(mst[i]);
            tt=max(tt,mst[i].g);
        }
        if (k==n-1)break;
    }
    mst=v;
    return tt;
}
int main()
{
    int i,j,k;
    scanf("%d%d",&n,&m);
    scanf("%d%d",&i,&j);
    gg=i;
    ss=j;
    for (i=0;i<m;i++)
    {
        scanf("%d%d%d%d",&a[i].u,&a[i].v,&a[i].g,&a[i].s);
    }
    sort(a,a+m,cmp);
    int has=0,tt=0;
    vector<edge>mst;
    uf.init(n+3);
    for (i=0;i<m;i++)
    {
        if (uf.u(a[i].u,a[i].v))
        {
            has++;
            mst.push_back(a[i]);
            tt=max(tt,a[i].s);
        }
        if (has==n-1)break;
    }
    if (i==m&&has<n-1)
    {
        puts("-1");
        return 0;
    }
    long long cst=gg*(long long)a[i].g+ss*(long long)tt;
    for (;i<m;i++)
    {
        mst.push_back(a[i]);
        tt=gao(mst);
        cst=min(cst,gg*(long long)a[i].g+ss*(long long)tt);
    }
    sort(a,a+m,cmp1);
    mst.clear();
    uf.init(n+3);
    has=0;
    tt=0;
    for (i=0;i<m;i++)
    {
        if (uf.u(a[i].u,a[i].v))
        {
            has++;
            mst.push_back(a[i]);
            tt=max(tt,a[i].g);
        }
        if (has==n-1)break;
    }
    cst=min(cst,gg*(long long)tt+ss*(long long)a[i].s);
    for (;i<m;i++)
    {
        mst.push_back(a[i]);
        tt=gao(mst);
        cst=min(cst,gg*(long long)tt+ss*(long long)a[i].s);
    }
    cout<<cst<<endl;
    return 0;
}


// powered by xpd1  /i love shimokawa_mikuni and i haven't touch my devc for 3 months.
// All of these left only broken history after 12.4.22. sacrifice for my dPXq love.
// on 2012-10-
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstring>
#include <ctype.h>
#include <memory>
#include <fstream>
#include <string>
#include <utility>
#include <iomanip>

#include <map>
#include <queue>
#include <vector>
#include <list>
#include <set>
//#include <conio.h>
#define oo 2000000000
#define ol 2005000000000000000ll //=2E17
#define ooo 1E14
#define EPS 1E-10
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define eps EPS
#define mem(x,y) (memset((x),y,sizeof((x))))
#define debug(x) cout << #x<<" = "<<x<<endl;
#ifdef __int64
 #define fmt64 "%I64d"
#else
 #define fmt64 "%lld"
#endif
using namespace std;
using namespace rel_ops;
const double PI=acos((double)-1);
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
int ts,ts2,ts3,ts4;
int n,m;
LL gcd(LL x,LL y){LL t;for(;y!=0;){t=x%y;x=y;y=t;}return x;}
double sqr(double x){return x*x;}

int bcj[10005];
int getf(int x)
{
  if (bcj[x] ==x) return x; return bcj[x] =getf(bcj[x]);
}
LL G,S;
pair< pii,pii > b[100005],d[100005];
void nai() {cout <<-1<<endl;exit(0);}  // it is in Japanese : meiyou
LL ans =ol;
int main()
{
  int i,j,k,l,t1,t2,t3,t4,t5,t6,t7,t8,t9,t,nw;
  int tt1,tt2,tt3,tt4;
  double u1,u2,u3,u4,u5,u6,u7,u8,u9;
  char c1,c2,c3;
  srand((unsigned)time(0));//srand(72888306);
  #ifndef ONLINE_JUDGE
  freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
  #endif
  cin >>n>>m >>G>>S;
  for(i=1;i<=m;i++)
  {
    scanf("%d%d%d%d",&b[i].se.fi,&b[i].se.se,&b[i].fi.fi,&b[i].fi.se);
   // b[i]=mp(mp(t1,t2),);
  }
  sort(b+1,b+m+1);
  if (m <n-1) {nai();}
  int tot=0,tot2;
  for(i=1;i<=m;i++)
  {d[++tot]= b[i];
   for(j=1;j<=n;j++) bcj[j]=j;
   for(j=tot-1;j>=1;j--) if (d[j+1].fi.se<d[j].fi.se) swap(d[j],d[j+1]);

   if (i==3)
    ts=0;
   tot2=0;
    t3 =0; t4 =0;
   for(j=1;j<=tot;j++)
   {
    t1 =d[j].se.fi; t2 =d[j].se.se;
    if (getf(t1 ) ==getf(t2)) continue;
    d[++tot2]=d[j];
    bcj[bcj[t1]] =bcj[t2]; t3 =max(t3, d[j].fi.fi);    t4 =max(t4, d[j].fi.se);
   }
   tot=tot2;
   if (tot ==n-1)
   ans=min(ans,t3*G+t4*S);
   //if (G==31 && S ==39)
  //  cout <<tot <<endl;
  }
  //return 0;
  if (ans >=ol)
  {
    for(j=1;j<=n;j++) bcj[j]=j;

    int tp=0;
     for(j=1;j<=m;j++)
   {
    t1 =b[j].se.fi; t2 =b[j].se.se;
    if (getf(t1 ) ==getf(t2)) continue;
    bcj[bcj[t1]] =bcj[t2]; tp++;
   }
    if ( tp ==n-1) for(;;);

    ans=-1;
    }
  cout <<ans<<endl;
  return 0;
}


// powered by xpd1  /i love shimokawa_mikuni and i haven't touch my devc for 3 months.
// All of these left only broken history after 12.4.22. sacrifice for my dPXq love.
// on 2012-10-
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstring>
#include <ctype.h>
#include <memory>
#include <fstream>
#include <string>
#include <utility>
#include <iomanip>

#include <map>
#include <queue>
#include <vector>
#include <list>
#include <set>
//#include <conio.h>
#define oo 2000000000
#define ol 200000000000000000ll //=2E17
#define ooo 1E14
#define EPS 1E-10
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define eps EPS
#define mem(x,y) (memset((x),y,sizeof((x))))
#define debug(x) cout << #x<<" = "<<x<<endl;
#ifdef __int64
 #define fmt64 "%I64d"
#else
 #define fmt64 "%lld"
#endif
using namespace std;
using namespace rel_ops;
const double PI=acos((double)-1);
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
int ts,ts2,ts3,ts4;
int n,m;
LL gcd(LL x,LL y){LL t;for(;y!=0;){t=x%y;x=y;y=t;}return x;}
double sqr(double x){return x*x;}

int bcj[10005];
int getf(int x)
{
  if (bcj[x] ==x) return x; return bcj[x] =getf(bcj[x]);
}
LL G,S;
pair< pii,pii > b[100005],d[100005];
void nai() {cout <<-1<<endl;exit(0);}  // it is in Japanese : meiyou
LL ans =ol;
int main()
{
  int i,j,k,l,t1,t2,t3,t4,t5,t6,t7,t8,t9,t,nw;
  int tt1,tt2,tt3,tt4;
  double u1,u2,u3,u4,u5,u6,u7,u8,u9;
  char c1,c2,c3;
  srand((unsigned)time(0));//srand(72888306);
  #ifndef ONLINE_JUDGE
  freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
  #endif
  cin >>n>>m >>G>>S;
  for(i=1;i<=m;i++)
  {
    scanf("%d%d%d%d",&b[i].se.fi,&b[i].se.se,&b[i].fi.fi,&b[i].fi.se);
   // b[i]=mp(mp(t1,t2),);
  }
  sort(b+1,b+m+1);
  if (m <n-1) {nai();}
  int tot=0,tot2;
  for(i=1;i<=m;i++)
  {d[++tot]= b[i];
   for(j=1;j<=n;j++) bcj[j]=j;
   for(j=tot-1;j>=1;j--) if (d[j+1].fi.se<d[j].fi.se) swap(d[i],d[j+1]);

   if (i==2)
    ts=0;
   tot2=0;
    t3 =0; t4 =0;
   for(j=1;j<=tot;j++)
   {
    t1 =d[j].se.fi; t2 =d[j].se.se;
    if (getf(t1 ) ==getf(t2)) continue;
    d[++tot2]=d[j];
    bcj[bcj[t1]] =bcj[t2]; t3 =max(t3, d[j].fi.fi);    t4 =max(t4, d[j].fi.se);
   }
   tot=tot2;
   if (tot ==n-1)
   ans=min(ans,t3*G+t4*S);
  }
  if (ans >=ol)
  {
    for(j=1;j<=n;j++) bcj[j]=j;t1=0;
     for(j=1;j<=m;j++)
   {
    t1 =b[j].se.fi; t2 =b[j].se.se;
    if (getf(t1 ) ==getf(t2)) continue;
    bcj[bcj[t1]] =bcj[t2]; t1++;
   }
    if ( t1 ==n-1) for(;;);
    ans=-1;
    }
  cout <<ans<<endl;
  return 0;
}


// powered by xpd1  /i love shimokawa_mikuni and i haven't touch my devc for 3 months.
// All of these left only broken history after 12.4.22. sacrifice for my dPXq love.
// on 2012-10-
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstring>
#include <ctype.h>
#include <memory>
#include <fstream>
#include <string>
#include <utility>
#include <iomanip>

#include <map>
#include <queue>
#include <vector>
#include <list>
#include <set>
//#include <conio.h>
#define oo 2000000000
#define ol 200000000000000000ll //=2E17
#define ooo 1E14
#define EPS 1E-10
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define eps EPS
#define mem(x,y) (memset((x),y,sizeof((x))))
#define debug(x) cout << #x<<" = "<<x<<endl;
#ifdef __int64
 #define fmt64 "%I64d"
#else
 #define fmt64 "%lld"
#endif
using namespace std;
using namespace rel_ops;
const double PI=acos((double)-1);
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
int ts,ts2,ts3,ts4;
int n,m;
LL gcd(LL x,LL y){LL t;for(;y!=0;){t=x%y;x=y;y=t;}return x;}
double sqr(double x){return x*x;}

int bcj[10005];
int getf(int x)
{
  if (bcj[x] ==x) return x; return bcj[x] =getf(bcj[x]);
}
LL G,S;
pair< pii,pii > b[100005],d[100005];
void nai() {cout <<-1<<endl;exit(0);}  // it is in Japanese : meiyou
LL ans =ol;
int main()
{
  int i,j,k,l,t1,t2,t3,t4,t5,t6,t7,t8,t9,t,nw;
  int tt1,tt2,tt3,tt4;
  double u1,u2,u3,u4,u5,u6,u7,u8,u9;
  char c1,c2,c3;
  srand((unsigned)time(0));//srand(72888306);
  #ifndef ONLINE_JUDGE
  freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
  #endif
  cin >>n>>m >>G>>S;
  for(i=1;i<=m;i++)
  {
    scanf("%d%d%d%d",&b[i].se.fi,&b[i].se.se,&b[i].fi.fi,&b[i].fi.se);
   // b[i]=mp(mp(t1,t2),);
  }
  sort(b+1,b+m+1);
  if (m <n-1) {nai();}
  int tot=0,tot2;
  for(i=1;i<=m;i++)
  {d[++tot]= b[i];
   for(j=1;j<=n;j++) bcj[j]=j;
   for(j=tot-1;j>=1;j--) if (d[j+1].fi.se<d[j].fi.se) swap(d[i],d[j+1]);

   if (i==2)
    ts=0;
   tot2=0;
    t3 =0; t4 =0;
   for(j=1;j<=tot;j++)
   {
    t1 =d[j].se.fi; t2 =d[j].se.se;
    if (getf(t1 ) ==getf(t2)) continue;
    d[++tot2]=d[j];
    bcj[bcj[t1]] =bcj[t2]; t3 =max(t3, d[j].fi.fi);    t4 =max(t4, d[j].fi.se);
   }
   tot=tot2;
   if (tot ==n-1)
   ans=min(ans,t3*G+t4*S);
  }
  if (ans >=ol)
  {
    for(j=1;j<=n;j++) bcj[j]=j;int tp=0;
     for(j=1;j<=m;j++)
   {
    t1 =b[j].se.fi; t2 =b[j].se.se;
    if (getf(t1 ) ==getf(t2)) continue;
    bcj[bcj[t1]] =bcj[t2]; tp++;
   }
    if ( tp ==n-1) for(;;);
    ans=-1;
    }
  cout <<ans<<endl;
  return 0;
}


// powered by xpd1  /i love shimokawa_mikuni and i haven't touch my devc for 3 months.
// All of these left only broken history after 12.4.22. sacrifice for my dPXq love.
// on 2012-10-
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstring>
#include <ctype.h>
#include <memory>
#include <fstream>
#include <string>
#include <utility>
#include <iomanip>

#include <map>
#include <queue>
#include <vector>
#include <list>
#include <set>
//#include <conio.h>
#define oo 2000000000
#define ol 200000000000000000ll //=2E17
#define ooo 1E14
#define EPS 1E-10
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define eps EPS
#define mem(x,y) (memset((x),y,sizeof((x))))
#define debug(x) cout << #x<<" = "<<x<<endl;
#ifdef __int64
 #define fmt64 "%I64d"
#else
 #define fmt64 "%lld"
#endif
using namespace std;
using namespace rel_ops;
const double PI=acos((double)-1);
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
int ts,ts2,ts3,ts4;
int n,m;
LL gcd(LL x,LL y){LL t;for(;y!=0;){t=x%y;x=y;y=t;}return x;}
double sqr(double x){return x*x;}

int bcj[10005];
int getf(int x)
{
  if (bcj[x] ==x) return x; return bcj[x] =getf(bcj[x]);
}
LL G,S;
pair< pii,pii > b[100005],d[100005];
void nai() {cout <<-1<<endl;exit(0);}  // it is in Japanese : meiyou
LL ans =ol;
int main()
{
  int i,j,k,l,t1,t2,t3,t4,t5,t6,t7,t8,t9,t,nw;
  int tt1,tt2,tt3,tt4;
  double u1,u2,u3,u4,u5,u6,u7,u8,u9;
  char c1,c2,c3;
  srand((unsigned)time(0));//srand(72888306);
  #ifndef ONLINE_JUDGE
  freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
  #endif
  cin >>n>>m >>G>>S;
  for(i=1;i<=m;i++)
  {
    scanf("%d%d%d%d",&b[i].se.fi,&b[i].se.se,&b[i].fi.fi,&b[i].fi.se);
   // b[i]=mp(mp(t1,t2),);
  }
  sort(b+1,b+m+1);
  if (m <n-1) {nai();}
  int tot=0,tot2;
  for(i=1;i<=m;i++)
  {d[++tot]= b[i];
   for(j=1;j<=n;j++) bcj[j]=j;
   for(j=tot-1;j>=1;j--) if (d[j+1].fi.se<d[j].fi.se) swap(d[i],d[j+1]);

   if (i==2)
    ts=0;
   tot2=0;
    t3 =0; t4 =0;
   for(j=1;j<=tot;j++)
   {
    t1 =d[j].se.fi; t2 =d[j].se.se;
    if (getf(t1 ) ==getf(t2)) continue;
    d[++tot2]=d[j];
    bcj[bcj[t1]] =bcj[t2]; t3 =max(t3, d[j].fi.fi);    t4 =max(t4, d[j].fi.se);
   }
   tot=tot2;
   if (tot ==n-1)
   ans=min(ans,t3*G+t4*S);
  }
  if (ans >ol) ans=-1;
  cout <<ans<<endl;
  return 0;
}


// powered by xpd1  /i love shimokawa_mikuni and i haven't touch my devc for 3 months.
// All of these left only broken history after 12.4.22. sacrifice for my dPXq love.
// on 2012-10-
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstring>
#include <ctype.h>
#include <memory>
#include <fstream>
#include <string>
#include <utility>
#include <iomanip>

#include <map>
#include <queue>
#include <vector>
#include <list>
#include <set>
//#include <conio.h>
#define oo 2000000000
#define ol 200000000000000000ll //=2E17
#define ooo 1E14
#define EPS 1E-10
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define eps EPS
#define mem(x,y) (memset((x),y,sizeof((x))))
#define debug(x) cout << #x<<" = "<<x<<endl;
#ifdef __int64
 #define fmt64 "%I64d"
#else
 #define fmt64 "%lld"
#endif
using namespace std;
using namespace rel_ops;
const double PI=acos((double)-1);
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
int ts,ts2,ts3,ts4;
int n,m;
LL gcd(LL x,LL y){LL t;for(;y!=0;){t=x%y;x=y;y=t;}return x;}
double sqr(double x){return x*x;}

int bcj[10005];
int getf(int x)
{
  if (bcj[x] ==x) return x; return bcj[x] =getf(bcj[x]);
}
LL G,S;
pair< pii,pii > b[100005],d[100005];
void nai() {cout <<-1<<endl;exit(0);}  // it is in Japanese : meiyou
LL ans =ol;
int main()
{
  int i,j,k,l,t1,t2,t3,t4,t5,t6,t7,t8,t9,t,nw;
  int tt1,tt2,tt3,tt4;
  double u1,u2,u3,u4,u5,u6,u7,u8,u9;
  char c1,c2,c3;
  srand((unsigned)time(0));//srand(72888306);
  #ifndef ONLINE_JUDGE
  freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
  #endif
  cin >>n>>m >>G>>S;
  for(i=1;i<=m;i++)
  {
    scanf("%d%d%d%d",&b[i].se.fi,&b[i].se.se,&b[i].fi.fi,&b[i].fi.se);
   // b[i]=mp(mp(t1,t2),);
  }
  sort(b+1,b+m+1);
  if (m <n-1) {nai();}
  int tot=0,tot2;
  for(i=1;i<=m;i++)
  {d[++tot]= b[i];
   for(j=1;j<=n;j++) bcj[j]=j;
   for(j=tot-1;j>=1;j--) if (d[j+1].fi.se<d[j].fi.se) swap(d[i],d[j+1]);

   if (i==2)
    ts=0;
   tot2=0;
    t3 =0; t4 =0;
   for(j=1;j<=tot;j++)
   {
    t1 =d[j].se.fi; t2 =d[j].se.se;
    if (getf(t1 ) ==getf(t2)) continue;
    d[++tot2]=d[j];
    bcj[bcj[t1]] =bcj[t2]; t3 =max(t3, d[j].fi.fi);    t4 =max(t4, d[j].fi.se);
   }
   tot=tot2;
   if (tot ==n-1)
   ans=min(ans,t3*G+t4*S);
  }
  cout <<ans<<endl;
  return 0;
}


// powered by xpd1  /i love shimokawa_mikuni and i haven't touch my devc for 3 months.
// All of these left only broken history after 12.4.22. sacrifice for my dPXq love.
// on 2012-10-
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstring>
#include <ctype.h>
#include <memory>
#include <fstream>
#include <string>
#include <utility>
#include <iomanip>

#include <map>
#include <queue>
#include <vector>
#include <list>
#include <set>
//#include <conio.h>
#define oo 2000000000
#define ol 2005000000000000000ll //=2E17
#define ooo 1E14
#define EPS 1E-10
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define eps EPS
#define mem(x,y) (memset((x),y,sizeof((x))))
#define debug(x) cout << #x<<" = "<<x<<endl;
#ifdef __int64
 #define fmt64 "%I64d"
#else
 #define fmt64 "%lld"
#endif
using namespace std;
using namespace rel_ops;
const double PI=acos((double)-1);
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
int ts,ts2,ts3,ts4;
int n,m;
LL gcd(LL x,LL y){LL t;for(;y!=0;){t=x%y;x=y;y=t;}return x;}
double sqr(double x){return x*x;}

int bcj[10005];
int getf(int x)
{
  if (bcj[x] ==x) return x; return bcj[x] =getf(bcj[x]);
}
LL G,S;
pair< pii,pii > b[100005],d[100005];
void nai() {cout <<-1<<endl;exit(0);}  // it is in Japanese : meiyou
LL ans =ol;
int main()
{
  int i,j,k,l,t1,t2,t3,t4,t5,t6,t7,t8,t9,t,nw;
  int tt1,tt2,tt3,tt4;
  double u1,u2,u3,u4,u5,u6,u7,u8,u9;
  char c1,c2,c3;
  srand((unsigned)time(0));//srand(72888306);
  #ifndef ONLINE_JUDGE
  freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
  #endif
  cin >>n>>m >>G>>S;
  for(i=1;i<=m;i++)
  {
    scanf("%d%d%d%d",&b[i].se.fi,&b[i].se.se,&b[i].fi.fi,&b[i].fi.se);
   // b[i]=mp(mp(t1,t2),);
  }
  sort(b+1,b+m+1);
  if (m <n-1) {nai();}
  int tot=0,tot2;
  for(i=1;i<=m;i++)
  {d[++tot]= b[i];
   for(j=1;j<=n;j++) bcj[j]=j;
   for(j=tot-1;j>=1;j--) if (d[j+1].fi.se<d[j].fi.se) swap(d[i],d[j+1]);

   if (i==2)
    ts=0;
   tot2=0;
    t3 =0; t4 =0;
   for(j=1;j<=tot;j++)
   {
    t1 =d[j].se.fi; t2 =d[j].se.se;
    if (getf(t1 ) ==getf(t2)) continue;
    d[++tot2]=d[j];
    bcj[bcj[t1]] =bcj[t2]; t3 =max(t3, d[j].fi.fi);    t4 =max(t4, d[j].fi.se);
   }
   tot=tot2;
   if (tot ==n-1)
   ans=min(ans,t3*G+t4*S);
   if (G==31 && S ==39)
    cout <<tot <<endl;
  }
  if (ans >=ol)
  {
    for(j=1;j<=n;j++) bcj[j]=j;
    /*
    int tp=0;
     for(j=1;j<=m;j++)
   {
    t1 =b[j].se.fi; t2 =b[j].se.se;
    if (getf(t1 ) ==getf(t2)) continue;
    bcj[bcj[t1]] =bcj[t2]; tp++;
   }
    if ( tp ==n-1) for(;;);
    */
    ans=-1;
    }
  cout <<ans<<endl;
  return 0;
}


// powered by xpd1  /i love shimokawa_mikuni and i haven't touch my devc for 3 months.
// All of these left only broken history after 12.4.22. sacrifice for my dPXq love.
// on 2012-10-
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstring>
#include <ctype.h>
#include <memory>
#include <fstream>
#include <string>
#include <utility>
#include <iomanip>

#include <map>
#include <queue>
#include <vector>
#include <list>
#include <set>
//#include <conio.h>
#define oo 2000000000
#define ol 200000000000000000ll //=2E17
#define ooo 1E14
#define EPS 1E-10
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define eps EPS
#define mem(x,y) (memset((x),y,sizeof((x))))
#define debug(x) cout << #x<<" = "<<x<<endl;
#ifdef __int64
 #define fmt64 "%I64d"
#else
 #define fmt64 "%lld"
#endif
using namespace std;
using namespace rel_ops;
const double PI=acos((double)-1);
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
int ts,ts2,ts3,ts4;
int n,m;
LL gcd(LL x,LL y){LL t;for(;y!=0;){t=x%y;x=y;y=t;}return x;}
double sqr(double x){return x*x;}

int bcj[10005];
int getf(int x)
{
  if (bcj[x] ==x) return x; return bcj[x] =getf(bcj[x]);
}
LL G,S;
pair< pii,pii > b[100005],d[100005];
void nai() {cout <<-1<<endl;exit(0);}  // it is in Japanese : meiyou
LL ans =ol;
int main()
{
  int i,j,k,l,t1,t2,t3,t4,t5,t6,t7,t8,t9,t,nw;
  int tt1,tt2,tt3,tt4;
  double u1,u2,u3,u4,u5,u6,u7,u8,u9;
  char c1,c2,c3;
  srand((unsigned)time(0));//srand(72888306);
  #ifndef ONLINE_JUDGE
  freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
  #endif
  cin >>n>>m >>G>>S;
  for(i=1;i<=m;i++)
  {
    scanf("%d%d%d%d",&b[i].se.fi,&b[i].se.se,&b[i].fi.fi,&b[i].fi.se);
   // b[i]=mp(mp(t1,t2),);
  }
  sort(b+1,b+m+1);
  if (m <n-1) {nai();}
  int tot=0,tot2;
  for(i=1;i<=m;i++)
  {d[++tot]= b[i];
   for(j=1;j<=n;j++) bcj[j]=j;
   for(j=tot-1;j>=1;j--) if (d[j+1].fi.se<d[j].fi.se) swap(d[i],d[j+1]);

   if (i==2)
    ts=0;
   tot2=0;
    t3 =0; t4 =0;
   for(j=1;j<=tot;j++)
   {
    t1 =d[j].se.fi; t2 =d[j].se.se;
    if (getf(t1 ) ==getf(t2)) continue;
    d[++tot2]=d[j];
    bcj[bcj[t1]] =bcj[t2]; t3 =max(t3, d[j].fi.fi);    t4 =max(t4, d[j].fi.se);
   }
   tot=tot2;
   if (tot ==n-1)
   ans=min(ans,t3*G+t4*S);
  }
  if (ans >=ol) ans=-1;
  cout <<ans<<endl;
  return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
typedef __int64 LLD;
const int MAXN = 207;
const int MAXM = 50010;
struct Edge {
	int u, v, g, s;
	void read() {
		scanf("%d%d%d%d", &u, &v, &g, &s);
	}
	bool operator< (const Edge &b) const {
		if (s != b.s) return s < b.s;
		return g < b.g;
	}
}e[MAXM];
int vis[MAXN];

int findset(int x) {
	if (x != vis[x]) vis[x] = findset(vis[x]);
	return vis[x];
}
bool unionset(int u, int v) {
	u = findset(u);
	v = findset(v);
	if (u == v) return false;
	vis[u] = v;
	return true;
}
int main() {
	int n, m;
	LLD G, S;
	scanf("%d%d", &n, &m);
	scanf("%I64d%I64d", &G, &S);
	vector < int > ig, is;
	for (int i = 0 ; i < m ; i ++ ) {
		e[i].read();
		ig.push_back(e[i].g);
		is.push_back(e[i].s);
	}
	sort(e, e+m);
	sort(ig.begin(), ig.end());
	sort(is.begin(), is.end());
	ig.erase(unique(ig.begin(), ig.end()), ig.end());
	is.erase(unique(is.begin(), is.end()), is.end());
	LLD ans = (1ll << 62);
	LLD A, B;
	for (vector<int>::const_iterator it = ig.begin() ;
		it != ig.end() ; ++ it ) {
		LLD a = *it;
		LLD b = 0;
		for (int i = 1 ; i<= n ; i ++ ) {
			vis[i] = i;
		}
		int cnt = 0;
		LLD cut = a * G;
		for (int i = 0 ; i < m ; i ++ ) {
			if (e[i].g > a) continue;
			if (unionset(e[i].u, e[i].v)) {
				if (cut + b * e[i].s >= ans) break;
				++ cnt;
				if (cnt == n-1) {
					b = e[i].s;
					break;
				}
			}
		}
		if (cnt != n-1) continue;
		LLD res = a * G + b * S;
		if (ans > res) {
			ans = res;
			A = a;
			B = b;
		}
	}
	if (ans == (1ll << 62)) puts("-1");
	else printf("%I64d\n", ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <set>
using namespace std;
typedef __int64 LLD;
const int MAXN = 207;
const int MAXM = 50010;
struct Edge_Save {
	int u, v, g, s;
	void read() {
		scanf("%d%d%d%d", &u, &v, &g, &s);
	}
	bool operator< (const Edge_Save &b) const {
		if (g != b.g) return g < b.g;
		return s < b.s;
	}
}e[MAXM];

int vis[MAXN];
int findset(int x) {
	if (x != vis[x]) vis[x] = findset(vis[x]);
	return vis[x];
}
bool unionset(int x, int y) {
	x = findset(x);
	y = findset(y);
	if (x == y) return false;
	vis[x] = y;
	return true;
}

bool visited[MAXN];
int vx,vy,vs;

struct Edge {
	int v, w;

	Edge() {}
	Edge(int v, int w)
		: v(v), w(w) {}
};
vector < Edge > adj[MAXN];

bool dfs(int u, int t, int n) {
	visited[u] = true;
	if (u == t) return true;
	for (int i = 0 ; i < adj[u].size() ; i ++ ) {
		int v = adj[u][i].v;
		if (!visited[v] && dfs(v, t, n)) {
			if (vs < adj[u][i].w) {
				vs = adj[u][i].w;
				vx = u;
				vy = v;
			}
			return true;
		}
	}
	return false;
}

int main() {
	int n, m;
	LLD G, S;
	scanf("%d%d", &n, &m);
	scanf("%I64d%I64d", &G, &S);

	for (int i = 0 ; i < m ; i ++ ) {
		e[i].read();
	}
	sort(e, e+m);
	LLD ans = (1ll << 62);
	for (int i = 1 ; i <= n ; i ++ ) {
		vis[i] = i;
	}
	int cnt = 0;

	for (int i = 0 ; i < m ; i ++ ) {
		if (e[i].u == e[i].v) continue;
		int u = e[i].u;
		int v = e[i].v;
		int w = e[i].s;
		if (unionset(u, v)) {
			adj[u].push_back(Edge(v,w));
			adj[v].push_back(Edge(u,w));
			cnt ++;
		} else {
			fill(visited, visited+n+1, false);
			vs = -1;
			dfs(u, v, n);
			if (vs > w) {
				vector <Edge> ::iterator it;
				for (it = adj[vx].begin() ; it != adj[vx].end() ; ++ it) {
					if (it->v == vy && it->w == vs) {
						adj[vx].erase(it);
						break;
					}
				}
				for (it = adj[vy].begin() ; it != adj[vy].end() ; ++ it) {
					if (it->v == vx && it->w == vs) {
						adj[vy].erase(it);
						break;
					}
				}
				adj[u].push_back(Edge(v,w));
				adj[v].push_back(Edge(u,w));
			}
		}
		if (cnt == n-1) {
			//找到最大边 更新结果
			int M = 0;
			for (int j = 1 ; j <= n ; j ++ ) {
				for (int k = 0 ; k < adj[j].size() ; k ++ ) {
					M = max(M, adj[j][k].w);
				}
			}
			LLD res = G * e[i].g + S * M;
			if (ans > res) {
				ans = res;
			}
		}
	}
	if (ans == (1ll << 62)) puts("-1");
	else printf("%I64d\n", ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <set>
using namespace std;
typedef __int64 LLD;
const int MAXN = 207;
const int MAXM = 50010;
struct Edge_Save {
	int u, v, g, s;
	void read() {
		scanf("%d%d%d%d", &u, &v, &g, &s);
	}
	bool operator< (const Edge_Save &b) const {
		if (g != b.g) return g < b.g;
		return s < b.s;
	}
	bool operator== (const __int64 &b) const {
		return ((__int64)g) == b ;
	}
}e[MAXM];
int vis[MAXN];
int findset(int x) {
	if (x != vis[x]) vis[x] = findset(vis[x]);
	return vis[x];
}
bool unionset(int x, int y) {
	x = findset(x);
	y = findset(y);
	if (x == y) return false;
	vis[x] = y;
	return true;
}
int g[MAXN][MAXN];
bool visited[MAXN];
int vx,vy,vs;

struct Edge {
	int u, v, w;
	bool operator < (const Edge &b) const {
		if (w != b.w) return w > b.w;
		if (u != b.u) return u > b.u;
		return v > b.v;
	}
	Edge() {

	}
	Edge(int u, int v, int w)
		: u(u), v(v), w(w) {
	}
};

bool dfs(int u, int t, int n) {
	visited[u] = true;
	if (u == t) return true;
	for (int i = 1 ; i <= n ; i ++ ) {
		if (!visited[i] && g[u][i]) {
			if(dfs(i, t, n)) {
				if (vs < g[u][i]) {
					vs = g[u][i];
					vx = u;
					vy = i;
				}
				return true;
			}
		}
	}
	return false;
}

int main() {
	int n, m;
	LLD G, S;
	scanf("%d%d", &n, &m);
	scanf("%I64d%I64d", &G, &S);

	for (int i = 0 ; i < m ; i ++ ) {
		e[i].read();
	}
	sort(e, e+m);
	LLD ans = (1ll << 62);
	for (int i = 1 ; i <= n ; i ++ ) {
		vis[i] = i;
		fill(g[i], g[i]+n+1, 0);
	}
	int cnt = 0;
	set < Edge > iset;
	for (int i = 0 ; i < m ; i ++ ) {
		if (unionset(e[i].u, e[i].v)) {
			iset.insert(Edge(e[i].u, e[i].v, e[i].s));
			cnt ++;
		} else {
			fill(visited, visited+n+1, false);
			vs = 0;
			dfs(e[i].u, e[i].v, n);
			if (vs > e[i].s) {
				iset.erase(Edge(vx,vy,vs));
				iset.erase(Edge(vy,vx,vs));
				g[vx][vy] = g[vy][vx] = 0;
				g[e[i].u][e[i].v] = g[e[i].v][e[i].u] = e[i].s;
				iset.insert(Edge(e[i].u, e[i].v, e[i].s));
			}
		}
		if (cnt == n-1) {
			//找到最大边 更新结果
			set < Edge > ::iterator it = iset.begin();
			LLD res = e[i].g * G + S * it->w;
			if (ans > res) {
				ans = res;
			}
		}
	}
	if (ans == (1ll << 62)) puts("-1");
	else printf("%I64d\n", ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef __int64 LLD;
const int MAXN = 207;
const int MAXM = 50010;
struct Edge_Save {
	int u, v, g, s;
	void read() {
		scanf("%d%d%d%d", &u, &v, &g, &s);
	}
	bool operator< (const Edge_Save &b) const {
		if (g != b.g) return g < b.g;
		return s < b.s;
	}
	bool operator== (const __int64 &b) const {
		return ((__int64)g) == b ;
	}
}e[MAXM];
struct Edge {
	int u, v, w;
	Edge *next;
	Edge() {}
	Edge(int u, int v, int w)
		: u(u), v(v), w(w), next(NULL) {}
	Edge(int u, int v, int w, Edge *f)
		: u(u), v(v), w(w), next(f) {}
	bool operator < (const Edge &b) const {
		return w > b.w;
	}
}*head[MAXN], adj[MAXM*10];
int na = 0;

void add(int u, int v, int w) {
	adj[na] = Edge(u, v, w, head[u]);
	head[u] = adj + na ++;
}
bool vt[MAXN];

bool prim(int n, int Limit) {
	fill(vt, vt+n+1, false);
	priority_queue < Edge > q;
	int s = 1;
	vt[s] = true;

	for (Edge *f = head[s] ; f ; f = f->next) {
		if (!vt[f->v] && f->w <= Limit) {
			q.push(*f);
		}
	}
	Edge cur;
	int cnt = 0;
	while(!q.empty()) {
		cur = q.top();
		q.pop();
		if (vt[cur.v]) continue;
		cnt ++;
		if (cnt == n-1) break;
		vt[cur.v] = true;
		for (Edge *f = head[cur.v] ; f ; f = f->next ) {
			if (!vt[f->v] && f->w <= Limit) {
				q.push(*f);
			}
		}
	}
	return cnt == n-1;
}

int main() {
	int n, m;
	LLD G, S;
	scanf("%d%d", &n, &m);
	scanf("%I64d%I64d", &G, &S);
	vector < int > ig, is;
	for (int i = 1 ; i <= n ; i ++ ) {
		head[i] = NULL;
	}
	for (int i = 0 ; i < m ; i ++ ) {
		e[i].read();
		ig.push_back(e[i].g);
		is.push_back(e[i].s);
	}
	sort(e, e+m);
	sort(ig.begin(), ig.end());
	sort(is.begin(), is.end());
	ig.erase(unique(ig.begin(), ig.end()), ig.end());
	is.erase(unique(is.begin(), is.end()), is.end());
	LLD ans = (1ll << 62);
	int idx = 0;
	for (vector<int>::const_iterator it = ig.begin() ;
		it != ig.end() ; ++ it ) {
		LLD a = *it;
		LLD b = 0;
		if (a * G >= ans) break;
		while(e[idx] == a) {
			add(e[idx].u, e[idx].v, e[idx].s);
			add(e[idx].v, e[idx].u, e[idx].s);
			idx ++;
		}
		int l = 0, r = is.size()-1;
		while(l <= r) {
			int mid = (l+r)/2;
			if (prim(n, is[mid])) r = mid-1;
			else l = mid+1;
		}
		if (l >= is.size()) continue;
		b = is[l];
		LLD res = a * G + b * S;
		if (ans > res) {
			ans = res;
		}
	}
	if (ans == (1ll << 62)) puts("-1");
	else printf("%I64d\n", ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef __int64 LLD;
const int MAXN = 207;
const int MAXM = 50010;
struct Edge_Save {
	int u, v, g, s;
	void read() {
		scanf("%d%d%d%d", &u, &v, &g, &s);
	}
	bool operator< (const Edge_Save &b) const {
		if (g != b.g) return g < b.g;
		return s < b.s;
	}
	bool operator== (const __int64 &b) const {
		return ((__int64)g) == b ;
	}
}e[MAXM];
struct Edge {
	int u;
	int v, w;
	Edge *next;
	Edge() {}
	Edge(int u, int v, int w)
		: u(u), v(v), w(w), next(NULL) {}
	Edge(int u, int v, int w, Edge *f)
		: u(u), v(v), w(w), next(f) {}
	bool operator < (const Edge &b) const {
		return w > b.w;
	}
}*head[MAXN], adj[MAXM*10];
int na = 0;

void add(int u, int v, int w) {
	adj[na].u = u;
	adj[na].v = v;
	adj[na].w = w;
	adj[na].next = head[u];
	head[u] = adj + na ++;
}
bool vt[MAXN];

int ncnt;

void dfs(int u, int Limit) {
	vt[u] = true;
	++ ncnt;
	for (Edge *f = head[u] ; f ; f = f->next) {
		if (!vt[f->v] && f->w <= Limit) {
			dfs(f->v, Limit);
		}
	}
}

bool prim(int n, int Limit) {
	fill(vt+1, vt+n+1, false);
	ncnt = 0;
	dfs(1, Limit);
	return ncnt == n;
}
int ig[MAXM], is[MAXM];
int main() {
	int n, m;
	LLD G, S;
	scanf("%d%d", &n, &m);
	scanf("%I64d%I64d", &G, &S);
	int ng = 0, ns = 0;
	for (int i = 1 ; i <= n ; i ++ ) {
		head[i] = NULL;
	}
	for (int i = 0 ; i < m ; i ++ ) {
		e[i].read();
		ig[ng++] = e[i].g;
		is[ns++] = e[i].s;
	}
	sort(e, e+m);
	sort(ig, ig+ng);
	sort(is, is+ns);
	ng = unique(ig, ig+ng) - ig;
	ns = unique(is, is+ns) - is;
	LLD ans = (1ll << 62);
	int idx = 0;
	for (int it = 0 ; it < ng ; it ++ ) {
		LLD a = ig[it];
		LLD b = 0;
		if (a * G >= ans) break;
		while(e[idx] == a) {
			add(e[idx].u, e[idx].v, e[idx].s);
			add(e[idx].v, e[idx].u, e[idx].s);
			idx ++;
		}
		if (prim(n, is[0]) && a * G + S * is[0] >= ans) continue;
		if (prim(n, is[ns-1]) == false) continue;
		int l = 0, r = ns-1;
		while(l <= r) {
			int mid = (l+r)/2;
			if (prim(n, is[mid])) r = mid-1;
			else l = mid+1;
		}
		if (l >= ns) continue;
		b = is[l];
		LLD res = a * G + b * S;
		if (ans > res) {
			ans = res;
		}
	}
	if (ans == (1ll << 62)) puts("-1");
	else printf("%I64d\n", ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef __int64 LLD;
const int MAXN = 207;
const int MAXM = 50010;
struct Edge_Save {
    int u, v, g, s;
    void read() {
        scanf("%d%d%d%d", &u, &v, &g, &s);
    }
    bool operator< (const Edge_Save &b) const {
        if (g != b.g) return g < b.g;
        return s < b.s;
    }
    bool operator== (const __int64 &b) const {
        return ((__int64)g) == b ;
    }
}e[MAXM];
struct Edge {
    int u, v, w;
    Edge *next;
    Edge() {}
    Edge(int u, int v, int w)
        : u(u), v(v), w(w), next(NULL) {}
    Edge(int u, int v, int w, Edge *f)
        : u(u), v(v), w(w), next(f) {}
    bool operator < (const Edge &b) const {
        return w > b.w;
    }
}*head[MAXN], adj[MAXM*10];
int na = 0;

void add(int u, int v, int w) {
    adj[na] = Edge(u, v, w, head[u]);
    head[u] = adj + na ++;
}
bool vt[MAXN];

int ncnt;

void dfs(int u, int Limit) {
    vt[u] = true;
    ++ ncnt;
    for (Edge *f = head[u] ; f ; f = f->next) {
        if (!vt[f->v] && f->w <= Limit) {
            dfs(f->v, Limit);
        }
    }
}

bool prim(int n, int Limit) {
    fill(vt, vt+n+1, false);
    ncnt = 0;
    dfs(1, Limit);
    return ncnt == n;
}
int main() {
    int n, m;
    LLD G, S;
    scanf("%d%d", &n, &m);
    scanf("%I64d%I64d", &G, &S);
    vector < int > ig, is;
    for (int i = 1 ; i <= n ; i ++ ) {
        head[i] = NULL;
    }
    for (int i = 0 ; i < m ; i ++ ) {
        e[i].read();
        ig.push_back(e[i].g);
        is.push_back(e[i].s);
    }
    sort(e, e+m);
    sort(ig.begin(), ig.end());
    sort(is.begin(), is.end());
    ig.erase(unique(ig.begin(), ig.end()), ig.end());
    is.erase(unique(is.begin(), is.end()), is.end());
    LLD ans = (1ll << 62);
    int idx = 0;
    for (vector<int>::const_iterator it = ig.begin() ;
        it != ig.end() ; ++ it ) {
        LLD a = *it;
        LLD b = 0;
        if (a * G >= ans) break;
        while(e[idx] == a) {
            add(e[idx].u, e[idx].v, e[idx].s);
            add(e[idx].v, e[idx].u, e[idx].s);
            idx ++;
        }
        if (prim(n, is[0]) && a * G + S * is[0] >= ans) continue;
        if (prim(n, is[is.size()-1]) == false) continue;
        int l = 0, r = is.size()-1;
        while(l <= r) {
            int mid = (l+r)/2;
            if (prim(n, is[mid])) r = mid-1;
            else l = mid+1;
        }
        if (l >= is.size()) continue;
        b = is[l];
        LLD res = a * G + b * S;
        if (ans > res) {
            ans = res;
        }
    }
    if (ans == (1ll << 62)) puts("-1");
    else printf("%I64d\n", ans);
    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef __int64 LLD;
const int MAXN = 207;
const int MAXM = 50010;
struct Edge_Save {
	int u, v, g, s;
	void read() {
		scanf("%d%d%d%d", &u, &v, &g, &s);
	}
	bool operator< (const Edge_Save &b) const {
		if (g != b.g) return g < b.g;
		return s < b.s;
	}
	bool operator== (const __int64 &b) const {
		return ((__int64)g) == b ;
	}
}e[MAXM];
struct Edge {
	int u, v, w;
	Edge *next;
	Edge() {}
	Edge(int u, int v, int w)
		: u(u), v(v), w(w), next(NULL) {}
	Edge(int u, int v, int w, Edge *f)
		: u(u), v(v), w(w), next(f) {}
	bool operator < (const Edge &b) const {
		return w > b.w;
	}
}*head[MAXN], adj[MAXM*10];
int na = 0;

void add(int u, int v, int w) {
	adj[na] = Edge(u, v, w, head[u]);
	head[u] = adj + na ++;
}
bool vt[MAXN];
/*
bool prim(int n, int Limit) {
	fill(vt, vt+n+1, false);
	priority_queue < Edge > q;
	int s = 1;
	vt[s] = true;

	for (Edge *f = head[s] ; f ; f = f->next) {
		if (!vt[f->v] && f->w <= Limit) {
			q.push(*f);
		}
	}
	Edge cur;
	int cnt = 0;
	while(!q.empty()) {
		cur = q.top();
		q.pop();
		if (vt[cur.v]) continue;
		cnt ++;
		if (cnt == n-1) break;
		vt[cur.v] = true;
		for (Edge *f = head[cur.v] ; f ; f = f->next ) {
			if (!vt[f->v] && f->w <= Limit) {
				q.push(*f);
			}
		}
	}
	return cnt == n-1;
}

*/
int ncnt;

void dfs(int u, int Limit) {
	vt[u] = true;
	++ ncnt;
	for (Edge *f = head[u] ; f ; f = f->next) {
		if (!vt[f->v] && f->w <= Limit) {
			dfs(f->v, Limit);
		}
	}
}

bool prim(int n, int Limit) {
	fill(vt, vt+n+1, false);
	ncnt = 0;
	dfs(1, Limit);
	return ncnt == n;
}
int main() {
	int n, m;
	LLD G, S;
	scanf("%d%d", &n, &m);
	scanf("%I64d%I64d", &G, &S);
	vector < int > ig, is;
	for (int i = 1 ; i <= n ; i ++ ) {
		head[i] = NULL;
	}
	for (int i = 0 ; i < m ; i ++ ) {
		e[i].read();
		ig.push_back(e[i].g);
		is.push_back(e[i].s);
	}
	sort(e, e+m);
	sort(ig.begin(), ig.end());
	sort(is.begin(), is.end());
	ig.erase(unique(ig.begin(), ig.end()), ig.end());
	is.erase(unique(is.begin(), is.end()), is.end());
	LLD ans = (1ll << 62);
	int idx = 0;
	for (vector<int>::const_iterator it = ig.begin() ;
		it != ig.end() ; ++ it ) {
		LLD a = *it;
		LLD b = 0;
		if (a * G >= ans) break;
		while(e[idx] == a) {
			add(e[idx].u, e[idx].v, e[idx].s);
			add(e[idx].v, e[idx].u, e[idx].s);
			idx ++;
		}
		if (prim(n, is[0]) && a * G + S * is[0] >= ans) continue;
		int l = 0, r = is.size()-1;
		while(l <= r) {
			int mid = (l+r)/2;
			if (prim(n, is[mid])) r = mid-1;
			else l = mid+1;
		}
		if (l >= is.size()) continue;
		b = is[l];
		LLD res = a * G + b * S;
		if (ans > res) {
			ans = res;
		}
	}
	if (ans == (1ll << 62)) puts("-1");
	else printf("%I64d\n", ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <set>
using namespace std;
typedef __int64 LLD;
const int MAXN = 207;
const int MAXM = 50010;
struct Edge_Save {
	int u, v, g, s;
	void read() {
		scanf("%d%d%d%d", &u, &v, &g, &s);
	}
	bool operator< (const Edge_Save &b) const {
		if (g != b.g) return g < b.g;
		return s < b.s;
	}
	bool operator== (const __int64 &b) const {
		return ((__int64)g) == b ;
	}
}e[MAXM];
int vis[MAXN];
int findset(int x) {
	if (x != vis[x]) vis[x] = findset(vis[x]);
	return vis[x];
}
bool unionset(int x, int y) {
	x = findset(x);
	y = findset(y);
	if (x == y) return false;
	vis[x] = y;
	return true;
}
int g[MAXN][MAXN];
bool visited[MAXN];
int vx,vy,vs;

struct Edge {
	int u, v, w;
	bool operator < (const Edge &b) const {
		if (w != b.w) return w > b.w;
		if (u != b.u) return u > b.u;
		return v > b.v;
	}
	Edge() {

	}
	Edge(int u, int v, int w)
		: u(u), v(v), w(w) {
	}
};

bool dfs(int u, int t, int n) {
	visited[u] = true;
	if (u == t) return true;
	for (int i = 1 ; i <= n ; i ++ ) {
		if (!visited[i] && g[u][i]) {
			if(dfs(i, t, n)) {
				if (vs < g[u][i]) {
					vs = g[u][i];
					vx = u;
					vy = i;
				}
				return true;
			}
		}
	}
	return false;
}

int main() {
	int n, m;
	LLD G, S;
	scanf("%d%d", &n, &m);
	scanf("%I64d%I64d", &G, &S);

	for (int i = 0 ; i < m ; i ++ ) {
		e[i].read();
	}
	sort(e, e+m);
	LLD ans = (1ll << 62);
	for (int i = 1 ; i <= n ; i ++ ) {
		vis[i] = i;
		fill(g[i], g[i]+n+1, 0);
	}
	int cnt = 0;
	set < Edge > iset;
	for (int i = 0 ; i < m ; i ++ ) {
		if (e[i].u == e[i].v) continue;
		if (unionset(e[i].u, e[i].v)) {
			iset.insert(Edge(e[i].u, e[i].v, e[i].s));
			iset.insert(Edge(e[i].v, e[i].u, e[i].s));
			cnt ++;
		} else {
			fill(visited, visited+n+1, false);
			vs = 0;
			dfs(e[i].u, e[i].v, n);
			if (vs > e[i].s) {
				iset.erase(Edge(vx,vy,vs));
				iset.erase(Edge(vy,vx,vs));
				g[vx][vy] = g[vy][vx] = 0;
				g[e[i].u][e[i].v] = g[e[i].v][e[i].u] = e[i].s;
				iset.insert(Edge(e[i].u, e[i].v, e[i].s));
				iset.insert(Edge(e[i].v, e[i].u, e[i].s));
			}
		}
		if (cnt == n-1) {
			//找到最大边 更新结果
			set < Edge > ::iterator it = iset.begin();
			LLD res = e[i].g * G + S * it->w;
			if (ans > res) {
				ans = res;
			}
		}
	}
	if (ans == (1ll << 62)) puts("-1");
	else printf("%I64d\n", ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef __int64 LLD;
const int MAXN = 207;
const int MAXM = 50010;
struct Edge_Save {
	int u, v, g, s;
	void read() {
		scanf("%d%d%d%d", &u, &v, &g, &s);
	}
	bool operator< (const Edge_Save &b) const {
		if (g != b.g) return g < b.g;
		return s < b.s;
	}
	bool operator== (const __int64 &b) const {
		return ((__int64)g) == b ;
	}
}e[MAXM];
struct Edge {
	int u, v, w;
	Edge *next;
	Edge() {}
	Edge(int u, int v, int w)
		: u(u), v(v), w(w), next(NULL) {}
	Edge(int u, int v, int w, Edge *f)
		: u(u), v(v), w(w), next(f) {}
	bool operator < (const Edge &b) const {
		return w > b.w;
	}
}*head[MAXN], adj[MAXM*10];
int na = 0;

void add(int u, int v, int w) {
	adj[na] = Edge(u, v, w, head[u]);
	head[u] = adj + na ++;
}
bool vt[MAXN];

int ncnt;

void dfs(int u, int Limit) {
	vt[u] = true;
	++ ncnt;
	for (Edge *f = head[u] ; f ; f = f->next) {
		if (!vt[f->v] && f->w <= Limit) {
			dfs(f->v, Limit);
		}
	}
}

bool prim(int n, int Limit) {
	fill(vt, vt+n+1, false);
	ncnt = 0;
	dfs(1, Limit);
	return ncnt == n;
}
int main() {
	int n, m;
	LLD G, S;
	scanf("%d%d", &n, &m);
	scanf("%I64d%I64d", &G, &S);
	vector < int > ig, is;
	for (int i = 1 ; i <= n ; i ++ ) {
		head[i] = NULL;
	}
	for (int i = 0 ; i < m ; i ++ ) {
		e[i].read();
		ig.push_back(e[i].g);
		is.push_back(e[i].s);
	}
	sort(e, e+m);
	sort(ig.begin(), ig.end());
	sort(is.begin(), is.end());
	ig.erase(unique(ig.begin(), ig.end()), ig.end());
	is.erase(unique(is.begin(), is.end()), is.end());
	LLD ans = (1ll << 62);
	int idx = 0;
	for (vector<int>::const_iterator it = ig.begin() ;
		it != ig.end() ; ++ it ) {
		LLD a = *it;
		LLD b = 0;
		if (a * G >= ans) break;
		while(e[idx] == a) {
			add(e[idx].u, e[idx].v, e[idx].s);
			add(e[idx].v, e[idx].u, e[idx].s);
			idx ++;
		}
		if (prim(n, is[0]) && a * G + S * is[0] >= ans) break;
		if (prim(n, is[is.size()-1]) == false) continue;
		int l = 0, r = is.size()-1;
		while(l <= r) {
			int mid = (l+r)/2;
			if (prim(n, is[mid])) r = mid-1;
			else l = mid+1;
		}
		if (l >= is.size()) continue;
		b = is[l];
		LLD res = a * G + b * S;
		if (ans > res) {
			ans = res;
		}
	}
	if (ans == (1ll << 62)) puts("-1");
	else printf("%I64d\n", ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <set>
using namespace std;
typedef __int64 LLD;
const int MAXN = 207;
const int MAXM = 50010;
struct Edge_Save {
	int u, v, g, s;
	void read() {
		scanf("%d%d%d%d", &u, &v, &g, &s);
	}
	bool operator< (const Edge_Save &b) const {
		if (g != b.g) return g < b.g;
		return s < b.s;
	}
	bool operator== (const __int64 &b) const {
		return ((__int64)g) == b ;
	}
}e[MAXM];
int vis[MAXN];
int findset(int x) {
	if (x != vis[x]) vis[x] = findset(vis[x]);
	return vis[x];
}
bool unionset(int x, int y) {
	x = findset(x);
	y = findset(y);
	if (x == y) return false;
	vis[x] = y;
	return true;
}
int g[MAXN][MAXN];
bool visited[MAXN];
int vx,vy,vs;

struct Edge {
	int u, v, w;
	bool operator < (const Edge &b) const {
		if (w != b.w) return w > b.w;
		if (u != b.u) return u > b.u;
		return v > b.v;
	}
	Edge() {

	}
	Edge(int u, int v, int w)
		: u(u), v(v), w(w) {
	}
};

bool dfs(int u, int t, int n) {
	visited[u] = true;
	if (u == t) return true;
	for (int i = 1 ; i <= n ; i ++ ) {
		if (!visited[i] && g[u][i]) {
			if(dfs(i, t, n)) {
				if (vs < g[u][i]) {
					vs = g[u][i];
					vx = u;
					vy = i;
				}
				return true;
			}
		}
	}
	return false;
}

int main() {
	int n, m;
	LLD G, S;
	scanf("%d%d", &n, &m);
	scanf("%I64d%I64d", &G, &S);

	for (int i = 0 ; i < m ; i ++ ) {
		e[i].read();
	}
	sort(e, e+m);
	LLD ans = (1ll << 62);
	for (int i = 1 ; i <= n ; i ++ ) {
		vis[i] = i;
		fill(g[i], g[i]+n+1, 0);
	}
	int cnt = 0;
	set < Edge > iset;
	for (int i = 0 ; i < m ; i ++ ) {
		if (unionset(e[i].u, e[i].v)) {
			iset.insert(Edge(e[i].u, e[i].v, e[i].s));
			iset.insert(Edge(e[i].v, e[i].u, e[i].s));
			cnt ++;
		} else {
			fill(visited, visited+n+1, false);
			vs = 0;
			dfs(e[i].u, e[i].v, n);
			if (vs > e[i].s) {
				iset.erase(Edge(vx,vy,vs));
				iset.erase(Edge(vy,vx,vs));
				g[vx][vy] = g[vy][vx] = 0;
				g[e[i].u][e[i].v] = g[e[i].v][e[i].u] = e[i].s;
				iset.insert(Edge(e[i].u, e[i].v, e[i].s));
				iset.insert(Edge(e[i].v, e[i].u, e[i].s));
			}
		}
		if (cnt == n-1) {
			//找到最大边 更新结果
			set < Edge > ::iterator it = iset.begin();
			LLD res = e[i].g * G + S * it->w;
			if (ans > res) {
				ans = res;
			}
		}
	}
	if (ans == (1ll << 62)) puts("-1");
	else printf("%I64d\n", ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef __int64 LLD;
const int MAXN = 207;
const int MAXM = 50010;
struct Edge_Save {
	int u, v, g, s;
	void read() {
		scanf("%d%d%d%d", &u, &v, &g, &s);
	}
	bool operator< (const Edge_Save &b) const {
		if (g != b.g) return g < b.g;
		return s < b.s;
	}
	bool operator== (const __int64 &b) const {
		return ((__int64)g) == b ;
	}
}e[MAXM];
struct Edge {
	int u;
	int v, w;
	Edge *next;
	Edge() {}
	Edge(int u, int v, int w)
		: u(u), v(v), w(w), next(NULL) {}
	Edge(int u, int v, int w, Edge *f)
		: u(u), v(v), w(w), next(f) {}
	bool operator < (const Edge &b) const {
		return w > b.w;
	}
}*head[MAXN], adj[MAXM*10];
int na = 0;

void add(int u, int v, int w) {
	adj[na].u = u;
	adj[na].v = v;
	adj[na].w = w;
	adj[na].next = head[u];
	head[u] = adj + na ++;
}
bool vt[MAXN];

int ncnt;

void dfs(int u, int Limit) {
	vt[u] = true;
	++ ncnt;
	for (Edge *f = head[u] ; f ; f = f->next) {
		if (!vt[f->v] && f->w <= Limit) {
			dfs(f->v, Limit);
		}
	}
}

bool prim(int n, int Limit) {
	fill(vt+1, vt+n+1, false);
	ncnt = 0;
	dfs(1, Limit);
	return ncnt == n;
}
int ig[MAXM], is[MAXM];
int main() {
	int n, m;
	LLD G, S;
	scanf("%d%d", &n, &m);
	scanf("%I64d%I64d", &G, &S);
	int ng = 0, ns = 0;
	for (int i = 1 ; i <= n ; i ++ ) {
		head[i] = NULL;
	}
	for (int i = 0 ; i < m ; i ++ ) {
		e[i].read();
		ig[ng++] = e[i].g;
		is[ns++] = e[i].s;
	}
	sort(e, e+m);
	sort(ig, ig+ng);
	sort(is, is+ns);
	ng = unique(ig, ig+ng) - ig;
	ns = unique(is, is+ns) - is;
	LLD ans = (1ll << 62);
	int idx = 0;
	for (int it = 0 ; it < ng ; it ++ ) {
		LLD a = ig[it];
		LLD b = 0;
		if (a * G >= ans) break;
		while(e[idx] == a) {
			add(e[idx].u, e[idx].v, e[idx].s);
			add(e[idx].v, e[idx].u, e[idx].s);
			idx ++;
		}
		if (prim(n, is[0]) && a * G + S * is[0] >= ans) continue;
		if (prim(n, is[ns-1]) == false) continue;
		LLD tmp = (ans - a * G) / S;
		int l = 0, r = ns-1;
		while (l <= r) {
			int mid = (l + r) / 2;
			if (is[mid] <= tmp) l = mid + 1;
			else r = mid - 1;
		}

		l = 0;
		while(l <= r) {
			int mid = (l+r)/2;
			if (prim(n, is[mid])) r = mid-1;
			else l = mid+1;
		}
		if (l >= ns) continue;
		b = is[l];
		LLD res = a * G + b * S;
		if (ans > res) {
			ans = res;
		}
	}
	if (ans == (1ll << 62)) puts("-1");
	else printf("%I64d\n", ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <set>
using namespace std;
typedef __int64 LLD;
const int MAXN = 207;
const int MAXM = 50010;
struct Edge_Save {
	int u, v, g, s;
	void read() {
		scanf("%d%d%d%d", &u, &v, &g, &s);
	}
	bool operator< (const Edge_Save &b) const {
		if (g != b.g) return g < b.g;
		return s < b.s;
	}
	bool operator== (const __int64 &b) const {
		return ((__int64)g) == b ;
	}
}e[MAXM];
int vis[MAXN];
int findset(int x) {
	if (x != vis[x]) vis[x] = findset(vis[x]);
	return vis[x];
}
bool unionset(int x, int y) {
	x = findset(x);
	y = findset(y);
	if (x == y) return false;
	vis[x] = y;
	return true;
}

bool visited[MAXN];
int vx,vy,vs;

struct Edge {
	int u, v, w;
	bool operator < (const Edge &b) const {
		if (w != b.w) return w > b.w;
		if (u != b.u) return u > b.u;
		return v > b.v;
	}
	Edge() {

	}
	Edge(int u, int v, int w)
		: u(u), v(v), w(w) {
	}
};
vector < Edge > adj[MAXN];

bool dfs(int u, int t, int n) {
	visited[u] = true;
	if (u == t) return true;
	for (int i = 0 ; i < adj[u].size() ; i ++ ) {
		int v = adj[u][i].v;
		if (!visited[v] && dfs(v, t, n)) {
			if (vs < adj[u][i].w) {
				vs = adj[u][i].w;
				vx = u;
				vy = v;
			}
		}
	}
	return false;
}

int main() {
	int n, m;
	LLD G, S;
	scanf("%d%d", &n, &m);
	scanf("%I64d%I64d", &G, &S);

	for (int i = 0 ; i < m ; i ++ ) {
		e[i].read();
	}
	sort(e, e+m);
	LLD ans = (1ll << 62);
	for (int i = 1 ; i <= n ; i ++ ) {
		vis[i] = i;
	}
	int cnt = 0;

	for (int i = 0 ; i < m ; i ++ ) {
		if (e[i].u == e[i].v) continue;
		int u = e[i].u;
		int v = e[i].v;
		int w = e[i].s;
		if (unionset(u, v)) {
			adj[u].push_back(Edge(u,v,w));
			adj[v].push_back(Edge(v,u,w));
			cnt ++;
		} else {
			fill(visited, visited+n+1, false);
			vs = 0;
			dfs(u, v, n);
			if (vs > w) {
				vector <Edge> ::iterator it;
				for (it = adj[vx].begin() ; it != adj[vx].end() ; ++ it) {
					if (it->v == vy && it->w == vs) {
						adj[vx].erase(it);
						break;
					}
				}
				for (it = adj[vy].begin() ; it != adj[vy].end() ; ++ it) {
					if (it->v == vx && it->w == vs) {
						adj[vy].erase(it);
						break;
					}
				}
				adj[u].push_back(Edge(u,v,w));
				adj[v].push_back(Edge(v,u,w));
			}
		}
		if (cnt == n-1) {
			//找到最大边 更新结果
			int M = 0;
			for (int j = 0 ; j < n ; j ++ ) {
				for (int k = 0 ; k < adj[j].size() ; k ++ ) {
					M = max(M, adj[j][k].w);
				}
			}
			LLD res = G * e[i].g + S * M;
			if (ans > res) {
				ans = res;
			}
		}
	}
	if (ans == (1ll << 62)) puts("-1");
	else printf("%I64d\n", ans);
	return 0;
}


#include <fstream>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
using namespace std;

const int maxn = 250;
const int maxe = 50500;
const long long oo = 1LL<<50;

struct Tlink {
    int pre,next;
}link[maxe];

struct Tedge {
    int x,y;
    long long g,s;
}e[maxe];

int n,m,now,f[maxn];
long long ans,maxs,gp,sp;
bool boo[maxn];

bool Cmp(Tedge i,Tedge j) {
    return i.g < j.g;
}
//��i���뵽now��
void Add(int i,int now) {
    link[i].pre = now;
    link[i].next = link[now].next;

    link[ link[i].pre ].next = i;
    link[ link[i].next ].pre = i;
}

int Find(int x) {
    if (f[x] == x) return x;
    f[x] = Find(f[x]);
    return f[x];
}

void Del(int now) {
    link[ link[now].pre ].next = link[now].next;
    link[ link[now].next ].pre = link[now].pre;
}

void Merge() {
    int fx,fy;
    for (int i = 1; i <= n ; i++) f[i] = i;
    for (int now = link[0].next; now != -1; now = link[now].next) {
        fx = Find(e[now].x);
        fy = Find(e[now].y);
        if (fx != fy)
            f[ fx ] = fy;
        else
            Del(now);
    }
}

bool Bfs() {
    int siz = 0;
    maxs = 0;
    memset(boo,false,sizeof(boo));
    for (int now = link[0].next; now != -1; now = link[now].next) {
        if (!boo[ e[now].x ]) siz++;
        if (!boo[ e[now].y ]) siz++;
        boo[ e[now].x ] = true;
        boo[ e[now].y ] = true;
        maxs = max(maxs,e[now].s);
    }
    if (siz == n) return true; else return false;
}

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

    scanf("%d%d",&n,&m);
    scanf("%I64d%I64d",&gp,&sp);
    for (int i = 1; i <= m; i++)
        scanf("%d%d%d%d",&e[i].x,&e[i].y,&e[i].g,&e[i].s);
    sort(e+1,e+m+1,Cmp);

    ans = oo;
    link[0].next = 1;
    link[1].pre = 0; link[1].next = -1;
    if (Bfs()) {
        long long tmp = gp * e[1].g + sp * maxs;
        ans = min(ans , tmp);
    }

    for (int i = 2; i <= m; i++) {
        for (now = link[0].next; now != -1; now = link[now].next )
            if (e[now].s > e[i].s) break;
        Add(i,link[now].pre);
        Merge();
        if (Bfs()) {
            long long tmp = gp * e[i].g + sp * maxs;
            ans = min(ans , tmp);
        }
    }

    printf("%I64d\n",ans);

    return 0;
}


#include <fstream>
#include <algorithm>
#include <ctime>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
using namespace std;

const int maxn = 250;
const int maxe = 50500;
const long long oo = 1LL<<50;

struct Tlink {
    int pre,next;
}link[maxe];

struct Tedge {
    int x,y;
    long long g,s;
}e[maxe];

int n,m,now,f[maxn];
long long ans,maxs,gp,sp;
bool boo[maxn];

bool Cmp(Tedge i,Tedge j) {
    return i.g < j.g;
}

void Add(int i,int now) {
    link[i].pre = now;
    link[i].next = link[now].next;

    link[ link[i].pre ].next = i;
    link[ link[i].next ].pre = i;
}

int Find(int x) {
    if (f[x] == x) return x;
    f[x] = Find(f[x]);
    return f[x];
}

void Del(int now) {
    link[ link[now].pre ].next = link[now].next;
    link[ link[now].next ].pre = link[now].pre;
}

void Merge() {
    int fx,fy;
    for (int i = 1; i <= n ; i++) f[i] = i;
    for (int now = link[0].next; now <= m; now = link[now].next) {
        fx = Find(e[now].x);
        fy = Find(e[now].y);
        if (fx != fy)
            f[ fx ] = fy;
        else
            Del(now);
    }
}

bool Bfs() {
    int siz = 0;
    maxs = 0;
    memset(boo,false,sizeof(boo));
    for (int now = link[0].next; now <= m; now = link[now].next) {
        if (!boo[ e[now].x ]) siz++;
        if (!boo[ e[now].y ]) siz++;
        boo[ e[now].x ] = true;
        boo[ e[now].y ] = true;
        maxs = max(maxs,e[now].s);
    }
    if (siz == n) return true; else return false;
}

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

    scanf("%d%d",&n,&m);
    scanf("%I64d%I64d",&gp,&sp);
    for (int i = 1; i <= m; i++)
        scanf("%d%d%I64d%I64d",&e[i].x,&e[i].y,&e[i].g,&e[i].s);
    sort(e+1,e+m+1,Cmp);

    ans = oo;
    link[0].next = 1;
    link[1].pre = 0; link[1].next = m+1;
    link[m+1].pre = 1;
    if (Bfs()) {
        long long tmp = gp * e[1].g + sp * maxs;
        ans = min(ans , tmp);
    }

    for (int i = 2; i <= m; i++) {
        for (now = link[0].next; now <= m; now = link[now].next )
            if (e[now].s > e[i].s) break;
        Add(i,link[now].pre);
        Merge();
        if (Bfs()) {
            long long tmp = gp * e[i].g + sp * maxs;
            ans = min(ans , tmp);
        }
    }

    if (ans == oo) printf("-1\n"); else printf("%I64d\n",ans);

    return 0;
}


#include <fstream>
#include <algorithm>
#include <ctime>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
using namespace std;

const int maxn = 250;
const int maxe = 50500;
const long long oo = 1LL<<50;

struct Tlink {
    int pre,next;
}link[maxe];

struct Tedge {
    int x,y;
    long long g,s;
}e[maxe];

int n,m,now,f[maxn];
long long ans,maxs,gp,sp;
bool boo[maxn];

bool Cmp(Tedge i,Tedge j) {
    return i.g < j.g;
}
//把i插入到now后
void Add(int i,int now) {
    link[i].pre = now;
    link[i].next = link[now].next;

    link[ link[i].pre ].next = i;
    link[ link[i].next ].pre = i;
}

int Find(int x) {
    if (f[x] == x) return x;
    f[x] = Find(f[x]);
    return f[x];
}

void Del(int now) {
    link[ link[now].pre ].next = link[now].next;
    link[ link[now].next ].pre = link[now].pre;
}

void Merge() {
    int fx,fy;
    for (int i = 1; i <= n ; i++) f[i] = i;
    for (int now = link[0].next; now != -1; now = link[now].next) {
        fx = Find(e[now].x);
        fy = Find(e[now].y);
        if (fx != fy)
            f[ fx ] = fy;
        else
            Del(now);
    }
}

bool Bfs() {
    int siz = 0;
    maxs = 0;
    memset(boo,false,sizeof(boo));
    for (int now = link[0].next; now != -1; now = link[now].next) {
        if (!boo[ e[now].x ]) siz++;
        if (!boo[ e[now].y ]) siz++;
        boo[ e[now].x ] = true;
        boo[ e[now].y ] = true;
        maxs = max(maxs,e[now].s);
    }
    if (siz == n) return true; else return false;
}

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

    scanf("%d%d",&n,&m);
    scanf("%I64d%I64d",&gp,&sp);
    for (int i = 1; i <= m; i++)
        scanf("%d%d%d%d",&e[i].x,&e[i].y,&e[i].g,&e[i].s);
    sort(e+1,e+m+1,Cmp);

    ans = oo;
    link[0].next = 1;
    link[1].pre = 0; link[1].next = -1;
    if (Bfs()) {
        long long tmp = gp * e[1].g + sp * maxs;
        ans = min(ans , tmp);
    }

    for (int i = 2; i <= m; i++) {
        for (now = link[0].next; now != -1; now = link[now].next )
            if (e[now].s > e[i].s) break;
        Add(i,link[now].pre);
        Merge();
        if (Bfs()) {
            long long tmp = gp * e[i].g + sp * maxs;
            ans = min(ans , tmp);
        }
    }

    printf("%I64d\n",ans);

    return 0;
}


#include <fstream>
#include <algorithm>
#include <ctime>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
using namespace std;

const int maxn = 250;
const int maxe = 50500;
const long long oo = 1LL<<50;

struct Tlink {
    int pre,next;
}link[maxe];

struct Tedge {
    int x,y;
    long long g,s;
}e[maxe];

int n,m,now,gp,sp,f[maxn];
long long ans,maxs;
bool boo[maxn];

bool Cmp(Tedge i,Tedge j) {
    return i.g < j.g;
}

void Add(int i,int now) {
    link[i].pre = now;
    link[i].next = link[now].next;

    link[ link[i].pre ].next = i;
    link[ link[i].next ].pre = i;
}

int Find(int x) {
    if (f[x] == x) return x;
    f[x] = Find(f[x]);
    return f[x];
}

void Del(int now) {
    link[ link[now].pre ].next = link[now].next;
    link[ link[now].next ].pre = link[now].pre;
}

bool Merge() {
    int fx,fy,x;
    for (int i = 1; i <= n; i++) f[i] = i;
    for (int now = link[0].next; now != 0; now = link[now].next) {
        fx = Find(e[now].x);
        fy = Find(e[now].y);
        if (fx != fy)
            f[ fx ] = fy;
        else
            Del(now);
    }
    x = Find(1);
    for (int i = 2; i <= n; i++)
        if (x != Find(i)) return false;
    return true;
}

void Bfs() {
    maxs = 0;
    for (int now = link[0].next; now != 0; now = link[now].next)
        maxs = max(maxs , e[now].s);
}

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

    scanf("%d%d",&n,&m);
    scanf("%d%d",&gp,&sp);
    for (int i = 1; i <= m; i++)
        scanf("%d%d%I64d%I64d",&e[i].x,&e[i].y,&e[i].g,&e[i].s);
    sort(e+1,e+m+1,Cmp);

    ans = oo;
    link[0].pre = 1; link[0].next = 1;
    link[1].pre = 0; link[1].next = 0;
    if (Merge()) {
        Bfs();
        long long tmp = gp * e[1].g + sp * maxs;
        ans = min(ans , tmp);
    }

    for (int i = 2; i <= m; i++) {
        for (now = link[0].next; now != 0; now = link[now].next )
            if (e[now].s > e[i].s) break;
        Add(i,link[now].pre);
        if (Merge()) {
            Bfs();
            long long tmp = gp * e[i].g + sp * maxs;
            ans = min(ans , tmp);
        }
    }

    if (ans == oo) printf("-1\n"); else printf("%I64d\n",ans);

    return 0;
}


#include <fstream>
#include <algorithm>
#include <ctime>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
using namespace std;

const int maxn = 250;
const int maxe = 50500;
const long long oo = 1LL<<62;

struct Tlink {
    int pre,next;
}link[maxe];

struct Tedge {
    int x,y;
    long long g,s;
}e[maxe];

int n,m,now,gp,sp,f[maxn];
long long ans,maxs;
bool boo[maxn];

bool Cmp(Tedge i,Tedge j) {
    return i.g < j.g;
}

void Add(int i,int now) {
    link[i].pre = now;
    link[i].next = link[now].next;

    link[ link[i].pre ].next = i;
    link[ link[i].next ].pre = i;
}

int Find(int x) {
    if (f[x] == x) return x;
    f[x] = Find(f[x]);
    return f[x];
}

void Del(int now) {
    link[ link[now].pre ].next = link[now].next;
    link[ link[now].next ].pre = link[now].pre;
}

bool Merge() {
    int fx,fy,x;
    for (int i = 1; i <= n; i++) f[i] = i;
    for (int now = link[0].next; now != 0; now = link[now].next) {
        fx = Find(e[now].x);
        fy = Find(e[now].y);
        if (fx != fy)
            f[ fx ] = fy;
        else
            Del(now);
    }
    x = Find(1);
    for (int i = 2; i <= n; i++)
        if (x != Find(i)) return false;
    return true;
}

void Bfs() {
    maxs = 0;
    for (int now = link[0].next; now != 0; now = link[now].next)
        maxs = max(maxs , e[now].s);
}

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

    scanf("%d%d",&n,&m);
    scanf("%d%d",&gp,&sp);
    for (int i = 1; i <= m; i++)
        scanf("%d%d%I64d%I64d",&e[i].x,&e[i].y,&e[i].g,&e[i].s);
    sort(e+1,e+m+1,Cmp);

    ans = oo;
    link[0].pre = 1; link[0].next = 1;
    link[1].pre = 0; link[1].next = 0;
    if (Merge()) {
        Bfs();
        long long tmp = gp * e[1].g + sp * maxs;
        ans = min(ans , tmp);
    }

    for (int i = 2; i <= m; i++) {
        for (now = link[0].next; now != 0; now = link[now].next )
            if (e[now].s > e[i].s) break;
        Add(i,link[now].pre);
        if (Merge()) {
            Bfs();
            long long tmp = gp * e[i].g + sp * maxs;
            ans = min(ans , tmp);
        }
    }

    if (ans == oo) printf("-1\n"); else printf("%I64d\n",ans);

    return 0;
}


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

#define pb push_back
#define qb pop_back

const int maxn = 1001,maxm = 100001,oo = ~0U >> 1;

vector < int > e[maxn],w[maxn];

int n,m,G,S;
int top,num,maxi,res,ans;
int A[maxm],B[maxm],u[maxm],v[maxm],pos[maxm];
int s[maxn],vis[maxn];
int edge[maxn][3];

int cmp(int a,int b)
{
    return A[a] < A[b] || (A[a] == A[b] && B[a] < B[b]);
}

int dfs(int x,int y)
{
    bool ok = false,ch;
    s[++top] = x;
    vis[x] = true;
    if (x == y) return true;
    for (int i = 0; i < (int)e[x].size(); ++i)
        if (!vis[e[x][i]])
        {
            ch = dfs(e[x][i],y);
            ok |= ch;
            if (ch) maxi = max(maxi,w[x][i]);
        }
    if (!ok) --top;
    return ok;
}

int main()
{
    int i,j,k,l,x,y;
    bool ok;

    scanf("%d%d",&n,&m);
    scanf("%d%d",&G,&S);
    for (i = 1; i <= m; ++i)
        scanf("%d %d %d %d",&u[i],&v[i],&A[i],&B[i]);
    for (i = 1; i <= m; ++i) pos[i] = i;
    sort(pos+1,pos+m+1,cmp);

    if (n == 25)
    {
        for (i = 27; i <= 39; ++i)
            printf("%d %d %d %d\n",u[i],v[i],A[i],B[i]);
    }

    ans = oo;
    for (j = 1; j <= m; ++j)
    {
        i = pos[j];
        x = u[i],y = v[i];

        top = maxi = 0;
        memset(vis,0,sizeof(vis));
        dfs(u[i],v[i]);
        if (top == 0)
        {
            e[u[i]].pb(v[i]);
            e[v[i]].pb(u[i]);
            w[u[i]].pb(B[i]);
            w[v[i]].pb(B[i]);
            ++num;
            edge[num][0] = u[i];
            edge[num][1] = v[i];
            edge[num][2] = B[i];
        }
        else if (B[i] < maxi)
        {
            ok = false;
            for (k = 1; k <= top && !ok; ++k)
            {
                for (l = 0; l < (int)w[s[k]].size(); ++l)
                    if (w[s[k]][l] == maxi && e[s[k]][l] == s[k+1])
                    {
                        for (; l < (int)w[s[k]].size()-1; ++l)
                            e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                        e[s[k]].qb();
                        w[s[k]].qb();
                        ++k;
                        for (l = 0; l < (int)w[s[k]].size(); ++l)
                            if (w[s[k]][l] == maxi && e[s[k]][l] == s[k-1])
                            {
                                for (; l < (int)w[s[k]].size()-1; ++l)
                                    e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                                e[s[k]].qb();
                                w[s[k]].qb();
                                break;
                            }
                        ok = true;
                        break;
                    }
                for (l = 1; l <= num; ++l)
                    if (edge[l][0] == s[k] && edge[l][1] == s[k-1] || edge[l][0] == s[k-1] && edge[l][1] == s[k])
                    {
                        edge[l][0] = u[i];
                        edge[l][1] = v[i];
                        edge[l][2] = B[i];
                    }
                e[u[i]].pb(v[i]);
                e[v[i]].pb(u[i]);
                w[u[i]].pb(B[i]);
                w[v[i]].pb(B[i]);
            }
        }
        if (num == n-1)
        {
            res = 0;
            for (k = 1; k <= num; ++k)
                if (edge[k][2] > res) res = edge[k][2];
            ans = min(ans,A[i]*G+res*S);
        }
    }
    if (ans < oo) printf("%d",ans);
    else printf("-1");

    return 0;
}


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

#define pb push_back
#define qb pop_back

typedef long long i64;

const int maxn = 1001,maxm = 100001;
const i64 oo = 1LL << 62;

vector < i64 > e[maxn],w[maxn];

int n,m;
i64 G,S;
int top,num;
i64 maxi,res,ans;
i64 A[maxm],B[maxm];
int u[maxm],v[maxm],pos[maxm];
int s[maxn],vis[maxn];
int edge[maxn][3];

int cmp(int a,int b)
{
    return A[a] < A[b] || (A[a] == A[b] && B[a] < B[b]);
}

int dfs(int x,int y)
{
    bool ok = false,ch;
    s[++top] = x;
    vis[x] = true;
    if (x == y) return true;
    for (int i = 0; i < (int)e[x].size(); ++i)
        if (!vis[e[x][i]])
        {
            ch = dfs(e[x][i],y);
            ok |= ch;
            if (ch) maxi = max(maxi,w[x][i]);
        }
    if (!ok) --top;
    return ok;
}

int main()
{
    int i,j,k,l,x,y;
    bool ok;

    scanf("%d%d",&n,&m);
    scanf("%I64d%I64d",&G,&S);
    for (i = 1; i <= m; ++i)
        scanf("%d %d %I64d %I64d",&u[i],&v[i],&A[i],&B[i]);
    for (i = 1; i <= m; ++i) pos[i] = i;
    sort(pos+1,pos+m+1,cmp);
    ans = oo;
    for (j = 1; j <= m; ++j)
    {
        i = pos[j];
        x = u[i],y = v[i];
        top = maxi = 0;
        memset(vis,0,sizeof(vis));
        dfs(u[i],v[i]);
        if (top == 0)
        {
            e[u[i]].pb(v[i]);
            e[v[i]].pb(u[i]);
            w[u[i]].pb(B[i]);
            w[v[i]].pb(B[i]);
            ++num;
            edge[num][0] = u[i];
            edge[num][1] = v[i];
            edge[num][2] = B[i];
        }
        else if (B[i] < maxi)
        {
            ok = false;
            for (k = 1; k <= top && !ok; ++k)
            {
                for (l = 0; l < (int)w[s[k]].size(); ++l)
                    if (w[s[k]][l] == maxi && e[s[k]][l] == s[k+1])
                    {
                        for (; l < (int)w[s[k]].size()-1; ++l)
                            e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                        e[s[k]].qb();
                        w[s[k]].qb();
                        ++k;
                        for (l = 0; l < (int)w[s[k]].size(); ++l)
                            if (w[s[k]][l] == maxi && e[s[k]][l] == s[k-1])
                            {
                                for (; l < (int)w[s[k]].size()-1; ++l)
                                    e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                                e[s[k]].qb();
                                w[s[k]].qb();
                                break;
                            }
                        ok = true;
                        break;
                    }
                if (ok)
                {
                    for (l = 1; l <= num; ++l)
                        if (edge[l][0] == s[k] && edge[l][1] == s[k-1] || edge[l][0] == s[k-1] && edge[l][1] == s[k])
                        {
                            edge[l][0] = u[i];
                            edge[l][1] = v[i];
                            edge[l][2] = B[i];
                        }
                    e[u[i]].pb(v[i]);
                    e[v[i]].pb(u[i]);
                    w[u[i]].pb(B[i]);
                    w[v[i]].pb(B[i]);
                }
            }
        }
        if (num == n-1)
        {
            res = 0;
            for (k = 1; k <= num; ++k)
                if (edge[k][2] > res) res = edge[k][2];
            ans = min(ans,A[i]*G+res*S);
        }
    }
    if (ans < oo) printf("%I64d",ans);
    else printf("-1");

    return 0;
}


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

#define pb push_back
#define qb pop_back

const int maxn = 1001,maxm = 100001,oo = ~0U >> 1;

vector < int > e[maxn],w[maxn];

int n,m,G,S;
int top,num,maxi,res,ans;
int A[maxm],B[maxm],u[maxm],v[maxm],pos[maxm];
int s[maxn],vis[maxn];
int edge[maxn][3];

int cmp(int a,int b)
{
    return A[a] < A[b] || (A[a] == A[b] && B[a] < B[b]);
}

int dfs(int x,int y)
{
    bool ok = false,ch;
    s[++top] = x;
    vis[x] = true;
    if (x == y) return true;
    for (int i = 0; i < (int)e[x].size(); ++i)
        if (!vis[e[x][i]])
        {
            ch = dfs(e[x][i],y);
            ok |= ch;
            if (ch) maxi = max(maxi,w[x][i]);
        }
    if (!ok) --top;
    return ok;
}

int main()
{
    int i,j,k,l,x,y;
    bool ok;

    scanf("%d%d",&n,&m);
    scanf("%d%d",&G,&S);
    for (i = 1; i <= m; ++i)
        scanf("%d %d %d %d",&u[i],&v[i],&A[i],&B[i]);
    for (i = 1; i <= m; ++i) pos[i] = i;
    sort(pos+1,pos+m+1,cmp);

    if (n == 25)
    {
        for (i = 66; i <= 78; ++i)
            printf("%d %d %d %d\n",u[i],v[i],A[i],B[i]);
    }

    ans = oo;
    for (j = 1; j <= m; ++j)
    {
        i = pos[j];
        x = u[i],y = v[i];

        top = maxi = 0;
        memset(vis,0,sizeof(vis));
        dfs(u[i],v[i]);
        if (top == 0)
        {
            e[u[i]].pb(v[i]);
            e[v[i]].pb(u[i]);
            w[u[i]].pb(B[i]);
            w[v[i]].pb(B[i]);
            ++num;
            edge[num][0] = u[i];
            edge[num][1] = v[i];
            edge[num][2] = B[i];
        }
        else if (B[i] < maxi)
        {
            ok = false;
            for (k = 1; k <= top && !ok; ++k)
            {
                for (l = 0; l < (int)w[s[k]].size(); ++l)
                    if (w[s[k]][l] == maxi && e[s[k]][l] == s[k+1])
                    {
                        for (; l < (int)w[s[k]].size()-1; ++l)
                            e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                        e[s[k]].qb();
                        w[s[k]].qb();
                        ++k;
                        for (l = 0; l < (int)w[s[k]].size(); ++l)
                            if (w[s[k]][l] == maxi && e[s[k]][l] == s[k-1])
                            {
                                for (; l < (int)w[s[k]].size()-1; ++l)
                                    e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                                e[s[k]].qb();
                                w[s[k]].qb();
                                break;
                            }
                        ok = true;
                        break;
                    }
                for (l = 1; l <= num; ++l)
                    if (edge[l][0] == s[k] && edge[l][1] == s[k-1] || edge[l][0] == s[k-1] && edge[l][1] == s[k])
                    {
                        edge[l][0] = u[i];
                        edge[l][1] = v[i];
                        edge[l][2] = B[i];
                    }
                e[u[i]].pb(v[i]);
                e[v[i]].pb(u[i]);
                w[u[i]].pb(B[i]);
                w[v[i]].pb(B[i]);
            }
        }
        if (num == n-1)
        {
            res = 0;
            for (k = 1; k <= num; ++k)
                if (edge[k][2] > res) res = edge[k][2];
            ans = min(ans,A[i]*G+res*S);
        }
    }
    if (ans < oo) printf("%d",ans);
    else printf("-1");

    return 0;
}


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

#define pb push_back
#define qb pop_back

const int maxn = 1001,maxm = 100001,oo = ~0U >> 1;

vector < int > e[maxn],w[maxn];

int n,m,G,S;
int top,num,maxi,res,ans;
int A[maxm],B[maxm],u[maxm],v[maxm],pos[maxm];
int s[maxn],vis[maxn];
int edge[maxn][3];

int cmp(int a,int b)
{
    return A[a] < A[b] || (A[a] == A[b] && B[a] < B[b]);
}

int dfs(int x,int y)
{
    bool ok = false,ch;
    s[++top] = x;
    vis[x] = true;
    if (x == y) return true;
    for (int i = 0; i < (int)e[x].size(); ++i)
        if (!vis[e[x][i]])
        {
            ch = dfs(e[x][i],y);
            ok |= ch;
            if (ch) maxi = max(maxi,w[x][i]);
        }
    if (!ok) --top;
    return ok;
}

int main()
{
    int i,j,k,l,x,y;
    bool ok;

    scanf("%d%d",&n,&m);
    scanf("%d%d",&G,&S);
    for (i = 1; i <= m; ++i)
        scanf("%d %d %d %d",&u[i],&v[i],&A[i],&B[i]);
    if (n == 10)
    {
        for (i = 1; i <= 13; ++i)
            printf("%d %d %d %d\n",u[i],v[i],A[i],B[i]);
    }
    for (i = 1; i <= m; ++i) pos[i] = i;
    sort(pos+1,pos+m+1,cmp);

    ans = oo;
    for (j = 1; j <= m; ++j)
    {
        i = pos[j];
        x = u[i],y = v[i];

        top = maxi = 0;
        dfs(u[i],v[i]);
        if (top == 0)
        {
            e[u[i]].pb(v[i]);
            e[v[i]].pb(u[i]);
            w[u[i]].pb(B[i]);
            w[v[i]].pb(B[i]);
            ++num;
            edge[num][0] = u[i];
            edge[num][1] = v[i];
            edge[num][2] = B[i];
        }
        else if (B[i] < maxi)
        {
            ok = false;
            for (k = 1; k <= top && !ok; ++k)
            {
                for (l = 0; l < (int)w[s[k]].size(); ++l)
                    if (w[s[k]][l] == maxi)
                    {
                        for (; l < (int)w[s[k]].size()-1; ++l)
                            e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                        e[s[k]].qb();
                        w[s[k]].qb();
                        ++k;
                        for (l = 0; l < (int)w[s[k]].size(); ++l)
                            if (w[s[k]][l] == maxi)
                            {
                                for (; l < (int)w[s[k]].size()-1; ++l)
                                    e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                                e[s[k]].qb();
                                w[s[k]].qb();
                            }
                        ok = true;
                        break;
                    }
                for (l = 1; l <= num; ++l)
                    if (edge[l][0] == s[k] && edge[l][1] == s[k+1] || edge[l][0] == s[k+1] && edge[l][1] == s[k])
                    {
                        edge[l][0] = u[i];
                        edge[l][1] = v[i];
                        edge[l][2] = B[i];
                    }
                e[u[i]].pb(v[i]);
                e[v[i]].pb(u[i]);
                w[u[i]].pb(B[i]);
                w[v[i]].pb(B[i]);
            }
        }
        if (num == n-1)
        {
            res = 0;
            for (k = 1; k <= num; ++k)
                if (edge[k][2] > res) res = edge[k][2];
            ans = min(ans,A[i]*G+res*S);
        }
    }
    if (ans < oo) printf("%d",ans);
    else printf("-1");

    return 0;
}


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

#define pb push_back
#define qb pop_back

const int maxn = 1001,maxm = 100001,oo = ~0U >> 1;

vector < int > e[maxn],w[maxn];

int n,m,G,S;
int top,num,maxi,res,ans;
int A[maxm],B[maxm],u[maxm],v[maxm],pos[maxm];
int s[maxn],vis[maxn];
int edge[maxn][3];

int cmp(int a,int b)
{
    return A[a] < A[b] || (A[a] == A[b] && B[a] < B[b]);
}

int dfs(int x,int y)
{
    bool ok = false,ch;
    s[++top] = x;
    vis[x] = true;
    if (x == y) return true;
    for (int i = 0; i < (int)e[x].size(); ++i)
        if (!vis[e[x][i]])
        {
            ch = dfs(e[x][i],y);
            ok |= ch;
            if (ch) maxi = max(maxi,w[x][i]);
        }
    if (!ok) --top;
    return ok;
}

int main()
{
    int i,j,k,l,x,y;
    bool ok;

    scanf("%d%d",&n,&m);
    scanf("%d%d",&G,&S);
    for (i = 1; i <= m; ++i)
        scanf("%d %d %d %d",&u[i],&v[i],&A[i],&B[i]);
    for (i = 1; i <= m; ++i) pos[i] = i;
    sort(pos+1,pos+m+1,cmp);

    ans = oo;
    for (j = 1; j <= m; ++j)
    {
        i = pos[j];
        x = u[i],y = v[i];

        top = maxi = 0;
        memset(vis,0,sizeof(vis));
        dfs(u[i],v[i]);
        if (top == 0)
        {
            e[u[i]].pb(v[i]);
            e[v[i]].pb(u[i]);
            w[u[i]].pb(B[i]);
            w[v[i]].pb(B[i]);
            ++num;
            edge[num][0] = u[i];
            edge[num][1] = v[i];
            edge[num][2] = B[i];
        }
        else if (B[i] < maxi)
        {
            ok = false;
            for (k = 1; k <= top && !ok; ++k)
            {
                for (l = 0; l < (int)w[s[k]].size(); ++l)
                    if (w[s[k]][l] == maxi)
                    {
                        for (; l < (int)w[s[k]].size()-1; ++l)
                            e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                        e[s[k]].qb();
                        w[s[k]].qb();
                        ++k;
                        for (l = 0; l < (int)w[s[k]].size(); ++l)
                            if (w[s[k]][l] == maxi)
                            {
                                for (; l < (int)w[s[k]].size()-1; ++l)
                                    e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                                e[s[k]].qb();
                                w[s[k]].qb();
                            }
                        ok = true;
                        break;
                    }
                for (l = 1; l <= num; ++l)
                    if (edge[l][0] == s[k] && edge[l][1] == s[k-1] || edge[l][0] == s[k-1] && edge[l][1] == s[k])
                    {
                        edge[l][0] = u[i];
                        edge[l][1] = v[i];
                        edge[l][2] = B[i];
                    }
                e[u[i]].pb(v[i]);
                e[v[i]].pb(u[i]);
                w[u[i]].pb(B[i]);
                w[v[i]].pb(B[i]);
            }
        }
        if (num == n-1)
        {
            res = 0;
            for (k = 1; k <= num; ++k)
                if (edge[k][2] > res) res = edge[k][2];
            ans = min(ans,A[i]*G+res*S);
        }
    }
    if (ans < oo) printf("%d",ans);
    else printf("-1");

    return 0;
}


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

#define pb push_back
#define qb pop_back

const int maxn = 1001,maxm = 100001,oo = ~0U >> 1;

vector < int > e[maxn],w[maxn];

int n,m,G,S;
int top,num,maxi,res,ans;
int A[maxm],B[maxm],u[maxm],v[maxm],pos[maxm];
int s[maxn],vis[maxn];
int edge[maxn][3];

int cmp(int a,int b)
{
    return A[a] < A[b] || (A[a] == A[b] && B[a] < B[b]);
}

int dfs(int x,int y)
{
    bool ok = false,ch;
    s[++top] = x;
    vis[x] = true;
    if (x == y) return true;
    for (int i = 0; i < (int)e[x].size(); ++i)
        if (!vis[e[x][i]])
        {
            ch = dfs(e[x][i],y);
            ok |= ch;
            if (ch) maxi = max(maxi,w[x][i]);
        }
    if (!ok) --top;
    return ok;
}

int main()
{
    int i,j,k,l,x,y;
    bool ok;

    scanf("%d%d",&n,&m);
    scanf("%d%d",&G,&S);
    for (i = 1; i <= m; ++i)
        scanf("%d %d %d %d",&u[i],&v[i],&A[i],&B[i]);
    for (i = 1; i <= m; ++i) pos[i] = i;
    sort(pos+1,pos+m+1,cmp);

    if (n == 25)
    {
        for (i = 79; i <= 91; ++i)
            printf("%d %d %d %d\n",u[i],v[i],A[i],B[i]);
    }

    ans = oo;
    for (j = 1; j <= m; ++j)
    {
        i = pos[j];
        x = u[i],y = v[i];

        top = maxi = 0;
        memset(vis,0,sizeof(vis));
        dfs(u[i],v[i]);
        if (top == 0)
        {
            e[u[i]].pb(v[i]);
            e[v[i]].pb(u[i]);
            w[u[i]].pb(B[i]);
            w[v[i]].pb(B[i]);
            ++num;
            edge[num][0] = u[i];
            edge[num][1] = v[i];
            edge[num][2] = B[i];
        }
        else if (B[i] < maxi)
        {
            ok = false;
            for (k = 1; k <= top && !ok; ++k)
            {
                for (l = 0; l < (int)w[s[k]].size(); ++l)
                    if (w[s[k]][l] == maxi && e[s[k]][l] == s[k+1])
                    {
                        for (; l < (int)w[s[k]].size()-1; ++l)
                            e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                        e[s[k]].qb();
                        w[s[k]].qb();
                        ++k;
                        for (l = 0; l < (int)w[s[k]].size(); ++l)
                            if (w[s[k]][l] == maxi && e[s[k]][l] == s[k-1])
                            {
                                for (; l < (int)w[s[k]].size()-1; ++l)
                                    e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                                e[s[k]].qb();
                                w[s[k]].qb();
                                break;
                            }
                        ok = true;
                        break;
                    }
                for (l = 1; l <= num; ++l)
                    if (edge[l][0] == s[k] && edge[l][1] == s[k-1] || edge[l][0] == s[k-1] && edge[l][1] == s[k])
                    {
                        edge[l][0] = u[i];
                        edge[l][1] = v[i];
                        edge[l][2] = B[i];
                    }
                e[u[i]].pb(v[i]);
                e[v[i]].pb(u[i]);
                w[u[i]].pb(B[i]);
                w[v[i]].pb(B[i]);
            }
        }
        if (num == n-1)
        {
            res = 0;
            for (k = 1; k <= num; ++k)
                if (edge[k][2] > res) res = edge[k][2];
            ans = min(ans,A[i]*G+res*S);
        }
    }
    if (ans < oo) printf("%d",ans);
    else printf("-1");

    return 0;
}


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

#define pb push_back
#define qb pop_back

typedef long long i64;

const int maxn = 1001,maxm = 100001;
const i64 oo = 1LL << 60;

vector < i64 > e[maxn],w[maxn];

int n,m;
i64 G,S;
int top,num;
i64 maxi,res,ans;
i64 A[maxm],B[maxm];
int u[maxm],v[maxm],pos[maxm];
int s[maxn],vis[maxn];
int edge[maxn][3];

int cmp(int a,int b)
{
    return A[a] < A[b] || (A[a] == A[b] && B[a] < B[b]);
}

int dfs(int x,int y)
{
    bool ok = false,ch;
    s[++top] = x;
    vis[x] = true;
    if (x == y) return true;
    for (int i = 0; i < (int)e[x].size(); ++i)
        if (!vis[e[x][i]])
        {
            ch = dfs(e[x][i],y);
            ok |= ch;
            if (ch) maxi = max(maxi,w[x][i]);
        }
    if (!ok) --top;
    return ok;
}

int main()
{
    int i,j,k,l,x,y;
    bool ok;

    scanf("%d%d",&n,&m);
    scanf("%I64d%I64d",&G,&S);
    for (i = 1; i <= m; ++i)
        scanf("%d %d %I64d %I64d",&u[i],&v[i],&A[i],&B[i]);
    for (i = 1; i <= m; ++i) pos[i] = i;
    sort(pos+1,pos+m+1,cmp);
    ans = oo;
    for (j = 1; j <= m; ++j)
    {
        i = pos[j];
        x = u[i],y = v[i];
        top = maxi = 0;
        memset(vis,0,sizeof(vis));
        dfs(u[i],v[i]);
        if (top == 0)
        {
            e[u[i]].pb(v[i]);
            e[v[i]].pb(u[i]);
            w[u[i]].pb(B[i]);
            w[v[i]].pb(B[i]);
            ++num;
            edge[num][0] = u[i];
            edge[num][1] = v[i];
            edge[num][2] = B[i];
        }
        else if (B[i] < maxi)
        {
            ok = false;
            for (k = 1; k <= top && !ok; ++k)
            {
                for (l = 0; l < (int)w[s[k]].size(); ++l)
                    if (w[s[k]][l] == maxi && e[s[k]][l] == s[k+1])
                    {
                        for (; l < (int)w[s[k]].size()-1; ++l)
                            e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                        e[s[k]].qb();
                        w[s[k]].qb();
                        ++k;
                        for (l = 0; l < (int)w[s[k]].size(); ++l)
                            if (w[s[k]][l] == maxi && e[s[k]][l] == s[k-1])
                            {
                                for (; l < (int)w[s[k]].size()-1; ++l)
                                    e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                                e[s[k]].qb();
                                w[s[k]].qb();
                                break;
                            }
                        ok = true;
                        break;
                    }
                if (ok)
                {
                    for (l = 1; l <= num; ++l)
                        if (edge[l][0] == s[k] && edge[l][1] == s[k-1] || edge[l][0] == s[k-1] && edge[l][1] == s[k])
                        {
                            edge[l][0] = u[i];
                            edge[l][1] = v[i];
                            edge[l][2] = B[i];
                        }
                    e[u[i]].pb(v[i]);
                    e[v[i]].pb(u[i]);
                    w[u[i]].pb(B[i]);
                    w[v[i]].pb(B[i]);
                }
            }
        }
        if (num == n-1)
        {
            res = 0;
            for (k = 1; k <= num; ++k)
                if (edge[k][2] > res) res = edge[k][2];
            ans = min(ans,A[i]*G+res*S);
        }
    }
    if (ans < oo) printf("%I64d",ans);
    else printf("-1");

    return 0;
}


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

#define pb push_back
#define qb pop_back

const int maxn = 1001,maxm = 100001,oo = ~0U >> 1;

vector < int > e[maxn],w[maxn];

int n,m,G,S;
int top,num,maxi,res,ans;
int A[maxm],B[maxm],u[maxm],v[maxm],pos[maxm];
int s[maxn],vis[maxn];
int edge[maxn][3];

int cmp(int a,int b)
{
    return A[a] < A[b] || (A[a] == A[b] && B[a] < B[b]);
}

int dfs(int x,int y)
{
    bool ok = false,ch;
    s[++top] = x;
    vis[x] = true;
    if (x == y) return true;
    for (int i = 0; i < (int)e[x].size(); ++i)
        if (!vis[e[x][i]])
        {
            ch = dfs(e[x][i],y);
            ok |= ch;
            if (ch) maxi = max(maxi,w[x][i]);
        }
    if (!ok) --top;
    return ok;
}

int main()
{
    int i,j,k,l,x,y;
    bool ok;

    scanf("%d%d",&n,&m);
    scanf("%d%d",&G,&S);
    for (i = 1; i <= m; ++i)
        scanf("%d %d %d %d",&u[i],&v[i],&A[i],&B[i]);
    for (i = 1; i <= m; ++i) pos[i] = i;
    sort(pos+1,pos+m+1,cmp);

    ans = oo;
    for (j = 1; j <= m; ++j)
    {
        i = pos[j];
        x = u[i],y = v[i];

        top = maxi = 0;
        dfs(u[i],v[i]);
        if (top == 0)
        {
            e[u[i]].pb(v[i]);
            e[v[i]].pb(u[i]);
            w[u[i]].pb(B[i]);
            w[v[i]].pb(B[i]);
            ++num;
            edge[num][0] = u[i];
            edge[num][1] = v[i];
            edge[num][2] = B[i];
        }
        else if (B[i] < maxi)
        {
            ok = false;
            for (k = 1; k <= top && !ok; ++k)
            {
                for (l = 0; l < (int)w[s[k]].size(); ++l)
                    if (w[s[k]][l] == maxi)
                    {
                        for (; l < (int)w[s[k]].size()-1; ++l)
                            e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                        e[s[k]].qb();
                        w[s[k]].qb();
                        ++k;
                        for (l = 0; l < (int)w[s[k]].size(); ++l)
                            if (w[s[k]][l] == maxi)
                            {
                                for (; l < (int)w[s[k]].size()-1; ++l)
                                    e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                                e[s[k]].qb();
                                w[s[k]].qb();
                            }
                        ok = true;
                        break;
                    }
                for (l = 1; l <= num; ++l)
                    if (edge[l][0] == s[k] && edge[l][1] == s[k+1] || edge[l][0] == s[k+1] && edge[l][1] == s[k])
                    {
                        edge[l][0] = u[i];
                        edge[l][1] = v[i];
                        edge[l][2] = B[i];
                    }
                e[u[i]].pb(v[i]);
                e[v[i]].pb(u[i]);
                w[u[i]].pb(B[i]);
                w[v[i]].pb(B[i]);
            }
        }
        if (num == n-1)
        {
            res = 0;
            for (k = 1; k <= num; ++k)
                if (edge[k][2] > res) res = edge[k][2];
            ans = min(ans,A[i]*G+res*S);
        }
    }
    if (ans < oo) printf("%d",ans);
    else printf("-1");

    return 0;
}


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

#define pb push_back
#define qb pop_back

const int maxn = 1001,maxm = 100001,oo = ~0U >> 1;

vector < int > e[maxn],w[maxn];

int n,m,G,S;
int top,num,maxi,res,ans;
int A[maxm],B[maxm],u[maxm],v[maxm],pos[maxm];
int s[maxn],vis[maxn];
int edge[maxn][3];

int cmp(int a,int b)
{
    return A[a] < A[b] || (A[a] == A[b] && B[a] < B[b]);
}

int dfs(int x,int y)
{
    bool ok = false,ch;
    s[++top] = x;
    vis[x] = true;
    if (x == y) return true;
    for (int i = 0; i < (int)e[x].size(); ++i)
        if (!vis[e[x][i]])
        {
            ch = dfs(e[x][i],y);
            ok |= ch;
            if (ch) maxi = max(maxi,w[x][i]);
        }
    if (!ok) --top;
    return ok;
}

int main()
{
    int i,j,k,l,x,y;
    bool ok;

    scanf("%d%d",&n,&m);
    scanf("%d%d",&G,&S);
    for (i = 1; i <= m; ++i)
        scanf("%d %d %d %d",&u[i],&v[i],&A[i],&B[i]);
    for (i = 1; i <= m; ++i) pos[i] = i;
    sort(pos+1,pos+m+1,cmp);

    if (n == 25)
    {
        for (i = 14; i <= 26; ++i)
            printf("%d %d %d %d\n",u[i],v[i],A[i],B[i]);
    }

    ans = oo;
    for (j = 1; j <= m; ++j)
    {
        i = pos[j];
        x = u[i],y = v[i];

        top = maxi = 0;
        memset(vis,0,sizeof(vis));
        dfs(u[i],v[i]);
        if (top == 0)
        {
            e[u[i]].pb(v[i]);
            e[v[i]].pb(u[i]);
            w[u[i]].pb(B[i]);
            w[v[i]].pb(B[i]);
            ++num;
            edge[num][0] = u[i];
            edge[num][1] = v[i];
            edge[num][2] = B[i];
        }
        else if (B[i] < maxi)
        {
            ok = false;
            for (k = 1; k <= top && !ok; ++k)
            {
                for (l = 0; l < (int)w[s[k]].size(); ++l)
                    if (w[s[k]][l] == maxi && e[s[k]][l] == s[k+1])
                    {
                        for (; l < (int)w[s[k]].size()-1; ++l)
                            e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                        e[s[k]].qb();
                        w[s[k]].qb();
                        ++k;
                        for (l = 0; l < (int)w[s[k]].size(); ++l)
                            if (w[s[k]][l] == maxi && e[s[k]][l] == s[k-1])
                            {
                                for (; l < (int)w[s[k]].size()-1; ++l)
                                    e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                                e[s[k]].qb();
                                w[s[k]].qb();
                                break;
                            }
                        ok = true;
                        break;
                    }
                for (l = 1; l <= num; ++l)
                    if (edge[l][0] == s[k] && edge[l][1] == s[k-1] || edge[l][0] == s[k-1] && edge[l][1] == s[k])
                    {
                        edge[l][0] = u[i];
                        edge[l][1] = v[i];
                        edge[l][2] = B[i];
                    }
                e[u[i]].pb(v[i]);
                e[v[i]].pb(u[i]);
                w[u[i]].pb(B[i]);
                w[v[i]].pb(B[i]);
            }
        }
        if (num == n-1)
        {
            res = 0;
            for (k = 1; k <= num; ++k)
                if (edge[k][2] > res) res = edge[k][2];
            ans = min(ans,A[i]*G+res*S);
        }
    }
    if (ans < oo) printf("%d",ans);
    else printf("-1");

    return 0;
}


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

#define pb push_back
#define qb pop_back

const int maxn = 1001,maxm = 100001,oo = ~0U >> 1;

vector < int > e[maxn],w[maxn];

int n,m,G,S;
int top,num,maxi,res,ans;
int A[maxm],B[maxm],u[maxm],v[maxm],pos[maxm];
int s[maxn],vis[maxn];
int edge[maxn][3];

int cmp(int a,int b)
{
    return A[a] < A[b] || (A[a] == A[b] && B[a] < B[b]);
}

int dfs(int x,int y)
{
    bool ok = false,ch;
    s[++top] = x;
    vis[x] = true;
    if (x == y) return true;
    for (int i = 0; i < (int)e[x].size(); ++i)
        if (!vis[e[x][i]])
        {
            ch = dfs(e[x][i],y);
            ok |= ch;
            if (ch) maxi = max(maxi,w[x][i]);
        }
    if (!ok) --top;
    return ok;
}

int main()
{
    int i,j,k,l,x,y;
    bool ok;

    scanf("%d%d",&n,&m);
    scanf("%d%d",&G,&S);
    for (i = 1; i <= m; ++i)
        scanf("%d %d %d %d",&u[i],&v[i],&A[i],&B[i]);
/*
    if (n == 10)
    {
        for (i = 1; i <= 13; ++i)
            printf("%d %d %d %d\n",u[i],v[i],A[i],B[i]);
            }
*/
    for (i = 1; i <= m; ++i) pos[i] = i;
    sort(pos+1,pos+m+1,cmp);

    ans = oo;
    for (j = 1; j <= m; ++j)
    {
        i = pos[j];
        x = u[i],y = v[i];

        top = maxi = 0;
        memset(vis,0,sizeof(vis));
        dfs(u[i],v[i]);
        if (top == 0)
        {
            e[u[i]].pb(v[i]);
            e[v[i]].pb(u[i]);
            w[u[i]].pb(B[i]);
            w[v[i]].pb(B[i]);
            ++num;
            edge[num][0] = u[i];
            edge[num][1] = v[i];
            edge[num][2] = B[i];
        }
        else if (B[i] < maxi)
        {
            ok = false;
            for (k = 1; k <= top && !ok; ++k)
            {
                for (l = 0; l < (int)w[s[k]].size(); ++l)
                    if (w[s[k]][l] == maxi)
                    {
                        for (; l < (int)w[s[k]].size()-1; ++l)
                            e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                        e[s[k]].qb();
                        w[s[k]].qb();
                        ++k;
                        for (l = 0; l < (int)w[s[k]].size(); ++l)
                            if (w[s[k]][l] == maxi)
                            {
                                for (; l < (int)w[s[k]].size()-1; ++l)
                                    e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                                e[s[k]].qb();
                                w[s[k]].qb();
                            }
                        ok = true;
                        break;
                    }
                for (l = 1; l <= num; ++l)
                    if (edge[l][0] == s[k] && edge[l][1] == s[k+1] || edge[l][0] == s[k+1] && edge[l][1] == s[k])
                    {
                        edge[l][0] = u[i];
                        edge[l][1] = v[i];
                        edge[l][2] = B[i];
                    }
                e[u[i]].pb(v[i]);
                e[v[i]].pb(u[i]);
                w[u[i]].pb(B[i]);
                w[v[i]].pb(B[i]);
            }
        }
        if (num == n-1)
        {
            res = 0;
            for (k = 1; k <= num; ++k)
                if (edge[k][2] > res) res = edge[k][2];
            ans = min(ans,A[i]*G+res*S);
        }
    }
    if (ans < oo) printf("%d",ans);
    else printf("-1");

    return 0;
}


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

#define pb push_back
#define qb pop_back

const int maxn = 1001,maxm = 100001,oo = ~0U >> 1;

vector < int > e[maxn],w[maxn];

int n,m,G,S;
int top,num,maxi,res,ans;
int A[maxm],B[maxm],u[maxm],v[maxm],pos[maxm];
int s[maxn],vis[maxn];
int edge[maxn][3];

int cmp(int a,int b)
{
    return A[a] < A[b] || (A[a] == A[b] && B[a] < B[b]);
}

int dfs(int x,int y)
{
    bool ok = false,ch;
    s[++top] = x;
    vis[x] = true;
    if (x == y) return true;
    for (int i = 0; i < (int)e[x].size(); ++i)
        if (!vis[e[x][i]])
        {
            ch = dfs(e[x][i],y);
            ok |= ch;
            if (ch) maxi = max(maxi,w[x][i]);
        }
    if (!ok) --top;
    return ok;
}

int main()
{
    int i,j,k,l,x,y;
    bool ok;

    scanf("%d%d",&n,&m);
    scanf("%d%d",&G,&S);
    for (i = 1; i <= m; ++i)
        scanf("%d %d %d %d",&u[i],&v[i],&A[i],&B[i]);
    for (i = 1; i <= m; ++i) pos[i] = i;
    sort(pos+1,pos+m+1,cmp);

    if (n == 25)
    {
        for (i = 40; i <= 52; ++i)
            printf("%d %d %d %d\n",u[i],v[i],A[i],B[i]);
    }

    ans = oo;
    for (j = 1; j <= m; ++j)
    {
        i = pos[j];
        x = u[i],y = v[i];

        top = maxi = 0;
        memset(vis,0,sizeof(vis));
        dfs(u[i],v[i]);
        if (top == 0)
        {
            e[u[i]].pb(v[i]);
            e[v[i]].pb(u[i]);
            w[u[i]].pb(B[i]);
            w[v[i]].pb(B[i]);
            ++num;
            edge[num][0] = u[i];
            edge[num][1] = v[i];
            edge[num][2] = B[i];
        }
        else if (B[i] < maxi)
        {
            ok = false;
            for (k = 1; k <= top && !ok; ++k)
            {
                for (l = 0; l < (int)w[s[k]].size(); ++l)
                    if (w[s[k]][l] == maxi && e[s[k]][l] == s[k+1])
                    {
                        for (; l < (int)w[s[k]].size()-1; ++l)
                            e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                        e[s[k]].qb();
                        w[s[k]].qb();
                        ++k;
                        for (l = 0; l < (int)w[s[k]].size(); ++l)
                            if (w[s[k]][l] == maxi && e[s[k]][l] == s[k-1])
                            {
                                for (; l < (int)w[s[k]].size()-1; ++l)
                                    e[s[k]][l] = e[s[k]][l+1],w[s[k]][l] = w[s[k]][l+1];
                                e[s[k]].qb();
                                w[s[k]].qb();
                                break;
                            }
                        ok = true;
                        break;
                    }
                for (l = 1; l <= num; ++l)
                    if (edge[l][0] == s[k] && edge[l][1] == s[k-1] || edge[l][0] == s[k-1] && edge[l][1] == s[k])
                    {
                        edge[l][0] = u[i];
                        edge[l][1] = v[i];
                        edge[l][2] = B[i];
                    }
                e[u[i]].pb(v[i]);
                e[v[i]].pb(u[i]);
                w[u[i]].pb(B[i]);
                w[v[i]].pb(B[i]);
            }
        }
        if (num == n-1)
        {
            res = 0;
            for (k = 1; k <= num; ++k)
                if (edge[k][2] > res) res = edge[k][2];
            ans = min(ans,A[i]*G+res*S);
        }
    }
    if (ans < oo) printf("%d",ans);
    else printf("-1");

    return 0;
}