#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=101,M=5005;
int f[N][N];
int n,m,head[N],id;
struct data{
int u,v,value,next;
};
data edge[M];
void add(int u,int v,int value){
++id;
edge[id].u=u;
edge[id].v=v;
edge[id].value=value;
edge[id].next=head[u];
head[u]=id;
}
int dis[N];
bool vis[N];
struct node{
int point,value;
bool operator <(const node &x)const{
return value>x.value;
}
};
void dijkstra(int start){
memset(dis,0x3f,sizeof dis);
memset(vis,0,sizeof vis);
priority_queue<node>q;
dis[start]=0;
node temp;
temp.point=start;
temp.value=0;
q.push(temp);
while(!q.empty()){
temp=q.top();
q.pop();
int u=temp.point;
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].v;
if(!vis[v]&&dis[v]>dis[u]+edge[id].value){
dis[v]=dis[u]+edge[id].value;
q.push({v,dis[v]});
}
}
}
}
int main(){
memset(f,0x3f,sizeof f);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
bool flag;
scanf("%d",&flag);
if(!flag){
int u,v;
scanf("%d%d",&u,&v);
dijkstra(u);
if(dis[v]==INF) puts("-1");
else printf("%d\n",dis[v]);
}else{
int u,v,value;
scanf("%d%d%d",&u,&v,&value);
if(f[u][v]>value){
f[u][v]=f[v][u]=value;
add(u,v,value);
add(v,u,value);
}
}
}
return 0;
}