#include<algorithm>
#include<iostream>
#include<string>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
int main(){
  int i,j;
  int a[100][100],b[100],c[100],m,n;
  int mn;
  while(cin>>n>>m&&n+m){
    for(i=0;i<n;i++)
      for(j=0;j<n;j++)
	a[i][j]=200000000;
    for(i=0;i<m;i++){
      int p,q,r;
      cin>>p;
      if(p){
	cin>>p>>q>>r;
	p--;
	q--;
	a[p][q]=a[q][p]=min(a[p][q],r);
      }else{
	cin>>p>>q;
	p--;
	q--;
	memset(b,-1,sizeof(b));
	b[p]=1;
	c[p]=0;
	for(j=0;j<n;j++){
	  if(j!=p)
	    c[j]=c[p]+a[p][j];
	}
	for(;;){
	  mn=q;
	  for(j=0;j<n;j++){
	    if(b[j]==-1&&c[mn]>c[j])
	      mn=j;
	  }
	  if(mn==q)
	    break;
	  b[mn]=1;
	  for(j=0;j<n;j++)
	    c[j]=min(c[j],c[mn]+a[mn][j]);
	}
	if(c[q]==200000000)
	  cout<<-1<<endl;
	else
	  cout<<c[q]<<endl;
      }
    }
  }
  return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int cost[101][101];
int d[101];
bool used[101]={};
int n,k;
#define INF 10000000
int V;
void dijkstra(int s){
	fill(d,d+101,INF);
	fill(used,used+101,false);
	d[s]=0;
	while(1){
		int c=-1;
		for(int u=0;u<V;u++){
			if(!used[u] && (c==-1 || d[u]<d[c])){
				c=u;
			}
		}
		if(c==-1){
			break;
		}
		used[c]=true;
		for(int i=0;i<V;i++){
			d[i]=min(d[i],d[c]+cost[c][i]);
		}
	}
}
int main(){
	while(1){
	scanf("%d %d",&n,&k);
	if(!(n+k)) break;
	for(int i=0;i<101;i++){
		for(int j=0;j<101;j++){
			cost[i][j]=INF;
		}
	}
	V=n;
	for(int i=0;i<k;i++){
		int q;
		scanf("%d",&q);
		if(q){
			int r,o,p;
			scanf("%d %d %d",&r,&o,&p);
			cost[r-1][o-1]=min(p,cost[r-1][o-1]);
			cost[o-1][r-1]=min(p,cost[o-1][r-1]);
		}else{
			int r,p;
			scanf("%d %d",&r,&p);
			dijkstra(r-1);
			if(d[p-1]==INF){
				printf("%d\n",-1);
			}else{
				printf("%d\n",d[p-1]);
			}
		}
	}
	}
	return 0;
}