#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int MAXN = 100005;
const int LOG = 17; // log2(MAXN) + 1
vector<pair<int, int>> adj[MAXN];
int parent[MAXN][LOG], maxEdge[MAXN][LOG];
int depth[MAXN];
// DFS to initialize parent, maxEdge, and depth arrays
void dfs(int node, int par, int weight) {
parent[node][0] = par;
maxEdge[node][0] = weight;
for (auto &[next, w] : adj[node]) {
if (next != par) {
depth[next] = depth[node] + 1;
dfs(next, node, w);
}
}
}
// Binary Lifting Preprocessing
void preprocess(int n) {
memset(parent, -1, sizeof(parent));
memset(maxEdge, 0, sizeof(maxEdge));
dfs(1, -1, 0); // Assuming node 1 is the root
for (int j = 1; j < LOG; j++) {
for (int i = 1; i <= n; i++) {
if (parent[i][j - 1] != -1) {
parent[i][j] = parent[parent[i][j - 1]][j - 1];
maxEdge[i][j] = max(maxEdge[i][j - 1], maxEdge[parent[i][j - 1]][j - 1]);
}
}
}
}
// Find LCA and maximum edge weight on the path between two nodes
int getMaxEdge(int u, int v) {
if (depth[u] < depth[v]) swap(u, v);
int maxWeight = 0;
// Bring u and v to the same depth
for (int i = LOG - 1; i >= 0; i--) {
if (depth[u] - (1 << i) >= depth[v]) {
maxWeight = max(maxWeight, maxEdge[u][i]);
u = parent[u][i];
}
}
if (u == v) return maxWeight;
// Move both nodes up until they meet at LCA
for (int i = LOG - 1; i >= 0; i--) {
if (parent[u][i] != parent[v][i]) {
maxWeight = max({maxWeight, maxEdge[u][i], maxEdge[v][i]});
u = parent[u][i];
v = parent[v][i];
}
}
// Add the edge connecting to the LCA
return max({maxWeight, maxEdge[u][0], maxEdge[v][0]});
}
int main() {
int n, q;
cin >> n >> q;
for (int i = 0; i < n - 1; i++) {
int u, v, w;
cin >> u >> v >> w;
adj[u].emplace_back(v, w);
adj[v].emplace_back(u, w);
}
preprocess(n);
while (q--) {
int a, b;
cin >> a >> b;
cout << getMaxEdge(a, b) << "\n";
}
return 0;
}