func_code_string: #include <bits/stdc++.h>   using namespace std;   void Get(int &T) {     char C;     bool F = 0;     for (; C = getchar(), C <  0  || C >  9 ;)       if (C ==  - ) F = 1;     for (T = C -  0 ; C = getchar(), C >=  0  && C <=  9 ; T = T * 10 + C -  0 )       ;     F && (T = -T);   }   void Get(long long &T) {     char C;     bool F = 0;     for (; C = getchar(), C <  0  || C >  9 ;)       if (C ==  - ) F = 1;     for (T = C -  0 ; C = getchar(), C >=  0  && C <=  9 ; T = T * 10 + C -  0 )       ;     F && (T = -T);   }   int U[50005];   int V[50005];   int W[50005];   int W2[50005];   int Order[50005];   int N, M;   bool Cmp(int X, int Y) { return W2[X] < W2[Y]; }   long long C1, C2;   void Init() {     Get(N);     Get(M);     Get(C1);     Get(C2);     for (int i = 1; i <= M; i++) {       Get(U[i]);       Get(V[i]);       Get(W[i]);       Get(W2[i]);       Order[i] = i;     }     std::sort(Order + 1, Order + M + 1, Cmp);   }   bool Delete[100005];   struct E {     int V, W, Next;   } Edge[100005];   int EdgeTop = 1;   int Head[205];   void Add(int U, int V, int W) {     Edge[++EdgeTop] = (E){V, W, Head[U]};     Head[U] = EdgeTop;   }   int Visited[205];   int Time;   int StackAns[205];   int StackX[205];   int Stacki[205];   multiset<int> Hash;   int DFS(int X, int Y) {     int Top = 1, i;     StackX[Top] = X;   Call:     X = StackX[Top];     if (X == Y) {       int Max = StackAns[1];       for (int i = 2; i < Top; i++) {         if (Edge[StackAns[i]].W > Edge[Max].W) Max = StackAns[i];       }       return Max;     }     Visited[X] = Time;     for (; Delete[Head[X]]; Head[X] = Edge[Head[X]].Next)       ;     for (i = Head[X]; i; i = Edge[i].Next) {       if (Visited[Edge[i].V] != Time) {         StackAns[Top] = i;         StackX[Top + 1] = Edge[i].V;         Stacki[Top] = i;         Top++;         goto Call;       Return:         Top--;         X = StackX[Top];         i = Stacki[Top];       }       for (; Delete[Edge[i].Next]; Edge[i].Next = Edge[Edge[i].Next].Next)         ;     }     if (Top >= 2) goto Return;     return -1;   }   long long Ans;   void Work() {     Ans = 0x2f2f2f2f2f2f2f2fll;     for (int k = 1, i; k <= M; k++) {       i = Order[k];       if (U[i] == V[i]) continue;       Time++;       int Max = DFS(U[i], V[i]);       if (Max == -1) {         Hash.insert(W[i]);         Add(U[i], V[i], W[i]);         Add(V[i], U[i], W[i]);       } else if (Edge[Max].W > W[i]) {         Delete[Max] = Delete[Max ^ 1] = 1;         Hash.erase(Hash.find(Edge[Max].W));         Hash.insert(W[i]);         Add(U[i], V[i], W[i]);         Add(V[i], U[i], W[i]);       }       if (Hash.size() == N - 1) {         long long Ans0 = *Hash.rbegin() * C1 + W2[i] * C2;         if (Ans > Ans0) Ans = Ans0;       }     }   }   void Output() {     if (Ans >= 0x2f2f2f2f2f2f2f2fll)       puts( -1 );     else       printf( %I64d n , Ans);   }   int main() {     Init();     Work();     Output();     return 0;   }   