#include <iostream>

#define MX 1000000000

using namespace std;
int M[100][100],N; //M[i][j]:i©çjÜÅÌRXg

int dijkstra(int s , int g){
  bool visited[100];
  int d[100];
  for(int i=0;i < N;i++) d[i] = MX , visited[i] = false;
  d[s] = 0;
  while(1){
    int u;
    int mincost = MX;
    for(int i=0;i<N;i++)if(!visited[i] && d[i] < mincost) mincost = d[i] , u = i;
    if(mincost == MX) break;
    visited[u] = true;
    for(int v=0;v<N;v++){
      if(visited[v] || M[u][v] == MX) continue;
      if(d[v] > d[u] + M[u][v]) d[v] = d[u] + M[u][v];
    }
  }
  return d[g];
}
    
int main(){
  int k;
  while(cin >> N >> k){
    for(int i=0;i<N;i++)for(int j=0;j<N;j++) M[i][j] = MX;
    while(k--){
      int x,a,b,c;
      cin >> x;
      if(!(x)){
        int cost;
        cin >> a >> b;
        cost = dijkstra(a-1,b-1);
        if(cost == MX) cout << "-1" << endl;
        else cout << cost << endl;
      }
      else {
        cin >> a >> b >> c;        
        if(M[a-1][b-1] > c && M[b-1][a-1] > c) M[a-1][b-1] = M[b-1][a-1] = c;
      }
    }
  }
  return 0;
}
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>

#define INF (1e+9)
#define LLINF (1e+18)
#define LL long long

#define MAX_V 100

using namespace std;

typedef struct edge{
	int to;
	int cost;
	edge(){

	}
	edge(int _to,int _cost){
		to = _to;
		cost = _cost;
	}
	bool operator<(const edge &a)const{
		if(cost == a.cost) return to > a.to;
		return cost > a.cost;	//for asc
	}
}edge;


int cost[MAX_V + 1];
vector<edge> G[MAX_V + 1];
priority_queue<edge> pque;


int V;
int K;


void solve(int s){
	for(int i = 1;i <= V;i++){
		cost[i] = INF;
	}

	pque.push(edge(s,0));

	while(!pque.empty()){
		edge e = pque.top();pque.pop();
		if(cost[e.to] != INF) continue;
		cost[e.to] = e.cost;
		for(int i = 0;i < G[e.to].size();i++){
			int _to = G[e.to][i].to;
			int _cost = e.cost + G[e.to][i].cost;
			pque.push(edge(_to,_cost));
		}
	}

	return ;
}

int main (void){

	while(true){
		scanf("%d%d",&V,&K);
		if(V == 0 && K == 0) break;
		int query;
		int _u,_v,_cost;
		for(int i = 0;i < K;i++){
			scanf("%d",&query);
			if(query){
				scanf("%d%d%d",&_u,&_v,&_cost);
				G[_u].push_back(edge(_v,_cost));
				G[_v].push_back(edge(_u,_cost));
			}
			else {
				scanf("%d%d",&_u,&_v);
				solve(_u);
				if(cost[_v] == INF)puts("-1");
				else printf("%d\n",cost[_v]);
			}
		}
		for(int i = 1;i <= V;i++) G[i].clear();
	}

	return 0;
}