#include "bits/stdc++.h"
#define MOD 1000000007
#define INF 11234567890
#define in std::cin
#define out std::cout
#define rep(i,N) for(int i=0;i<N;++i)
typedef long long int LL;
typedef std::pair<LL, LL> P;
struct edge { LL to, cost; };

LL n, k;
LL d[112];
std::vector<edge>G[112];

void dijkstra(LL s)
{
	std::priority_queue<P, std::vector<P>, std::greater<P>>que;
	std::fill(d, d + n + 1, INF);
	d[s] = 0;
	que.push(P(0, s));
	while (!que.empty())
	{
		P p = que.top(); que.pop();
		LL v = p.second;
		if (d[v] < p.first) { continue; }
		rep(i, G[v].size())
		{
			edge e = G[v][i];
			if (d[e.to] > d[v] + e.cost)
			{
				d[e.to] = d[v] + e.cost;
				que.push(P(d[e.to], e.to));
			}
		}
	}
}

int main()
{
	while (true)
	{
		n = k = 0;
		memset(d, 0, sizeof(d));
		rep(i, 112) { G[i].clear(); }

		in >> n >> k;
		if (n == 0 && k == 0) { break; }
		rep(loop, k)
		{
			LL flag;
			in >> flag;
			if (flag == 0)
			{
				LL a, b;
				in >> a >> b;
				dijkstra(a);
				out << (d[b] == INF ? -1 : d[b]) << std::endl;
			}
			else
			{
				LL c, d, e;
				in >> c >> d >> e;
				G[c].push_back({ d,e });
				G[d].push_back({ c,e });
			}
		}
	}
	return 0;
}
#include <cstdio>
#include <algorithm>
using namespace std;
#define INF (1<<27)
int cost[100][100];
int main() {
	int n,k;
	while(scanf("%d %d",&n,&k),n) {
		fill((int*)cost,(int*)(cost+100),INF);
		for(int i=0;i<k;i++) {
			int a,b,c;
			scanf("%d",&a);
			if(a==0) {
				scanf("%d %d",&a,&b);
				if(cost[a-1][b-1]==INF)
					printf("-1\n");
				else
					printf("%d\n",cost[a-1][b-1]);
			}else {
				scanf("%d %d %d",&a,&b,&c);
				if(cost[a-1][b-1]>c) {
					cost[a-1][b-1]=cost[b-1][a-1]=c;
					for(int k=0;k<n;k++) {
						for(int i=0;i<n;i++) {
							for(int j=0;j<n;j++) {
								cost[i][j]=min(cost[i][j],cost[i][k]+cost[k][j]);
							}
						}
					}
				}
			}
		}
	}
}