#include <iostream>
#include <vector>
#include <utility>
#include <queue>
#include <map>
#include <cmath>
using namespace std;

#define rep(i,n) for(int i=0;i<n;i++)
using P = pair<int,int>;
vector<vector<int> > tree;
vector<long long> w;
class biconnected{
public:
    
    int V,kind;
    vector<vector<int> > G;
    vector<vector<P> >check;
    vector<int> ord,low,cmp;
    
    vector<P> bridge;
    vector<bool> visit;
    biconnected(int node_size) : V(node_size),kind(0),G(V),check(V),ord(V),low(V),cmp(V),visit(V,false){}
    void build(){
        int id = 0;
        rep(i,V){
            if(!visit[i]){
                dfs(i,-1,id);
            }
        }
    }
    void dfs(int v,int p,int &k){
        visit[v] = true;
        ord[v] = k++;
        low[v] = ord[v];
        rep(i,(int)G[v].size()){
            int w = G[v][i];
            if(!visit[w]){
                dfs(w,v,k);
                low[v] = min(low[v],low[w]);
               
                    if(ord[v] < low[w]){
                        bridge.push_back(P(v,w));
                        check[v][i].second = 1;
                        check[w][check[v][i].first].second = 1;
                    }
                
            }else if(w!=p){
                low[v] = min(low[v],ord[w]);
            }
        }
    }
    void add_edge(int u,int v){
        G[u].push_back(v),G[v].push_back(u);
        check[u].push_back(P((int)check[v].size(),0));
        check[v].push_back(P((int)check[u].size()-1,0));
        
    }
    void restrict_dfs(int u,int p,int kind,queue<int> &que){
        visit[u] = true;
        cmp[u] = kind;
        rep(i,(int)G[u].size()){
            int w = G[u][i];
            if(check[u][i].second){
                if(!visit[w]){
                    que.push(w);
                }
            }else if(!visit[w]){
                restrict_dfs(w,u,kind,que);
            }
        }
    }
    void rebuild(){
        fill(visit.begin(),visit.end(),false);
        rep(i,V){
            if(!visit[i]){
                queue<int> que;
                que.push(i);
                while(!que.empty()){
                    int p = que.front();
                    que.pop();
                    restrict_dfs(p,-1,kind,que);
                    kind++;
                }
            }
        }
    }
     void make_bctree(){
            w.resize(V);
            tree.resize(V);
            rebuild();
            rep(i,(int)bridge.size()){
                int a = cmp[bridge[i].first];
                int b = cmp[bridge[i].second];
                tree[a].push_back(b),tree[b].push_back(a);
            }
        }
};

map<pair<int,int>,long long >mp2;
void bfs(int i,int pre){
    for(auto x:tree[i]){
        if(x!=pre){
            bfs(x,i);
            int a = min(x,i);
            int b = max(x,i);
            w[i] += w[x] + mp2[P(a,b)];
        }
    }
    return;
}


int main(){
    int n,m;
    cin >> n >> m;
    biconnected bc(n);
    map<pair<int,int>,long long> mp;
    P mi = P(200000,200000);
    P mim  = P(200000,200000);
    long long sm = 0;
    long long maxw = 0;
    for(int i=0;i<m;i++){
        int u,v;
        long long w;
        cin >> u >> v >> w;
        u--;v--;
        bc.add_edge(u,v);
        sm += w;
        mp[P(u,v)] = w;
        if(maxw <w){
            maxw = w;
            mim =P(u,v);
        }else if(maxw == w){
            mim = min(mim,P(u,v));
        }
    }
    bc.build();
    bc.make_bctree();
    if(bc.bridge.size()==0){
        cout << mim.first+1 << " " << mim.second+1 << endl;
        return 0;
    }
    map<pair<int,int>,pair<int,int> > mp3;
    for(auto x:mp){
        auto y = x.first;
        auto we = x.second;
        if(bc.cmp[y.first]==bc.cmp[y.second]){
            w[bc.cmp[y.first]] += x.second;
        }else{
            int a = bc.cmp[y.first];
            int b = bc.cmp[y.second];
            int c = y.first;
            int d = y.second;
            if(a>b){
                swap(a,b);
            }
            mp2[P(a,b)] = we;
            
            mp3[P(a,b)] = P(c,d);
        }
    }
    // for(auto x:bc.bridge){
    //     cout << x.first << " " << x.second << endl;
    // }
    // for(int i=0;i<bc.w.size();i++){
    //     cout << i << " " << bc.w[i] << endl;
    // }
    long long mimi = 1LL << 60;
    bfs(0,-1);
    // for(int i=0;i<5;i++){
    //     cout << w[i] << endl;
    // }
    for(auto x:bc.bridge){
        int a = bc.cmp[x.first];
        int b = bc.cmp[x.second];
        int c = x.first;
        int d = x.second;
        if(a>b)swap(a,b);
        if(c>d)swap(c,d);
        //cerr << c << " " << d << endl;
        long long sm2 = sm-mp[P(c,d)];
        //cout << a << " " << b << " " << w[a] << " " << w[b] << " " << sm << " " << sm2 << endl;
        if(w[a]>w[b]){
            long long tmp = sm2 -w[b];
            //cout << tmp << " " << w[b] << endl;
            if(mimi == abs(tmp-w[b])){
                mimi = abs(tmp-w[b]);
                mi = min(mi,P(c,d));
            }else if(mimi >abs(tmp-w[b])){
                mimi = abs(tmp-w[b]);
                mi = P(c,d);
            }
        }else{
            long long tmp = sm2 -w[a];
            if(mimi == abs(tmp-w[a])){
                mimi = abs(tmp-w[a]);
                mi = min(mi,P(c,d));
            }else if(mimi >abs(tmp-w[a])){
                mimi = abs(tmp-w[a]);
                mi = P(c,d);
            }
        }
        //cout << mi.first<< " " << mi.second << endl;
    }
    if(mimi>sm-maxw){
        mi = mim;
    }
    if(mimi==sm-maxw){
        mi = min(mim,mi);
    }
    cout << mi.first+1 << " " << mi.second+1 << endl;
    return 0;
}


Measured memory_bytes: 41432