#include<cstdio>
#include<queue>
#include<algorithm>
#define rep(i,b,e) for ( int i = b; i <= e; i++ )
using namespace std;

#define MAX 100
#define INFTY (1<<21)
int n, M[MAX+1][MAX+1];

class State{
    public:
    int p, e;
    State( int p = 0, int e = 0 ): p(p), e(e){}
    bool operator < ( const State &s ) const{
	return e > s.e;
    }
};

int dijkstra( int s, int t ){
    priority_queue<State> PQ;
    bool visited[MAX+1];
    int d[MAX+1];
    rep(i,1,n){
	visited[i] = false;
	d[i] = INFTY;
    }
    PQ.push(State(s, 0));
    d[s] = 0;
    State u;
    while( !PQ.empty() ){
	u = PQ.top(); PQ.pop();
	if ( u.p == t ) return u.e;
	visited[u.p] = true;
	rep(v,1,n){
	    if ( M[u.p][v] == INFTY || visited[v] ) continue;
	    if ( d[v] > d[u.p] + M[u.p][v] ){
		d[v] = d[u.p] + M[u.p][v];
		PQ.push(State(v, d[v]));
	    }
	}
    }
    return -1;
}

int main(){
    int k, m, s, t, e;
    while(1){
	scanf("%d %d", &n, &k);
	if ( n == 0 && k == 0 ) break;
	rep(i,1,n) rep(j,1,n) M[i][j] = INFTY;
	rep(i,1,k){
	    scanf("%d %d %d", &m, &s, &t);
	    if ( m ){
		scanf("%d", &e);
		M[s][t] = min( M[s][t], e );
		M[t][s] = M[s][t];
	    } else printf("%d\n", dijkstra(s, t));
	}
    }
}