#include #include //#include #include #include #include #include using namespace std; typedef long long ll; const int maxn = 30010; const int logn = 20; const int INF = 2e9; int up[maxn][logn], n; vector> graph[maxn]; int depth[maxn], parent[maxn]; int dp[logn][maxn]; ll dist[maxn]; int max_edge[logn][maxn], min_edge[logn][maxn]; void dfs(int node, int prev, int level) { depth[node] = level; parent[node] = prev; dp[0][node] = prev; for(int i = 0; i < (int) graph[node].size(); i++) { int neighbour = graph[node][i].first; int weight = graph[node][i].second; if(prev != neighbour) { dist[neighbour] = dist[node] + weight; min_edge[0][neighbour] = weight; max_edge[0][neighbour] = weight; dfs(neighbour, node, level + 1); } } } void preprocess() { memset(up, -1, sizeof up); for(int i = 0; i < n; i++) { up[i][0] = parent[i]; } for(int j = 1; (1 << j) < n; j++) { for(int i = 0; i < n; i++) { if(up[i][j - 1] != -1) { up[i][j] = up[up[i][j - 1]][j - 1]; } } } } int LCA(int a, int b) { if(depth[a] > depth[b]) { swap(a, b); } int diff = depth[b] - depth[a]; while(diff > 0) { int pow = log2(diff); b = up[b][pow]; diff -= (1 << pow); } if(b == a) { return a; } for(int i = logn - 1; i >= 0; i--) { if(up[a][i] != -1 and up[a][i] != up[b][i]) { a = up[a][i]; b = up[b][i]; } } return parent[a]; } void preprocess_max_min() { for(int i = 1; i < logn; i++) { for(int j = 1; j <= n; j++) { dp[i][j] = dp[i - 1][dp[i - 1][j]]; max_edge[i][j] = max(max_edge[i - 1][j], max_edge[i - 1][dp[i - 1][j]]); min_edge[i][j] = min(min_edge[i - 1][j], min_edge[i - 1][dp[i - 1][j]]); } } } pair get_max_min_edge(int a, int b) { if(depth[b] < depth[a]) { swap(a, b); } int res_min = INF, res_max = -INF; int diff = depth[b] - depth[a]; while(diff > 0) { int pow = log2(diff); res_max = max(res_max, max_edge[pow][b]); res_min = min(res_min, min_edge[pow][b]); b = dp[pow][b]; diff -= (1 << pow); } while(a != b) { int i = log2(depth[a]); while(i > 0 and dp[i][a] == dp[i][b]) { i--; } res_max = max(res_max, max_edge[i][a]); res_max = max(res_max, max_edge[i][b]); res_min = min(res_min, min_edge[i][a]); res_min = min(res_min, min_edge[i][b]); a = dp[i][a]; b = dp[i][b]; } return make_pair(res_min, res_max); } int main() { ios_base::sync_with_stdio(false); int q; cin >> n >> q; for(int i = 1; i < n; i++) { int a, b, c; cin >> a >> b >> c; a--; b--; graph[a].push_back(make_pair(b, c)); graph[b].push_back(make_pair(a, c)); } for(int i = 0; i < n; i++) { for(int j = 0; j < logn; j++) { max_edge[j][i] = -INF; min_edge[j][i] = INF; } } dfs(0, -1, 0); preprocess(); preprocess_max_min(); ll ivan = 0, martin = 0; for(int i = 1; i <= q; i++) { int a, b, c; cin >> a >> b >> c; a--; b--; int lca = LCA(a, b); ll d = dist[a] + dist[b] - 2LL * dist[lca]; pair p = get_max_min_edge(a, b); int neg = -1 * p.first * c; int pos = p.second * c; ll d1 = d, d2 = d; d1 -= p.first; d1 += neg; d2 -= p.second; d2 += pos; d = max(d1, d2); if(i % 2 == 1) { ivan += d; } else { martin += d; } } if(ivan == martin) { cout << "=" << endl; } else if(ivan > martin) { cout << "Ivan " << ivan - martin << endl; } else { cout << "Martin " << martin - ivan << endl; } return 0; }