# include <iostream>
# include <algorithm>
#include <array>
# include <cassert>
#include <cctype>
#include <climits>
#include <numeric>
# include <vector>
# include <string>
# include <set>
# include <map>
# include <cmath>
# include <iomanip>
# include <functional>
# include <tuple>
# include <utility>
# include <stack>
# include <queue>
# include <list>
# include <bitset>
# include <complex>
# include <chrono>
# include <random>
# include <limits.h>
# include <unordered_map>
# include <unordered_set>
# include <deque>
# include <cstdio>
# include <cstring>
#include <stdio.h>
#include<time.h>
#include <stdlib.h>
#include <cstdint>
#include <cfenv>
#include<fstream>
//#include <bits/stdc++.h>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
long long MOD = 1000000000 + 7;
constexpr long long INF = numeric_limits<LL>::max();
const double PI = acos(-1);
#define fir first
#define sec second
#define thi third
#define debug(x) cerr<<#x<<": "<<x<<'\n'
typedef pair<LL, LL> Pll;
typedef pair<LL, pair<LL, LL>> Ppll;
typedef pair<LL, pair<LL, bitset<100001>>> Pbll;
typedef pair<LL, pair<LL, vector<LL>>> Pvll;
typedef pair<LL, LL> Vec2;
struct Tll { LL first, second, third; };
struct Fll { LL first, second, third, fourth; };
typedef pair<LL, Tll> Ptll;
#define rep(i,rept) for(LL i=0;i<rept;i++)
#define Mfor(i,mf) for(LL i=mf-1;i>=0;i--)
LL h, w, n, m, k, t, s, p, q, last, first, cnt, sum,  dp[200000],a[300000], b[300000];
Tll ans;
string str, ss;
bool f[200];
char c, ch[100][100];
int di[4][2] = { { 0,1 },{ 1,0 },{ 0,-1 },{ -1,0 } };
struct Edge { LL from,to, cost; };
vector<Edge>vec;
vector<LL>v;
map<Pll,LL>ma;
multiset<LL>st;
void YN(bool f) {
	if (f)
		cout << "YES" << endl;
	else
		cout << "NO" << endl;
}
void yn(bool f) {
	if (f)
		cout << "Yes" << endl;
	else
		cout << "No" << endl;
}
struct LowLink {
	int n;
	vector<vector<Pll>> G;
	map<Pll,LL > bridge;
	set<int> articulation;
	vector<int> ord, low;
	vector<bool> vis;
	LowLink() {}
	LowLink(int _n) :n(_n) {
		G.resize(_n);
		ord.resize(_n);
		low.resize(_n);
		vis.resize(_n);
	}
	LowLink(vector<vector<Pll>> &g) {
		G.resize(g.size());
		rep(i, g.size()) {
			rep(j, g[i].size()) {
				G[i].push_back(g[i][j]);
			}
		}
		n = G.size();
		ord.resize(G.size());
		low.resize(G.size());
		vis.resize(G.size());
	}

	void build() {
		int k = 0;
		for (int i = 0; i < n; i++) {
			if (!vis[i]) dfs(i, -1, k);
		}
	}

	void dfs(LL v, LL p, int &k)
	{
		vis[v] = true;

		ord[v] = k++;
		low[v] = ord[v];

		bool isArticulation = false;
		int ct = 0;

		for (int i = 0; i < G[v].size(); i++) {
			if (!vis[G[v][i].fir]) {
				ct++;
				dfs(G[v][i].fir, v, k);
				low[v] = min(low[v], low[G[v][i].fir]);
				if (~p && ord[v] <= low[G[v][i].fir]) isArticulation = true;
				if (ord[v] < low[G[v][i].fir]) bridge[Pll(min(v, G[v][i].fir), max(v, G[v][i].fir))] = G[v][i].sec;
			}
			else if (G[v][i].fir != p) {
				low[v] = min(low[v], ord[G[v][i].fir]);
			}
		}
		if (p == -1 && ct > 1) isArticulation = true;
		if (isArticulation) articulation.insert(v);
	}
};
struct TwoEdgeConnectedComponent {
	int n;
	vector<vector<Pll>> g;
	vector<vector<pair<Pll,Pll>>>tree;//木として見た時の辺が入っている
	vector<int> cmp;//木として見た時の頂点が入っている
	LowLink lnk;
	TwoEdgeConnectedComponent(int _n) {
		n = _n;
		cmp.assign(_n, -1);
		g.resize(_n);
		tree.resize(_n);
	}
	void add_Edge(int x, int y,LL w) {
		g[x].push_back(Pll(y,w));
		g[y].push_back(Pll(x,w));
	}
	void build() {
		lnk = LowLink(g);
		lnk.build();
		int k = 0;
		function<void(LL, LL)> dfs = [&](LL u, LL prev) {
			cmp[u] = k;
			rep(i, g[u].size()) {
				if (cmp[g[u][i].first] == k) {
					a[k] += g[u][i].second;
				}
			}
			for (auto v : g[u]) 
				if (cmp[v.first] == -1 && lnk.bridge.count({ min(u, v.first), max(u, v.first) }) == 0) {
					dfs(v.fir, u);
				}
		};
		for (int i = 0; i < n; i++) if (cmp[i] == -1) {
			dfs(i, -1);
			k++;
		}
		tree.resize(k);
		for (auto e : lnk.bridge) {
			tree[cmp[e.first.first]].push_back(make_pair(Pll(cmp[e.first.second], e.second), e.first));
			tree[cmp[e.first.second]].push_back(make_pair(Pll(cmp[e.first.first], e.second), e.first));
		}
	}
};

TwoEdgeConnectedComponent tec(200010);

LL dfs(int cur,int par) {
	LL ret = a[cur];
	rep(i, tec.tree[cur].size()) {
		if (tec.tree[cur][i].first.first != par) {
			LL num = dfs(tec.tree[cur][i].first.first, cur),dif=tec.tree[cur][i].first.second;
			if (ans.first > abs((sum - num - dif) - num)) {
				ans = Tll{ abs((sum - num - dif) - num), tec.tree[cur][i].second.first,tec.tree[cur][i].second.second };
			}
			ret += num + dif;
		}
	}
	return dp[cur] = ret;
}

int main() {
	cin >> n >> m;
	
	rep(i, m) {
		LL x, y, z;
		cin >> x >> y >> z;
		x--, y--;
		sum += z;
		tec.add_Edge(x, y, z);
	}
	tec.build();
	
	ans.first = INF;
	rep(i,n) {
		rep(j, tec.g[i].size()) {
			if(ans.first>(sum - tec.g[i][j].second))
			ans = Tll{ sum - tec.g[i][j].second, min(tec.g[i][j].first, i), max(tec.g[i][j].first, i) };
		}
	}
	dfs(0,-1);
	
	cout << ans.second+1 << " " << ans.third+1 << endl;
	return 0;
}



Measured memory_bytes: 48560