#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    int a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
vector<kra> acc_kras;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    if(fx == fy) {
        return;
    }
    if(fsize[fx] > fsize[fy]) {
        fsize[fx] += fsize[fy];
        fu[fy] = fx;
    } else {
        fsize[fy] += fsize[fx];
        fu[fx] = fy;
    }
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

LL mini = (LL)INF * INF;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras.push_back(kras[i]);
        finit();
        sort(ALL(acc_kras), comp_s);
        int dod = 0;
        int maxi_s = 0;

        F(kr, 0 , acc_kras.size()) {
            kra it = acc_kras[kr];
            if(dod==n-1) break;
            int fa = find(it.a);
            int fb = find(it.b);

            if(fa == fb) {
                continue;
            }
            dod++;
            maxi_s = it.s;
            funion(fa,fb);
        }

        if(dod == n-1) {
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    cout<<mini<<endl;
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    int a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            }
        }
        int dod = 0;
        int maxi_s = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);

            if(fa == fb) {
                continue;
            }
            maxi_s = it.s;
            funion(fa,fb);
            swpa(acc_kras[dod++], acc_kras[j]);
        }

        if(dod == n-1) {
                found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    int a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-2, 0) {
            if(acc_kras[j].s > acc_kras[j+1].s) {
                swap(acc_kras[j], acc_kras[j+1]);
            }
        }
        int dod = 0;
        int maxi_s = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);
            if(dod == n-1) break;
            if(fa == fb) {
                continue;
            }
            maxi_s = it.s;
            funion(fa,fb);
            acc_kras[dod++] = it;
        }

        if(dod == n-1) {
                found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    LL a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            } else {
                break;
            }
        }
        int dod = 0;
        LL maxi_s = 0;
        LL maxi_g = 0;

        F(kr, 0 , i+1) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);

            if(fa == fb) {
                continue;
            }
            maxi_s = max(maxi_s,it.s);
            maxi_g = max(maxi_g, it.g);
            funion(fa,fb);
            acc_kras[dod++] = it;

            if(dod == n-1) break;
        }

        if(dod == n-1) {

            found = true;
            mini = min(mini, gm*maxi_g + sm * maxi_s);
        }
        cnt_kras = dod;

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    LL a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            } else {
                break;
            }
        }
        int dod = 0;
        LL maxi_s = 0;
        LL maxi_g = 0;

        F(kr, 0 , i+1) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);
            if(dod == n-1) break;
            if(fa == fb) {
                continue;
            }
            maxi_s = max(maxi_s,it.s);
            maxi_g = max(maxi_g, it.g);
            funion(fa,fb);
            acc_kras[dod++] = it;
        }

        if(dod == n-1) {
            cnt_kras = n-1;
            found = true;
            mini = min(mini, gm*maxi_g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    int a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = (LL)INF * INF;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(i, cnt_kras-1, 1) {
            if(acc_kras[i].s < acc_kras[i-1].s) {
                kra kr = acc_kras[i];
                acc_kras[i] = acc_kras[i-1];
                acc_kras[i-1] = kr;
            }
        }
        int dod = 0;
        int maxi_s = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            if(dod==n-1) break;
            int fa = find(it.a);
            int fb = find(it.b);

            if(fa == fb) {
                continue;
            }
            dod++;
            maxi_s = it.s;
            funion(fa,fb);
        }

        if(dod == n-1) {
                found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    LL a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            }
        }
        int dod = 0;
        LL maxi_s = 0;
        LL maxi_g = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);
            if(dod == n-1) break;
            if(fa == fb) {
                continue;
            }
            maxi_s = max(maxi_s,it.s);
            maxi_g = max(maxi_g, it.g);
            funion(fa,fb);
            acc_kras[dod++] = it;
        }

        if(dod == n-1) {
            cnt_kras = n-1;
            found = true;
            mini = min(mini, gm*maxi_g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    LL a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            } else {
                    break;
            }

        }
        int dod = 0;
        LL maxi_s = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);
            if(dod == n-1) break;
            if(fa == fb) {
                continue;
            }
            maxi_s = max(maxi_s,it.s);
            funion(fa,fb);
            acc_kras[dod++] = it;
        }

        if(dod == n-1) {
            found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    int a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = (LL)INF * INF;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            }
        }
        int dod = 0;
        int maxi_s = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            if(dod==n-1) break;
            int fa = find(it.a);
            int fb = find(it.b);

            if(fa == fb) {
                continue;
            }
            dod++;
            maxi_s = it.s;
            funion(fa,fb);
            acc_kras[dod-1] = it;
        }

        if(dod == n-1) {
                found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    LL a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            } else {
                break;
            }
        }
        int dod = 0;
        LL maxi_s = 0;
        LL maxi_g = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);

            if(fa == fb) {
                continue;
            }
            maxi_s = max(maxi_s,it.s);
            maxi_g = max(maxi_g, it.g);
            funion(fa,fb);
            acc_kras[dod++] = it;

            if(dod == n-1) break;
        }

        if(dod == n-1) {

            found = true;
            mini = min(mini, gm*maxi_g + sm * maxi_s);
        }
        cnt_kras = dod;

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    int a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = (LL)INF * INF;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            }
        }
        int dod = 0;
        int maxi_s = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            if(dod==n-1) break;
            int fa = find(it.a);
            int fb = find(it.b);

            if(fa == fb) {
                continue;
            }
            dod++;
            maxi_s = it.s;
            funion(fa,fb);
            //acc_kras[dod-1] = it;
        }

        if(dod == n-1) {
                found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    LL a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            } else {
                    break;
            }

        }
        int dod = 0;
        LL maxi_s = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);
            if(dod == n-1) break;
            if(fa == fb) {
                continue;
            }
            maxi_s = it.s;
            funion(fa,fb);
            acc_kras[dod++] = it;
        }

        if(dod == n-1) {
            found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    LL a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            }
        }
        int dod = 0;
        LL maxi_s = 0;
        LL maxi_g = 0;

        F(kr, 0 , i+1) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);
            if(dod == n-1) break;
            if(fa == fb) {
                continue;
            }
            maxi_s = max(maxi_s,it.s);
            maxi_g = max(maxi_g, it.g);
            funion(fa,fb);
            acc_kras[dod++] = it;
        }

        if(dod == n-1) {
           //cnt_kras = n-1;
            found = true;
            mini = min(mini, gm*maxi_g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    LL a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            } else {
                    break;
            }
        }
        int dod = 0;
        LL maxi_s = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);
            if(dod == n-1) break;
            if(fa == fb) {
                continue;
            }
            maxi_s = max(maxi_s,it.s);
            funion(fa,fb);
            acc_kras[dod++] = it;
        }

        if(dod == n-1) {
                cnt_kras = n-1;
            found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    int a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            }
        }
        int dod = 0;
        int maxi_s = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);

            if(fa == fb) {
                continue;
            }
            maxi_s = it.s;
            funion(fa,fb);
            acc_kras[dod++] = it;
        }

        if(dod == n-1) {
                found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    LL a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            }
        }
        int dod = 0;
        LL maxi_s = 0;
        LL maxi_g = 0;

        F(kr, 0 , i) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);
            if(dod == n-1) break;
            if(fa == fb) {
                continue;
            }
            maxi_s = max(maxi_s,it.s);
            maxi_g = max(maxi_g, it.g);
            funion(fa,fb);
            acc_kras[dod++] = it;
        }

        if(dod == n-1) {
            cnt_kras = n-1;
            found = true;
            mini = min(mini, gm*maxi_g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    int a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
vector<kra> acc_kras;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    if(fx == fy) {
        return;
    }
    if(fsize[fx] > fsize[fy]) {
        fsize[fx] += fsize[fy];
        fu[fy] = fx;
    } else {
        fsize[fy] += fsize[fx];
        fu[fx] = fy;
    }
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = (LL)INF * INF;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras.push_back(kras[i]);
        finit();
        sort(ALL(acc_kras), comp_s);
        int dod = 0;
        int maxi_s = 0;

        F(kr, 0 , acc_kras.size()) {
            kra it = acc_kras[kr];
            if(dod==n-1) break;
            int fa = find(it.a);
            int fb = find(it.b);

            if(fa == fb) {
                continue;
            }
            dod++;
            maxi_s = it.s;
            funion(fa,fb);
        }

        if(dod == n-1) {
                found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    int a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    if(fx == fy) {
        return;
    }
    if(fsize[fx] > fsize[fy]) {
        fsize[fx] += fsize[fy];
        fu[fy] = fx;
    } else {
        fsize[fy] += fsize[fx];
        fu[fx] = fy;
    }
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = (LL)INF * INF;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(i, cnt_kras-1, 1) {
            if(acc_kras[i].s < acc_kras[i-1].s) {
                kra kr = acc_kras[i];
                acc_kras[i] = acc_kras[i-1];
                acc_kras[i-1] = kr;
            }
        }
        int dod = 0;
        int maxi_s = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            if(dod==n-1) break;
            int fa = find(it.a);
            int fb = find(it.b);

            if(fa == fb) {
                continue;
            }
            dod++;
            maxi_s = it.s;
            funion(fa,fb);
        }

        if(dod == n-1) {
                found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    LL a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            } else {
                break;
            }
        }
        int dod = 0;
        LL maxi_s = 0;
        LL maxi_g = 0;

        F(kr, 0 , i+1) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);
            if(dod == n-1) break;
            if(fa == fb) {
                continue;
            }
            maxi_s = max(maxi_s,it.s);
            maxi_g = max(maxi_g, it.g);
            funion(fa,fb);
            //swap(acc_kras[dod++], acc_kras[kr]);
        }

        if(dod == n-1) {
           //cnt_kras = n-1;
            found = true;
            mini = min(mini, gm*maxi_g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    int a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = 2e18;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(j, cnt_kras-1, 1) {
            if(acc_kras[j].s < acc_kras[j-1].s) {
                swap(acc_kras[j], acc_kras[j-1]);
            }
        }
        int dod = 0;
        int maxi_s = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            int fa = find(it.a);
            int fb = find(it.b);

            if(fa == fb) {
                continue;
            }
            maxi_s = it.s;
            funion(fa,fb);
            acc_kras[++dod] = it;
        }

        if(dod == n-1) {
                found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <bits/stdc++.h>
#include <iomanip>      // std::setprecision
using namespace std;
#define what_is(x) cerr << #x << " is " << x << endl;
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define abs(x) (x<0?(-x):x) // big bug here if "-x" is not surrounded by "()"
#define IN(i,l,r) (l<i&&i<r) //the next for are for checking bound
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define F(i,L,R) for (int i = L; i < R; i++) //next four are for "for loops"
#define FE(i,L,R) for (int i = L; i <= R; i++)
#define FF(i,L,R) for (int i = L; i > R; i--)
#define FFE(i,L,R) for (int i = L; i >= R; i--)
#define char2Int(c) (c-'0')
#define lastEle(vec) vec[vec.size()-1]
#define SZ(x) ((int)((x).size()))
#define REMAX(a,b) (a)=max((a),(b)) // set a to the maximum of a and b
#define REMIN(a,b) (a)=min((a),(b));
#define FENWICK(k) (k&-k)
#define FOREACH(i,t) for (auto i=t.begin(); i!=t.end(); i++) // traverse an STL data structure
#define ALL(c) (c).begin(),(c).end() //handy for function like "sort()"
#define PRESENT(c,x) ((c).find(x) != (c).end())
#define CPRESENT(c,x) (find(ALL(c),x) != (c).end())
#define LL long long //data types used often, but you don't want to type them time by time
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define IOS ios_base::sync_with_stdio(0); //to synchronize the input of cin and scanf
#define INF 1001001001
#define PI 3.1415926535897932384626
//for map, pair
#define mp make_pair
#define fi first
#define se second
//for vectors
#define pb push_back
typedef int elem_t;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
// directions
const int fx[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
const int fxx[8][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}, {1,1}, {1,-1}, {-1,1}, {-1,-1}};
const int rogi[4][2] = { {1,1}, {1,-1}};

int n,m;
struct kra {
    int a,b,g,s;
};

bool comp_g(kra a, kra b) {
    return a.g < b.g;
}

bool comp_s(kra a, kra b) {
    return a.s < b.s;
}

vector<kra> kras;
kra acc_kras[111111];
int cnt_kras = 0;

int fu[111111];
int fsize[111111];

int find(int x) {
    if(fu[x] == x) return fu[x];
    fu[x] = find(fu[x]);
    return fu[x];
}

void funion(int x, int y) {
    int fx = find(x);
    int fy = find(y);
    fu[fx] = fy;
}

void finit() {
    F(i,1,n+1) {
        fu[i] = i;
        fsize[i] = i;
    }
}

bool found = false;
LL mini = (LL)INF * INF;
LL gm, sm;
void dane() {
    cin>>n>>m;
    cin>>gm>>sm;
    F(i,0,m) {
        kra k;
        cin>>k.a>>k.b>>k.g>>k.s;
        kras.push_back(k);
    }
    sort(ALL(kras), comp_g);

    //szukaj
    F(i,0,m) {
        //dodaj KR
        acc_kras[cnt_kras++] = kras[i];
        finit();
        FFE(i, cnt_kras-1, 1) {
            if(acc_kras[i].s < acc_kras[i-1].s) {
                swap(acc_kras[i], acc_kras[i-1]);
            }
        }
        int dod = 0;
        int maxi_s = 0;

        F(kr, 0 , cnt_kras) {
            kra it = acc_kras[kr];
            if(dod==n-1) break;
            int fa = find(it.a);
            int fb = find(it.b);

            if(fa == fb) {
                continue;
            }
            dod++;
            maxi_s = it.s;
            funion(fa,fb);
            acc_kras[dod] = it;
        }

        if(dod == n-1) {
                found = true;
            mini = min(mini, gm*kras[i].g + sm * maxi_s);
        }

    }
    if(found)
    cout<<mini<<endl;
    else
        cout<<"-1\n";
}

int main() {
	IOS
	// int t;
	// cin>>t;
	// F(i,0,t)
	    dane();
    return 0;
}


#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <cstdio>
#include <vector>
#include <utility>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define INF 1e9
#define pb push_back
#define mp make_pair
#define forn(i,n) for (int i = 0; i < n; i++)
#define MAXN 300000

using namespace std;

typedef long long ll;

string vw = "aeiouAEIOU";
string s;
int n;
int sum[MAXN];
vector <pair <int, int> > d;

bool isv(char c)
{
    forn (i, vw.size())
    {
        if (c == vw[i])
            return true;
    }
    return false;
}

bool check(int l, int r)
{
    return 0 == (l ? sum[r] - sum[l - 1] : sum[r]);
}

int main()
{
    //freopen("input.txt", "r", stdin);
    cin >> s;
    n = s.size();
    forn (i, n)
    {
        sum[i + 1] = sum[i];
        sum[i + 1] += isv(s[i]) ? -1 : 2;
        d.pb(mp(sum[i + 1], i + 1));
    }
    d.pb(mp(0, 0));
    sort(d.begin(), d.end());
    int i = 0, j = 0, ans = 0, spree = 0;
    if (sum[n - 1] >= 0)
    {
        printf("%d 1", n);
        return 0;
    }
    if (sum[n] == -n)
    {
        printf("No solution");
        return 0;
    }
    while (i < n && j < n)
    {
        if (d[i].first == d[j].first)
        {
            if (ans == (d[j].second - d[i].second))
            {
                spree++;
            }
            if (ans < (d[j].second - d[i].second))
            {
                ans = d[j].second - d[i].second;
                spree = 1;
            }
            j++;
        }
        else
        {
            i = j;
        }
    }
    printf("%d %d", ans, spree);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 1, r = len;
    int ans, count;
    int best = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    if (best == -1) printf("No solution\n");
    else printf("%d %d\n", best, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 0, r = len;
    int ans;
    while (l <= r) {
        int m = (l + r) / 2;
        int count = ok(m, len);
        if (count > 0) {
           l = m + 1;
           ans = count;
        } else r = m - 1;
    }
    if ((l + r) / 2 == 0) printf("No solution\n");
    else printf("%d %d\n", (l + r) / 2, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 1, r = len;
    int ans, count;
    int best = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    if (best <= 0) printf("No solution\n");
    else printf("%d %d\n", best, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    //if (m == 0) return 1;
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 0, r = len;
    int ans, count, best = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    if (best <= 0) printf("No solution\n");
    else printf("%d %d\n", best, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 1, r = len;
    int ans, count;
    int best = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    if ((count = ok((l + r) / 2, len)) > 0 && (l + r) / 2 > best) {
        best = (l + r) / 2;
        ans = count;
    }
    if (best == -1) printf("No solution\n");
    else printf("%d %d\n", best, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    if (m == 0) return 0;
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 1, r = len;
    int ans, count;
    int best = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    int m = (l + r) / 2;
    count = ok(m, len);
    if (count > 0 && best < m) {
       best = m;
       ans = count;
    }
    if (best == -1) printf("No solution\n");
    else printf("%d %d\n", best, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = -1, r = len;
    int ans, count, best = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    if (best <= 0) printf("No solution\n");
    else printf("%d %d\n", best, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    if (m == 0) return 1;
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 0, r = len;
    int ans, count;
    int best = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    if (best <= 0) printf("No solution\n");
    else printf("%d %d\n", best, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 1, r = len;
    int ans, count;
    int best = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    int m = (l + r) / 2;
    count = ok(m, len);
    if (count > 0 && best < m) {
       best = m;
       ans = count;
    }
    if (best == -1) printf("No solution\n");
    else printf("%d %d\n", best, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;

    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 0, r = len;
    int ans, count, best = -1;
    while (l <= r) {
        int m = (l + r + 1) / 2;
        count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    if (best <= 0) printf("No solution\n");
    else printf("%d %d\n", best, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    if (m == 0) return 1;
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 0, r = len;
    int ans, count, best = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    if (best <= 0) printf("No solution\n");
    else printf("%d %d\n", best, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    if (m == 0) return 0;
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 1, r = len;
    int ans, count;
    int best = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    if (best == -1) printf("No solution\n");
    else printf("%d %d\n", best, ans);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 0, r = len;
    int ans;
    while (l <= r) {
        int m = (l + r) / 2;
        int count = ok(m, len);
        if (count > 0) {
           l = m + 1;
           ans = count;
        } else r = m - 1;
    }
    if ((l + r) / 2 == 0) printf("No solution\n");
    else printf("%d %d\n", (l + r) / 2, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 1, r = len;
    int ans;
    int best = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        int count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    if (best == -1) printf("No solution\n");
    else printf("%d %d\n", best, ans);
    return 0;
}


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

using namespace std;

const int MAXN = 200000;
char s[MAXN + 10];

int getC(char c) {
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') return 0;
    if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') return 0;
    return 1;
}

int ok(int m, int len) {
    int count = 0, c0 = 0, c1 = 0;
    for (int i = 0; i < m; i++) {
        if (getC(s[i]) == 0) c0++;
        else c1++;
    }
    if (c0 <= 2 * c1) count++;
    for (int i = m; i < len; i++) {
        if (getC(s[i - m]) == 0) c0--;
        else c1--;
        if (getC(s[i]) == 0) c0++;
        else c1++;
        if (c0 <= 2 * c1) count++;
    }
    return count;
}

int main() {
    scanf("%s", s);
    int len = strlen(s);
    int l = 1, r = len;
    int ans;
    int best = -1;
    while (l <= r) {
        int m = (l + r) / 2;
        int count = ok(m, len);
        if (count > 0) {
           if (best < m) {
               best = m;
               ans = count;
           }
           l = m + 1;
        } else r = m - 1;
    }
    if (best == -1) printf("No solution\n");
    else printf("%d %d\n", (l + r) / 2, ans);
    return 0;
}