#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <functional>
#include <vector>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <tuple>
#include <cassert>
#include <exception>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> P;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<string> vs;
typedef vector<P> vp;
#define rep(i,a,n) for(ll i = (a);i < (n);i++)
#define per(i,a,n) for(ll i = (a);i > (n);i--)
#define lep(i,a,n) for(ll i = (a);i <= (n);i++)
#define pel(i,a,n) for(ll i = (a);i >= (n);i--)
#define clr(a,b) memset((a),(b),sizeof(a))
#define pb push_back
#define mp make_pair
#define all(c) (c).begin(),(c).end()
#define sz size()
#define print(X) cout << (X) << endl
#define fprint(NUM,X) cout << fixed << setprecision(NUM) << (X) << endl
#define fprints(NUM,X,Y) cout << fixed << setprecision(NUM) << (X) << " " << (Y) << endl
const ll INF = 1e+9+7;
ll n,m,l;
string s,t;
ll d[200010],dp[550][550];
double w[1000],v[1000];
double box[200010];

#define MAX 10000
struct Edge{int to,cost;};
vector<Edge> G[MAX];
int mincost[MAX];
bool used[MAX];

int prim(){
  int res = 0;
  rep(i,0,n){
    mincost[i] = INF;
    used[i] = false;
  }
  mincost[0] = 0;
  while(1){
    int v = -1;
    rep(i,0,n){
      if(!used[i] && (v == -1 || mincost[i] < mincost[v]))v = i;
    }
    if(v == -1)break;
    used[v] = true;
    res += mincost[v];
    rep(i,0,G[v].sz){
      mincost[G[v][i].to] = min(mincost[G[v][i].to],G[v][i].cost);
    }
  }
  return res;
}

int main(){
  int m;
  int p,q,r;
  cin >> n >> m;
  rep(i,0,m){
    int p,q,r;
    cin >> p >> q >> r;
    G[p].pb(Edge{q,r});
    G[q].pb(Edge{p,r});
  }
  cout << prim() << endl;
  return 0;
}


#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
#include<queue>
#define PAIR pair<long long,int>
using namespace std;

class island{
public:
    vector<PAIR> road;
    void add(int goal,int much){
        road.push_back(PAIR(much,goal));
    }
};
long long func(vector<island>&,int,int);
int main(){
    int n,m;
    while(cin>>n>>m&&n){
        vector<island> map(n+1);
        for(int i=0;i<m;++i){
            int type;
            cin>>type;
            if(type==1) {
                int a,b,much;
                cin>>a>>b>>much;
                map[a].add(b,much);
                map[b].add(a,much);
            }else{
                int s,g;
                cin>>s>>g;
                cout<<func(map,s,g)<<endl;
            }
        }
    }
    return 0;
}

long long func(vector<island>& map,int s,int g){
    vector<long long> much(map.size()+1,-1);
    priority_queue<PAIR,vector<PAIR>,greater<PAIR> > que;
    que.push(PAIR(0,s));
    much[s]=0;
    while(!que.empty()){
        PAIR dpair = que.top();
        que.pop();
        long long time = dpair.first;
        int np = dpair.second;
        if(much[np]!=time){
            continue;
        }
        for(vector<PAIR>::iterator itr = map[np].road.begin();itr!=map[np].road.end();++itr){
            long long ntime = time + itr->first;
            int ng = itr->second;
            if(much[ng]==-1||much[ng]>ntime){
                much[ng]=ntime;
                que.push(PAIR(ntime,ng));
            }
        }
    }
    return much[g];
}
