#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <map>
#include <list>
#include <set>
#include <numeric>
#include <queue>
#include <stack>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <climits>
#include <cfloat>
#include <ctime>
#include <complex>
#include <cassert>
#include <iomanip>
#include <tuple>
using namespace std;
typedef long long LL;
typedef pair<int,int> P;

void exec()
{
	int edge[100][100]={0};
	int n,k;
	cin >> n >> k;
	if(n==0&&k==0)exit(0);
	for(int i=0;i<k;i++){
		int a,b,c;
		cin >> a >> b >> c;
		b--;
		c--;
		if(a==0){
			priority_queue<P, vector<P>, greater<P> > q;
			q.push(P(0,b));
			int dist[100];
			fill(dist,dist+n,INT_MAX);
			dist[b]=0;
			while(q.size()){
				int f=q.top().second;
				int d=q.top().first;
				q.pop();
				if(f==c)break;
				if(dist[f]<d)continue;
				for(int j=0;j<n;j++){
					if(edge[f][j]&&d+edge[f][j]<dist[j]){
						dist[j]=d+edge[f][j];
						q.push(P(dist[j],j));
					}
				}
			}
			if(dist[c]!=INT_MAX){
				cout << dist[c] << endl;
			}
			else
			{
				cout << -1 << endl;
			}
		}
		else
		{
			int d;
			cin >> d;
			if(edge[b][c]==0||d<edge[b][c]){
				edge[b][c]=d;
				edge[c][b]=d;
			}
		}
	}
}
int main() {
	while(1)exec();
}
#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<string>

using namespace std;

#define rep(i,n) for(int i=0;i<int(n);i++)
#define reps(i,n) for(int i=1;i<=int(n);i++)
#define sint(i) scanf("%d",&i);
#define sintt(i,j) scanf("%d%d",&i,&j);
#define sinttt(i,j,k) scanf("%d%d%d",&i,&j,&k);
#define sintttt(i,j,k,m) scanf("%d%d%d%d",&i,&j,&k,&m);

#define INF 1010000000
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};

class S{
	public:
	int p,n;
	S(int p,int n):p(p),n(n){}
	
	bool operator<(const S& a)const{
		return n>a.n;
	}
};

////////////djk//////////////////////////////////////////
int main(){
	while(1){
		int n,m;
		sintt(n,m);
		if(n==0)break;
		vector<pair<int,int> > load[101];
		
		rep(o,m){
			int a;
			sint(a);
			if(a==1){
				int b,c,d;
				sinttt(b,c,d);
				load[b].push_back(make_pair(c,d));
				load[c].push_back(make_pair(b,d));
			}else{
				int s,g;
				sintt(s,g);
				
				priority_queue<S> que;
				que.push(S(s,0));
				
				int visit[101];
				rep(i,101)visit[i]=0;
				
				int ans=-1;
			
				while(1){
					if(que.empty()==1){
						break;
					}
					
					S u=que.top();
					que.pop();
					
					if(visit[u.p]==1){
						continue;
					}
					visit[u.p]=1;
					
					if(u.p==g){
						ans=u.n;
						break;
					}
					
					rep(i,load[u.p].size()){
						que.push( S( load[u.p][i].first,  u.n+load[u.p][i].second));
					}
				}
				printf("%d\n",ans);
			}
		}
	}
}