Problem:
Score : 100 points

Problem Statement

N of us are going on a trip, by train or taxi.

The train will cost each of us A yen (the currency of Japan).

The taxi will cost us a total of B yen.

How much is our minimum total travel expense?

Constraints

All values in input are integers.

1 \leq N \leq 20

1 \leq A \leq 50

1 \leq B \leq 50

Input

Input is given from Standard Input in the following format:

N A B

Output

Print an integer representing the minimum total travel expense.

Sample Input 1

4 2 9

Sample Output 1

8

The train will cost us 4 \times 2 = 8 yen, and the taxi will cost us 9 yen, so the minimum total travel expense is 8 yen.

Sample Input 2

4 2 7

Sample Output 2

7

Sample Input 3

4 2 8

Sample Output 3

8

Solution in C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

#include <bits/stdc++.h>

using namespace std;

#define INF 100000000
#define YJ 1145141919
#define INF_INT_MAX 2147483647
#define INF_LL 9223372036854775
#define INF_LL_MAX 9223372036854775807
#define EPS 1e-10
#define MOD 1000000007
#define MOD9 998244353
#define Pi acos(-1)
#define LL long long
#define ULL unsigned long long
#define LD long double

#define int long long

using II = pair<int, int>;

int gcd(int a, int b) { return b != 0 ? gcd(b, a % b) : a; }
int lcm(int a, int b) { return a * b / gcd(a, b); }
int extgcd(int a, int b, int &x, int &y) { int g = a; x = 1; y = 0; if (b != 0) g = extgcd(b, a % b, y, x), y -= (a / b) * x; return g; }

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(a)  begin((a)), end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())

const int MAX_N = 100005;
const int MAX_SQRT = 100;
int N, Q;

struct Edge {
  Edge(int c = -1, int d = -1, int to = -1) : c(c), d(d), to(to) {}
  int c, d, to;
};

struct Node {
  Node() {}
  vector<Edge> nexts;
  Edge preEdge;
  int pre = -1;
  int depth = 0;
  int sqrtPre = -1;
};

Node nodes[MAX_N];
vector<Edge> edges[MAX_N];

void initNodes(int pos, int pre = -1, int d = 0)
{
  nodes[pos].pre = pre;
  nodes[pos].depth = d;
  for(const Edge& edge : edges[pos]) {
    if(edge.to == pre) continue;
    nodes[pos].nexts.push_back(edge.to);
    nodes[edge.to].preEdge = edge;
    nodes[edge.to].preEdge.to = pos;
    initNodes(edge.to, pos, d+1);
  }
}

map<int, int> DIST_COUNT[MAX_N];
map<int, int> DIST_COST[MAX_N];
int DIST_TOTAL[MAX_N];

signed main()
{
  cin >> N >> Q;
  REP(n,N-1) {
    int a, b, c, d; cin >> a >> b >> c >> d; a--; b--; c--;
    edges[a].push_back(Edge(c,d,b));
    edges[b].push_back(Edge(c,d,a));
  }

  initNodes(0);

  REP(n,N) {
    int totalCost = 0;
    bool flag = true;
    int pos = n;
    for(int d = 0; d < MAX_SQRT && flag; d++) {
      if(nodes[pos].pre == -1) {
        flag = false;
        break;
      }
      const Edge& preEdge = nodes[pos].preEdge;
      DIST_COUNT[n][preEdge.c]++;
      DIST_COST[n][preEdge.c] += preEdge.d;
      totalCost += preEdge.d;
      pos = nodes[pos].pre;
    }

    if(flag) {
      DIST_TOTAL[n] = totalCost;
      nodes[n].sqrtPre = pos;
    }
  }

  REP(q,Q) {
    int x, y, u, v; 
    cin >> x >> y >> u >> v;
    x--; u--; v--;
    if(nodes[v].depth < nodes[u].depth) { // vを上にあげる
      swap(u,v);
    }

    int ans = 0;

    // 深さを揃える
    while(abs(nodes[v].depth - nodes[u].depth) > MAX_SQRT) {
      if(DIST_TOTAL[v] > 0) {
        ans += DIST_TOTAL[v] - DIST_COST[v][x] + DIST_COUNT[v][x] * y;
      } else {
        ans += DIST_TOTAL[v];
      }
      v = nodes[v].sqrtPre;
    }

    while(nodes[v].depth != nodes[u].depth) {
      if(nodes[v].preEdge.c == x) {
        ans += y;
      } else {
        ans += nodes[v].preEdge.d;
      }
      v = nodes[v].pre;
    }

    while(nodes[u].sqrtPre != nodes[v].sqrtPre) {
      if(DIST_TOTAL[v] > 0) {
        ans += DIST_TOTAL[v] - DIST_COST[v][x] + DIST_COUNT[v][x] * y;
      } else {
        ans += DIST_TOTAL[v];
      }
      if(DIST_TOTAL[u] > 0) {
        ans += DIST_TOTAL[u] - DIST_COST[u][x] + DIST_COUNT[u][x] * y;
      } else {
        ans += DIST_TOTAL[u];
      }

      v = nodes[v].sqrtPre;
      u = nodes[u].sqrtPre;
    }

    while(u != v) {
      if(nodes[u].preEdge.c == x) {
        ans += y;
      } else {
        ans += nodes[u].preEdge.d;
      }

      if(nodes[v].preEdge.c == x) {
        ans += y;
      } else {
        ans += nodes[v].preEdge.d;
      }

      u = nodes[u].pre;
      v = nodes[v].pre;
    }

    cout << ans << endl;
  }

  return 0;
}