Problem:
船旅
問題
JOI国には，n 島の島があり，各島には 1 から n までの番号が付けられている．現在，JOI国では各島の間を結ぶ航路網の整備が進んでいる．
あなたは，船舶の切符を扱っているチケットセンターに勤務している．JOI国には船舶を使って，できる限り安価に，島と島の間を旅行したいと考えている人が沢山おり，彼らは，出発地と目的地を注文票に記入して，あなたのところに送ってくる．
あなたの仕事は，客から注文票を受け取ったらすぐに，いくつかの船舶を乗り継いで，出発地と目的地を結ぶ航路の中で，もっとも安価な運賃を計算し，客に伝えることである．
ただし，旅程によっては，船舶を使って旅行することが出来ない場合もある．そのときは『船舶を使って旅行することが出来ない』と客に伝える必要がある．また，JOI国では，島と島の間を結ぶ新しい船舶が，次々と運航を開始しており，あなたには，その情報が随時伝えられる．客に返事をする際には，最新の情報に留意しなければならない．
入力として，客の注文票や新たに運航を開始した船舶の運航情報が与えられたときに，客への返事を求めるプログラムを作成せよ．
なお，入力例１と出力例１に対する実行状況を，図１として図示している．
入力
入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．
入力の 1 行目には2つの整数 n, k (1 ≤ n ≤ 100, 1 ≤ k ≤ 5000) が書かれている．これは，島の数が n 島で，入力が k + 1 行からなることを表す．
i + 1 行目 (1 ≤ i ≤ k) には， 3 個または 4 個の整数が空白を区切りとして書かれている．
最初の数字が 0 のとき，この行は客の注文票を表す．
この行には3個の整数 0, a, b (1 ≤ a ≤ n, 1 ≤ b ≤ n, a ≠ b) が空白を区切りとして書かれている．
      これは，客が，島 a を出発地とし島 b を目的地とするような注文票を送ってきたことを表す．
最初の数字が 1 のとき，この行は新たに運航を開始した船舶の運航情報を表す．
この行には 4 個の整数 1, c, d, e (1 ≤ c ≤ n, 1 ≤ d ≤ n, c ≠ d, 1 ≤ e ≤ 1000000) が書かれている．
これは島 c と島 d を往復する船舶が新たに運航を開始し，この船舶の島 c から島 d への運賃と，島 d から島 c への運賃が，共に e であることを表す．
この行以降の注文票に対しては，この船舶も考慮して返事をしなければならない．
最初の段階では，船舶は一隻も運航していないものとする．入力のうち，船舶の運航情報を表す行は 1000 行以下である．また，島と島の間に，複数の船舶が運航することがあることに注意せよ．
n, k がともに 0 のとき入力の終了を示す. データセットの数は 5 を超えない．
出力
データセットごとに以下の形式で出力する．
入力のうち，注文票を表す行の数を m とおく．
各データセットの出力は m 行からなり， i 行目(1 ≤ i ≤ m)には， i 番目の注文票に対する返事を表す整数を書く．
すなわち， i 番目の注文票の出発地と目的地の間を，いくつかの船舶を乗り継いで旅行することが可能ならば，その運賃の合計の最小値を書く．旅行することが不可能ならば，-1 を出力する．
入出力例
入力例
3 8
1 3 1 10
0 2 3
1 2 3 20
1 1 2 5
0 3 2
1 1 3 7
1 2 1 9
0 2 3
5 16
1 1 2 343750
1 1 3 3343
1 1 4 347392
1 1 5 5497
1 2 3 123394
1 2 4 545492
1 2 5 458
1 3 4 343983
1 3 5 843468
1 4 5 15934
0 2 1
0 4 1
0 3 2
0 4 2
0 4 3
0 5 3
0 0
出力例
-1
15
12
5955
21431
9298
16392
24774
8840
上記問題文と自動審判に使われるデータは、
情報オリンピック日本委員会
が作成し公開している問題文と採点用テストデータです。

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

constexpr int INF = 1e9;

int main() {
    int n, k;
    while(cin >> n >> k, n) {
        vector<vector<int>> d(n, vector<int>(n, INF));
        for(int i=0; i<n; ++i) {
            d[i][i] = 0;
        }
        for(int i=0; i<k; ++i) {
            int a;
            cin >> a;
            if(a == 0) {
                int b, c;
                cin >> b >> c;
                b--; c--;
                cout << (d[b][c] == INF ? -1 : d[b][c]) << endl;
            } else {
                int b, c, e;
                cin >> b >> c >> e;
                b--; c--;
                if(d[b][c] <= e) {
                    continue;
                }
                for(int j=0; j<n; ++j) {
                    for(int l=0; l<n; ++l) {
                        d[j][l] = min(d[j][l], min(d[j][b] + d[c][l], d[j][c] + d[b][l]) + e);
                    }
                }
            }
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3416
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)

vector<long long> dijkstra(int v,int r,const vector<vector<pair<int,int>>>& graph){
    const long long INF=LLONG_MAX;
    vector<long long> dist(v,INF);
    dist[r]=0;

    priority_queue<pair<long long,int>,vector<pair<long long,int>>,greater<>> pq;
    pq.push({0,r});

    while(!pq.empty()){
        auto [current_dist,u]=pq.top();
        pq.pop();
        if(current_dist>dist[u]) continue;
        
        for(auto& [to,weight]:graph[u]){
            long long new_dist=current_dist+weight;
            if(new_dist<dist[to]){
                dist[to]=new_dist;
                pq.push({new_dist,to});
            }
        }
    }
    return dist;
}
//計算量はO((V+E)logV)

int main(){
    while(1){
        int n,k;
        cin >> n >> k;
        if(n==0 && k==0) break;

        vector<vector<pair<int,int>>> graph(n);
        rep(i,k){
            int check;
            cin >> check;
            if(check==0){
                int a,b;
                cin >> a >> b;
                a--;b--;
                vector<long long> dist=dijkstra(n,a,graph);
                if(dist[b]==LLONG_MAX){
                    cout << -1 << endl;
                }
                else{
                    cout << dist[b] << endl;
                }
            }
            else{
                int c,d,e;
                cin >> c >> d >> e;
                c--;d--;
                graph[c].push_back({d,e});
                graph[d].push_back({c,e});
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3392
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <limits>


using namespace std;
typedef long long int ll;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;

const ll INF = numeric_limits<ll>::max();

void get_fare(ll n, vvll& fares) {
  ll a, b;
  cin >> a >> b;

  vll total_fare(n+1, INF);
  queue<ll> bfs_queue;
  bfs_queue.push(a);
  total_fare[a] = 0;
  while(!bfs_queue.empty()) {
    ll current = bfs_queue.front(); bfs_queue.pop();
    for (ll i = 1; i <= n; i++) {
      ll adj_fare = fares[current][i];
      if (adj_fare == INF) continue;
      if (total_fare[i] > adj_fare + total_fare[current]) {
        total_fare[i] = adj_fare + total_fare[current];
        //cout << i << ": " << total_fare[i] << " => " << adj_fare + total_fare[current] << endl;
        bfs_queue.push(i);
      }
    }
  }

  if (total_fare[b] == INF) {
    cout << -1 << endl;
  }
  else {
    cout << total_fare[b] << endl;
  }
}

void set_fare(vvll& fares) {
  ll c, d, e;
  cin >> c >> d >> e;
  if (fares[c][d] > e) {
    fares[c][d] = e;
    fares[d][c] = e;
  }
}

void solve(ll n, ll k) {
  vll temp(n+1, INF);
  vvll fares(n+1, temp);

  for (ll i = 0; i < k; i++) {
    ll c;
    cin >> c;
    if (c == 0) {
      get_fare(n, fares);
    }
    else {
      set_fare(fares);
    }
  }
}

int main() {
  ll n, k;
  for (;;) {
    cin >> n >> k;
    if (n == 0 && k == 0) {
      break;
    }

    solve(n, k);
  }
}
accuracy: 1
time_ms: 490
memory_kb: 3148
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<n;++i)
#define ALL(a)  (a).begin(),(a).end()
const int inf = INT_MAX;
using ll = long long;
const ll INF = 1e18;
using P = pair<ll,int>;
struct Edge{
    int to;
    ll cost;
    Edge(int to,ll cost):to(to),cost(cost){}
};
using kEdge = pair<int,pair<int,int>>;
using Graph = vector<vector<int>>;
using WeightedGraph = vector<vector<Edge>>;


struct UnionFind{
   vector<int> par,rank,siz;
   UnionFind(int n) : par(n,-1),rank(n,0),siz(n,1){ }

   int root(int x){
       if(par[x]==-1)return x;
       else return par[x]=root(par[x]);
   }

   bool issame(int x,int y){
       return root(x)==root(y);
   }

   bool unite(int x,int y){
       int rx=root(x),ry=root(y);
       if(rx==ry)return false;
       if(rank[rx]<rank[ry])swap(rx,ry);
       par[ry]=rx;
       if(rank[rx]==rank[ry])rank[rx]++;
       siz[rx]+=siz[ry];
       return true;
   }

   int size(int x){
       return siz[root(x)];
   }
};

class SegmentTree{
   public:
   vector<int>dat;
   int siz=1;

   void init(int N){
       siz=1;
       while(siz<N)siz*=2;
       dat=vector<int>(2*siz,0);
   }

   void update(int pos,int x){
       pos=pos+siz-1;
       dat[pos]=x;
       while(pos>=2){
           pos/=2;
           dat[pos]=max(dat[pos*2],dat[pos*2+1]);
       }
   }

   int query(int l,int r,int a,int b,int u){
       if(r<=a || b<=l)return -100000000;
       if(l<=a && b<=r)return dat[u];
       int m=(a+b)/2;
       int AnsL=query(l,r,a,m,u*2);
       int AnsR=query(l,r,m,b,u*2+1);
       return max(AnsL,AnsR);
   }
};

template<typename T> bool chmin(T& a, T b){if(a > b){a = b; return true;} return false;}
template<typename T> bool chmax(T& a, T b){if(a < b){a = b; return true;} return false;}

vector<int>dxs={1,0,-1,0};
vector<int>dys={0,1,0,-1};

//fixed << setprecision(10)
//A[i].erase(unique(ALL(A[i])),A[i].end());

int main(){

    int n,k;
    while(cin >> n && cin >> k){
        WeightedGraph g(n);
        rep(i,k){
            int q;
            cin >> q;
            if(q==0){
                int a,b;
                cin >> a >> b;
                a--,b--;

                vector<ll>dist(n,INF);
                priority_queue<P,vector<P>,greater<P>> que;
                dist[a]=0;
                que.emplace(0,a);

                while(!que.empty()){
                    ll d=que.top().first;
                    int v=que.top().second;
                    que.pop();
                    if(d>dist[v])continue;
                    for(auto vs:g[v]){
                        ll nd=d+vs.cost;
                        int to=vs.to;
                        if(chmin(dist[to],nd))que.emplace(nd,to);
                    }
                }

                if(dist[b]==INF)cout << -1 << endl;
                else cout << dist[b] << endl;
            }else{
                int c,d,e;
                cin >> c >> d >> e;
                c--,d--;
                g[c].push_back(Edge(d,e));
                g[d].push_back(Edge(c,e));
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3200
final_rank: 8

code_snippet: #include <bits/stdc++.h>

using namespace std;
#define endl "\n"
typedef long long ll;
#define int long long
const int INF = 1LL << 55;
void solved() {
  int n, q;

  while (cin >> n >> q) {
    if (n == 0 && q == 0) break;
    vector g(n, vector(n, INF));

    auto dij = [&](int s) -> vector<int> {
      vector<int> dp(n, INF);
      vector<bool> seen(n, false);
      dp[s] = 0;
      for (int i = 0; i < n; i++) {
        int md = INF;
        int mv = -1;
        for (int v = 0; v < n; v++) {
          if (seen[v]) continue;
          if (dp[v] < md) {
            md = dp[v];
            mv = v;
          }
        }
        if (mv == -1) break;
        seen[mv] = true;
        for (int v = 0; v < n; v++) {
          dp[v] = min(dp[v], dp[mv] + g[mv][v]);
        }
      }
      return dp;
    };
    for (int i = 0; i < q; i++) {
      int k, a, b, w = 0;
      cin >> k >> a >> b;
      --a, --b;
      if (k == 1) {
        cin >> w;
        g[a][b] = min(g[a][b], w);
        g[b][a] = min(g[b][a], w);
      } else {
        const auto &dp = dij(a);

        cout << (dp[b] < INF ? dp[b] : -1) << endl;
      }
    }
  }
}
signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  /*int t = 1;
  cin >> t;
  while (t--)*/
  solved();

  return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 3404
final_rank: 13

code_snippet: #line 1 "/opt/library/template.hpp"
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using i64 = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;
using u128 = unsigned __int128;
using f128 = __float128;

template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'000'001'000;
template <>
constexpr ll infty<ll> = ll(infty<int>) * infty<int> * 2;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * infty<ll>;
template <>
constexpr double infty<double> = infty<ll>;
template <>
constexpr long double infty<long double> = infty<ll>;
#define inf infty<ll>

using pi = pair<ll, ll>;
using vi = vector<ll>;
using vvi = vector<vector<ll>>;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

#define rep1(a) for (ll _ = 0; _ < (ll)(a); ++_)
#define rep2(i, a) for (ll i = 0; i < (ll)(a); ++i)
#define rep3(i, a, b) for (ll i = a; i < (ll)(b); ++i)
#define rep4(i, a, b, c) for (ll i = a; i < (ll)(b); i += (c))
#define rrep1(a) for (ll i = (a)-1; i >= (ll)(0); --i)
#define rrep2(i, a) for (ll i = (a)-1; i >= (ll)(0); --i)
#define rrep3(i, a, b) for (ll i = (b)-1; i >= (ll)(a); --i)
#define rrep4(i, a, b, c) for (ll i = (b)-1; i >= (ll)(a); i -= (c))
#define overload4(a, b, c, d, e, ...) e
#define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__)
#define rrep(...) overload4(__VA_ARGS__, rrep4, rrep3, rrep2, rrep1)(__VA_ARGS__)

#define all(x) (x).begin(),(x).end()
#define len(x) (ll)(x.size())
#define elif else if
#define bit(x, i) (((x)>>(i))&1)

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll
#define abs llabs

#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) \
  sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()

ll popcnt(ll x) { return __builtin_popcountll(x); }
ll popcnt(u64 x) { return __builtin_popcountll(x); }
ll popcnt_mod_2(ll x) { return __builtin_parityll(x); }
ll popcnt_mod_2(u64 x) { return __builtin_parityll(x); }
ll topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
ll topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
ll lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
ll lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T>
T floor(T a, T b) {
  return a / b - (a % b && (a ^ b) < 0);
}
template <typename T>
T ceil(T x, T y) {
  return floor(x + y - 1, y);
}
template <typename T>
T bmod(T x, T y) {
  return x - y * floor(x, y);
}
template <typename T>
pair<T, T> divmod(T x, T y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

template<typename T> T SUM(const vector<T> &A) {
  T s = 0; for (auto &&a: A) s += a;
  return s;
}

template <typename T>
T POP(queue<T> &que) {
  T a = que.front();
  que.pop();
  return a;
}
template <typename T>
T POP(deque<T> &que) {
  T a = que.front();
  que.pop_front();
  return a;
}
template <typename T>
T POP(pq<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(pqg<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(vc<T> &que) {
  T a = que.back();
  que.pop_back();
  return a;
}

template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
  if (check_ok) assert(check(ok));
  while (abs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    (check(x) ? ok : ng) = x;
  }
  return ok;
}
template <typename F>
f128 binary_search_real(F check, f128 ok, f128 ng, ll iter = 100) {
  rep(iter) {
    f128 x = (ok + ng) / 2;
    (check(x) ? ok : ng) = x;
  }
  return (ok + ng) / 2;
}

// ? は -1
vc<int> s_to_vi(const string &S, char first_char) {
  vc<int> A(S.size());
  rep(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); }
  return A;
}

template <typename T, typename U>
vc<T> cumsum(vc<U> &A, ll off = 1) {
  ll N = A.size();
  vc<T> B(N + 1);
  rep(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

// stable sort
template <typename T>
vi argsort(const vector<T> &A) {
  vi ids(len(A));
  iota(all(ids), 0);
  sort(all(ids),
       [&](ll i, ll j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vi &I) {
  vc<T> B(len(I));
  rep(i, len(I)) B[i] = A[I[i]];
  return B;
}

template<typename T> inline bool chmax(T &a, T b) {return ((a<b)?(a=b,true):(false));}
template<typename T> inline bool chmin(T &a, T b) {return ((a>b)?(a=b,true):(false));}

inline void wt(const char c) { cout << c; }
inline void wt(const string s) { cout << s; }
inline void wt(const char *s) { cout << s; }

template <typename T>
void wt_integer(T x) {
  if (x < 0) { cout << (i64)(x); }
  else { cout << (u64)(x); }
}
template <typename T>
void wt_real(T x) {
  cout << fixed << setprecision(15) << (long double)(x);
}

inline void wt(int x) { wt_integer(x); }
inline void wt(ll x) { wt_integer(x); }
inline void wt(i128 x) { wt_integer(x); }
inline void wt(u32 x) { wt_integer(x); }
inline void wt(u64 x) { wt_integer(x); }
inline void wt(u128 x) { wt_integer(x); }
inline void wt(double x) { wt_real(x); }
inline void wt(long double x) { wt_real(x); }
inline void wt(f128 x) { wt_real(x); }

template <class T, class U>
void wt(const pair<T, U> val) {
  wt(val.first); wt(' '); wt(val.second);
}
template <size_t N = 0, typename T>
void wt_tuple(const T t) {
  if constexpr (N < std::tuple_size<T>::value) {
    if constexpr (N > 0) { wt(' '); }
    const auto x = std::get<N>(t);
    wt(x);
    wt_tuple<N + 1>(t);
  }
}
template <class... T>
void wt(tuple<T...> tpl) {
  wt_tuple(tpl);
}
template <class T, size_t S>
void wt(const array<T, S> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}
template <class T>
void wt(const vector<T> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}

void print() { wt('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  wt(head);
  if (sizeof...(Tail)) wt(' ');
  print(forward<Tail>(tail)...);
}

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
void onez(bool t = 1) { print(t ? 1 : 0); }
#define endl '\n'
#define dump(x) {cerr << #x " = " << x << '\n';}
#line 2 "/opt/library/graph/base.hpp"

template <typename T>
struct Edge {
  ll frm, to;
  T cost;
  ll id;
};

template <typename T = ll, bool directed = false>
struct Graph {
  static constexpr bool is_directed = directed;
  ll N, M;
  using cost_type = T;
  using edge_type = Edge<T>;
  vector<edge_type> edges;
  vi indptr;
  vc<edge_type> csr_edges;
  vc<ll> vc_deg, vc_indeg, vc_outdeg;
  bool prepared;

  class OutgoingEdges {
  public:
    OutgoingEdges(const Graph* G, ll l, ll r) : G(G), l(l), r(r) {}

    const edge_type* begin() const {
      if (l == r) { return 0; }
      return &G->csr_edges[l];
    }

    const edge_type* end() const {
      if (l == r) { return 0; }
      return &G->csr_edges[r];
    }

  private:
    const Graph* G;
    ll l, r;
  };

  bool is_prepared() { return prepared; }

  Graph() : N(0), M(0), prepared(0) {}
  Graph(ll N) : N(N), M(0), prepared(0) {}

  void build(ll n) {
    N = n, M = 0;
    prepared = 0;
    edges.clear();
    indptr.clear();
    csr_edges.clear();
    vc_deg.clear();
    vc_indeg.clear();
    vc_outdeg.clear();
  }

  void add(ll frm, ll to, T cost = 1, ll i = -1) {
    assert(!prepared);
    assert(0 <= frm && 0 <= to && to < N);
    if (i == -1) i = M;
    auto e = edge_type({frm, to, cost, i});
    edges.eb(e);
    ++M;
  }

#ifdef FASTIO
  // wt, off
  void read_tree(bool wt = false, ll off = 1) { read_graph(N - 1, wt, off); }

  void read_graph(ll M, bool wt = false, ll off = 1) {
    for (ll m = 0; m < M; ++m) {
      LL(a, b);
      a -= off, b -= off;
      if (!wt) {
        add(a, b);
      } else {
        T c;
        read(c);
        add(a, b, c);
      }
    }
    build();
  }
#endif

  void build() {
    assert(!prepared);
    prepared = true;
    indptr.assign(N + 1, 0);
    for (auto&& e: edges) {
      indptr[e.frm + 1]++;
      if (!directed) indptr[e.to + 1]++;
    }
    for (ll v = 0; v < N; ++v) { indptr[v + 1] += indptr[v]; }
    auto counter = indptr;
    csr_edges.resize(indptr.back() + 1);
    for (auto&& e: edges) {
      csr_edges[counter[e.frm]++] = e;
      if (!directed)
        csr_edges[counter[e.to]++] = edge_type({e.to, e.frm, e.cost, e.id});
    }
  }

  OutgoingEdges operator[](ll v) const {
    assert(prepared);
    return {this, indptr[v], indptr[v + 1]};
  }

  vi deg_array() {
    if (vc_deg.empty()) calc_deg();
    return vc_deg;
  }

  pair<vi, vi> deg_array_inout() {
    if (vc_indeg.empty()) calc_deg_inout();
    return {vc_indeg, vc_outdeg};
  }

  ll deg(ll v) {
    if (vc_deg.empty()) calc_deg();
    return vc_deg[v];
  }

  ll in_deg(ll v) {
    if (vc_indeg.empty()) calc_deg_inout();
    return vc_indeg[v];
  }

  ll out_deg(ll v) {
    if (vc_outdeg.empty()) calc_deg_inout();
    return vc_outdeg[v];
  }

#ifdef FASTIO
  void debug() {
    print("Graph");
    if (!prepared) {
      print("frm to cost id");
      for (auto&& e: edges) print(e.frm, e.to, e.cost, e.id);
    } else {
      print("indptr", indptr);
      print("frm to cost id");
      rep(v, N) for (auto&& e: (*this)[v]) print(e.frm, e.to, e.cost, e.id);
    }
  }
#endif

  vi new_idx;
  vc<bool> used_e;

  // G における頂点 V[i] が、新しいグラフで i になるようにする
  // {G, es}
  Graph<T, directed> rearrange(vi V, bool keep_eid = 0) {
    if (len(new_idx) != N) new_idx.assign(N, -1);
    if (len(used_e) != M) used_e.assign(M, 0);
    ll n = len(V);
    rep(i, n) new_idx[V[i]] = i;
    Graph<T, directed> G(n);
    vi history;
    rep(i, n) {
      for (auto&& e: (*this)[V[i]]) {
        if (used_e[e.id]) continue;
        ll a = e.frm, b = e.to;
        if (new_idx[a] != -1 && new_idx[b] != -1) {
          history.eb(e.id);
          used_e[e.id] = 1;
          ll eid = (keep_eid ? e.id : -1);
          G.add(new_idx[a], new_idx[b], e.cost, eid);
        }
      }
    }
    rep(i, n) new_idx[V[i]] = -1;
    for (auto&& eid: history) used_e[eid] = 0;
    G.build();
    return G;
  }

private:
  void calc_deg() {
    assert(vc_deg.empty());
    vc_deg.resize(N);
    for (auto&& e: edges) vc_deg[e.frm]++, vc_deg[e.to]++;
  }

  void calc_deg_inout() {
    assert(vc_indeg.empty());
    vc_indeg.resize(N);
    vc_outdeg.resize(N);
    for (auto&& e: edges) { vc_indeg[e.to]++, vc_outdeg[e.frm]++; }
  }
};
#line 3 "/opt/library/graph/shortest_path/dijkstra.hpp"

template <typename T, typename GT>
pair<vc<T>, vi> dijkstra_dense(GT& G, ll s) {
  const ll N = G.N;
  vc<T> dist(N, infty<T>);
  vi par(N, -1);
  vc<bool> done(N);
  dist[s] = 0;
  while (1) {
    ll v = -1;
    T mi = infty<T>;
    rep(i, N) {
      if (!done[i] && chmin(mi, dist[i])) v = i;
    }
    if (v == -1) break;
    done[v] = 1;
    for (auto&& e: G[v]) {
      if (chmin(dist[e.to], dist[v] + e.cost)) par[e.to] = v;
    }
  }
  return {dist, par};
}

template <typename T, typename GT, bool DENSE = false>
pair<vc<T>, vi> dijkstra(GT& G, ll v) {
  if (DENSE) return dijkstra_dense<T>(G, v);
  auto N = G.N;
  vc<T> dist(N, infty<T>);
  vi par(N, -1);
  using P = pair<T, ll>;

  priority_queue<P, vector<P>, greater<P>> que;

  dist[v] = 0;
  que.emplace(0, v);
  while (!que.empty()) {
    auto [dv, v] = que.top();
    que.pop();
    if (dv > dist[v]) continue;
    for (auto&& e: G[v]) {
      if (chmin(dist[e.to], dist[e.frm] + e.cost)) {
        par[e.to] = e.frm;
        que.emplace(dist[e.to], e.to);
      }
    }
  }
  return {dist, par};
}

// 多点スタート。[dist, par, root]
template <typename T, typename GT>
tuple<vc<T>, vi, vi> dijkstra(GT& G, vi vs) {
  assert(G.is_prepared());
  ll N = G.N;
  vc<T> dist(N, infty<T>);
  vi par(N, -1);
  vi root(N, -1);

  using P = pair<T, ll>;

  priority_queue<P, vector<P>, greater<P>> que;

  for (auto&& v: vs) {
    dist[v] = 0;
    root[v] = v;
    que.emplace(T(0), v);
  }

  while (!que.empty()) {
    auto [dv, v] = que.top();
    que.pop();
    if (dv > dist[v]) continue;
    for (auto&& e: G[v]) {
      if (chmin(dist[e.to], dist[e.frm] + e.cost)) {
        root[e.to] = root[e.frm];
        par[e.to] = e.frm;
        que.push(mp(dist[e.to], e.to));
      }
    }
  }
  return {dist, par, root};
}
#line 3 "main.cpp"

int solve();
int main() {
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  while (!solve()) {}
  return 0;
}

int solve() {
  ll n, k, t, a, b, c, d, e;
  cin >> n >> k;
  if ((n==0) and (k==0)) return 1;
  Graph<ll> G(n);
  G.build();
  rep(k) {
    cin >> t;
    G.prepared = false;
    if (t == 0) {
      cin >> a >> b;
      G.build();
      a--; b--;
      auto [dist, par] = dijkstra<ll>(G, a);
      if (dist[b] == inf) print(-1);
      else print(dist[b]);
    } else {
      cin >> c >> d >> e;
      c--; d--;
      G.add(c, d, e);
    }
  }
  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3524
final_rank: 12

code_snippet: #include <algorithm>
#include <iostream>
#include <map>
#include <queue>

using namespace std;

#define INF 1e9

int n, k;
int ship[100][100];

int main() {
    while (cin >> n >> k, n + k > 0) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                ship[i][j] = i == j ? 0 : INF;
            }
        }
        for (int m = 0; m < k; m++) {
            int type;
            cin >> type;
            if (type == 1) {
                int a, b, cost;
                cin >> a >> b >> cost;
                a--;
                b--;
                if (ship[a][b] <= cost) {
                    continue;
                }
                for (int i = 0; i < n; i++) {
                    for (int j = 0; j < n; j++) {
                        ship[i][j] = min(ship[i][j],
                                         min(ship[i][a] + cost + ship[b][j],
                                             ship[i][b] + cost + ship[a][j]));
                    }
                }
            } else {
                int from, to;
                cin >> from >> to;
                from--;
                to--;
                if (ship[from][to] != INF) {
                    cout << ship[from][to] << endl;
                } else {
                    cout << -1 << endl;
                }
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3120
final_rank: 1

code_snippet: #include<stdio.h>
#include<stdlib.h>

#define INF 1e18

struct Node
{
    int id;
    long long cost;
    struct Node *next;
} *Graph[101];

struct Node *Heap[20000] = { NULL };
static int heap_p = 1;

void push( struct Node *p )
{
    Heap[heap_p++] = p;
    int cur = heap_p - 1, par = cur / 2;
    struct Node *tmp;
    while( par > 0 )
    {
        if( Heap[cur]->cost < Heap[par]->cost )
        {
            tmp = Heap[cur], Heap[cur] = Heap[par], Heap[par] = tmp;
            cur /= 2, par /= 2;
        }
        else
        {
            break;
        }
    }
}

struct Node *pop( void )
{
    struct Node *rep = Heap[1];
    Heap[1] = Heap[--heap_p];
    int cur = 1, child = 2;
    struct Node *tmp;
    while( child < heap_p )
    {
        if( child + 1 < heap_p && Heap[child]->cost > Heap[child + 1]->cost ) child++;
        if( Heap[child]->cost < Heap[cur]->cost )
        {
            tmp = Heap[child], Heap[child] = Heap[cur], Heap[cur] = tmp;
            cur = child, child *= 2;
        }
        else
        {
            break;
        }
    }

    return rep;
}

int empty( void )
{
    return heap_p == 0;
}

void clear( void )
{
    heap_p = 1;
}

long long searchShortestPath( int start, int goal )
{
    long long shortest[101];
    for( int i = 1; i <= 100; i++ ) shortest[i] = INF;
    struct Node s;
    s.id = start, s.cost = 0, s.next = NULL;
    clear(), push( &s );
    shortest[start] = 0;
    struct Node *cur, *p, *q;
    while( !empty() )
    {
        cur = pop();
        if( shortest[cur->id] < cur->cost ) continue;

        p = Graph[cur->id];
        while( p != NULL )
        {
            if( shortest[p->id] > shortest[cur->id] + p->cost )
            {
                shortest[p->id] = shortest[cur->id] + p->cost;
                q = ( struct Node * )malloc( sizeof( struct Node ) );
                q->id = p->id, q->cost = shortest[p->id];
                push( q );
            }

            p = p->next;
        }
    }

    return shortest[goal] == INF ? -1 : shortest[goal];
}

int main( void )
{
    int n, k;
    while( 1 )
    {
        scanf( "%d %d", &n, &k );
        if( n == 0 && k == 0 ) break;

        struct  Node *cur, *pre;
        for( int i = 1; i <= n; i++ )
        {
            cur = Graph[i];
            while( cur != NULL )
            {
                pre = cur;
                cur = cur->next;
                free( pre );
            }
            Graph[i] = NULL;
        }

        int order, a, b, c;
        for( int i = 0; i < k; i++ )
        {
            scanf( "%d", &order );
            if( order == 1 )
            {
                scanf( "%d %d %d", &a, &b, &c );

                cur = ( struct Node * )malloc( sizeof( struct Node ) );
                cur->id = b, cur->cost = c;
                cur->next = Graph[a], Graph[a] = cur;

                cur = ( struct Node * )malloc( sizeof( struct Node ) );
                cur->id = a, cur->cost = c;
                cur->next = Graph[b], Graph[b] = cur;
            }
            else
            {
                scanf( "%d %d", &a, &b );
                printf( "%lld\n", searchShortestPath( a, b ) );
            }
        }
    }

    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 43068
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vl = vector<ll>;
using vvl = vector<vl>;
using pl = pair<ll,ll>;
using vp = vector<pl>;
#define rep(i,n) for(ll i=0;i<(ll)(n);++i)
#define reps(i,s,n) for(ll i=(s);i<(ll)(n);++i)
#define rep1(i,n) for(ll i=1;i<=(ll)(n);++i)
template<typename T>inline bool chmax(T &a,T b){return a<b?a=b,true:false;}
template<typename T>inline bool chmin(T &a,T b){return a>b?a=b,true:false;}
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define be(v) (v).begin(),(v).end()
const long long INF = 1e18;
#ifdef DEBUG
#include <debug.hpp>
#endif

bool solve(){
	#ifdef DEBUG
	cout<<1e18<<endl;
	cout<<1e18-1<<endl;
	cout<<(ll)1e18-1<<endl;
	cout << "--- Input ---" << endl;
	#endif
	//cin.unsetf(ios::skipws);
	ll N,Q;cin>>N>>Q;
	if(N==0&&Q==0)return false;

	#ifdef DEBUG
	cout<<N<<" "<<Q<<endl;
	cout << "--- Logic ---" << endl;
	#endif
	vector<vp> g(N);
	auto dijk=[&](ll s){
		//priority_queue<pl,vp,greater<pl>> qu;
		priority_queue<pl> qu;
		qu.emplace(0,s);
		vl dis(N,INF);
		dis.at(s)=0;
		while(!qu.empty()){
			pl p=qu.top();qu.pop();
			ll u=p.se;
			for(auto e:g.at(u)){
				ll v=e.se,c=e.fi;
				if(chmin(dis.at(v),dis.at(u)+c)){
					qu.emplace(c,v);
				}
			}
		}
		return dis;
	};
	rep(qi,Q){
		ll t;cin>>t;
		if(t==0){
			ll a,b;cin>>a>>b;--a;--b;
			vl d=dijk(a);
			if(d.at(b)>=INF)cout<<-1<<endl;
			else cout<<d.at(b)<<endl;
		}else if(t==1){
			ll u,v,c;cin>>u>>v>>c;--u;--v;
			g.at(u).eb(c,v);
			g.at(v).eb(c,u);
		}
	}

	#ifdef DEBUG
	cout << "--- Answer ---" << endl;
	#endif
	return true;
}
int main(){
	#ifdef DEBUG
	cout << "--- Main ---" << endl;
	#endif
	//solve();
	while(solve());
	return 0;
}
//cout << fixed << setprecision(9);
accuracy: 1
time_ms: 620
memory_kb: 3460
final_rank: 19

code_snippet: #include <algorithm>
#include <iostream>
#include <iomanip>
#include <limits.h>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include <stack>
#include <complex>

using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define rep1(i, n) for (int i = 1; i < n + 1; i++)
#define all(A) A.begin(), A.end()
#define itr(A, l, r) A.begin() + l, A.begin() + r
#define debug(var) cout << #var << " = " << var << endl;
typedef long long ll;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p)
{
    os << "(" << p.first << "," << p.second << ")";
    return os;
}

template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p)
{
    is >> p.first >> p.second;
    return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v)
{
    for (int i = 0; i < (int)v.size(); i++)
    {
        os << v[i] << (i + 1 != (int)v.size() ? " " : "");
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &v)
{
    for (int i = 0; i < (int)v.size(); i++)
    {
        os << v[i] << endl;
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<vector<vector<T>>> &v)
{
    for (int i = 0; i < (int)v.size(); i++)
    {
        os << "i = " << i << endl;
        os << v[i];
    }
    return os;
}

template <typename T>
istream &operator>>(istream &is, vector<T> &v)
{
    for (T &in : v)
        is >> in;
    return is;
}

template <typename T, typename S>
ostream &operator<<(ostream &os, map<T, S> &mp)
{
    for (auto &[key, val] : mp)
    {
        os << key << ":" << val << " ";
    }
    cout << endl;
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, set<T> st)
{
    auto itr = st.begin();
    for (int i = 0; i < (int)st.size(); i++)
    {
        os << *itr << (i + 1 != (int)st.size() ? " " : "");
        itr++;
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, multiset<T> st)
{
    auto itr = st.begin();
    for (int i = 0; i < (int)st.size(); i++)
    {
        os << *itr << (i + 1 != (int)st.size() ? " " : "");
        itr++;
    }
    return os;
}

int main()
{
    while (1)
    {
        int n, k;
        cin >> n >> k;
        if (n + k == 0)
        {
            return 0;
        }
        int inf = 1e9;
        using S = pair<int, int>;
        vector<vector<S>> to(n, vector<S>());
        // debug(n);
        // debug(k);
        while (k--)
        {
            int t;
            cin >> t;
            // debug(to);
            if (t == 0)
            {
                vector<int> dist(n, inf);
                int a, b;
                cin >> a >> b;
                a--;
                b--;
                priority_queue<S, vector<S>, greater<S>> pq;
                pq.push({0, a});
                while (pq.size())
                {
                    auto [d, now] = pq.top();
                    pq.pop();
                    if (d >= dist[now])
                    {
                        continue;
                    }
                    dist[now] = d;
                    for (auto [next, cost] : to[now])
                    {
                        pq.push({d + cost, next});
                    }
                }
                // cout << dist << endl;
                if (dist[b] == inf)
                {
                    cout << -1 << endl;
                }
                else
                {
                    cout << dist[b] << endl;
                }
            }
            if (t == 1)
            {
                int c, d, e;
                cin >> c >> d >> e;
                c--;
                d--;
                to[c].push_back({d, e});
                to[d].push_back({c, e});
            }
        }
    }
}
accuracy: 1
time_ms: 340
memory_kb: 3440
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using i32 = int;
using pii = pair<i32, i32>;

const i32 supi = 1e9;

void solve(i32 n, i32 k) {
    vector G(n, vector(0, pair(0, 0)));
    auto dij = [&](i32 a, i32 b) -> i32 {
        vector dist(n, supi);
        dist[a] = 0;
        priority_queue<pii, vector<pii>, greater<pii>> que;
        que.emplace(0, a);
        while (que.size()) {
            auto [w, v] = que.top();
            que.pop();
            if (v == b) {
                break;
            }
            if (dist[v] < w) {
                continue;
            }
            for (auto [x, d] : G[v]) {
                if (dist[x] > w + d) {
                    dist[x] = w + d;
                    que.emplace(dist[x], x);
                }
            }
        }
        return (dist[b] == supi ? -1 : dist[b]);
    };
    for (i32 _ = 0 ; _ < k ; _++) {
        i32 t; cin >> t;
        assert(t == 0 or t == 1);
        if (t == 0) {
            i32 a, b; cin >> a >> b;
            cout << dij(a - 1, b - 1) << endl;
        }
        if (t == 1) {
            i32 c, d, e; cin >> c >> d >> e;
            G[c - 1].emplace_back(d - 1, e);
            G[d - 1].emplace_back(c - 1, e);
        }
    }
}

int main() {
    while (1) {
        i32 n, k; cin >> n >> k;
        if (!n) {
            break;
        }
        solve(n, k);
    }
}
accuracy: 1
time_ms: 40
memory_kb: 3336
final_rank: 6

code_snippet: #include <iostream>
using namespace std;

constexpr int SIZE = 101;
constexpr int INF = 1e9;
int dist[SIZE][SIZE];

int main() {
  for (;;) {
    int N, K; cin >> N >> K;
    if (N == 0 && K == 0) break;
    for (int i = 1; i <= N; ++i)
      for (int j = 1; j <= N; ++j)
        dist[i][j] = (i == j ? 0 : INF);

    while (K-- > 0) {
      int op; cin >> op;
      if (op == 0) {
        int a, b; cin >> a >> b;
        cout << (dist[a][b] == INF ? -1 : dist[a][b]) << endl;
      } else {
        int c, d, e; cin >> c >> d >> e;
        if (dist[c][d] < e) continue;
        dist[c][d] = e;
        dist[d][c] = e;
        for (int k = c; k == c || k == d; k += (d - c))
          for (int i = 1; i <= N; ++i)
            for (int j = 1; j <= N; ++j)
              dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
      }
    }
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3368
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;
template<class t> using vc = vector<t>;
template<class t> using vvc = vc<vc<t>>;
using pi = pair<int,int>;
using vi = vc<int>;
using vvi = vvc<int>;

#define rep(i,a,b) for (int i = (a); i < (b); i++)
#define irep(i,a,b) for (int i = (a); i > (b); i--)
#define all(a) a.begin(),a.end()
#define print(n) cout << n << '\n'
#define pritn(n) print(n)
#define printv(n,a) {copy(all(n),ostream_iterator<a>(cout," ")); cout<<"\n";}
#define rup(a,b) (a+b-1)/b
#define input(A,N) rep(i,0,N) cin>>A[i]
#define chmax(a,b) a = max(a,b)
#define chmin(a,b) a = min(a,b)

template< typename T >
struct edge{
    int to;
    T cost;
    /*
    *to:繋がってる先
    *cost:辺のコスト
    */
    edge(int to, T cost):to(to),cost(cost){};
    edge &operator=(const int& x){
        to = x;
        return *this;
    }
};

template< typename T >
struct graph{
    int n;
    vector<vector<edge<T>>> e;
    bool isweighted=false,isdirected=false;
    graph(int n, bool isweighted=false, bool isdirected=false):
    n(n),e(vector<vector<edge<T>>>(n)),isweighted(isweighted),isdirected(isdirected){}

    graph(int n, vector<vector<T>>& edges, int index=1,bool isweighted=false, bool isdirected=false)
    :n(n),e(vector<vector<edge<T>>>(n)),isweighted(isweighted),isdirected(isdirected){
        addedges(edges,index);
    }

    void addedges(vector<vector<T>>& edges, int index=1){
        for(int i=0; i<edges.size(); i++){
            addedges(edges[i],index);
        }
        return;
    }

    void addedges(vector<T>& edges, int index=1){
        int u = edges[0];u -= index;
        int v = edges[1];v -= index;
        T cost;
        if(isweighted) cost = edges[2];
        else cost = 1;
        e[u].emplace_back(v,cost);
        if(!isdirected) e[v].emplace_back(u,cost);
        return;
    }

    vector<edge<T>> &operator[](int i) {
        return e[i];
    }
};

/*
* O(ElogV)
* 到達不能の場合は―1が入ってる。
*/
template< typename T >
vector<T> dijkstra(graph<T>& g, int st){
    int n = g.n;
    using pt = pair<T,int>;
    vector<T> dist(n,-1);
    dist[st] = 0;
    priority_queue<pt, vector<pt>, greater<pt>>que;
    que.emplace(0,st);
    while(que.size()){
        int ni;
        T cost;
        tie(cost,ni) = que.top();
        que.pop();
        if(dist[ni]<cost&&dist[ni]!=-1) continue;
        for(edge<T> itr:g[ni]){
            int nxt = itr.to;
            if(dist[nxt]>cost+itr.cost||dist[nxt]==-1){
                dist[nxt] = cost + itr.cost;
                que.emplace(dist[nxt],nxt);
            }
        }
    }
    return dist;
};

void solve(int n,int k){
    graph<ll> g(n,true,false);
    while(k--){
        int i;
        cin>>i;
        if(i==0){
            int a,b;
            cin>>a>>b;
            a--;b--;
            vector<ll> dist = dijkstra(g,a);
            print(dist[b]);
        }else{
            int a,b,c;
            cin>>a>>b>>c;
            vector<ll> e{a,b,c};
            g.addedges(e);
        }
    }
}

int main(){
    cout << fixed << setprecision(15);
    
    while(1){
        int n,k;
        cin>>n>>k;
        if(n==0&&k==0) break;
        solve(n,k);
    }
    
    //system("pause");
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3396
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)

template<class T>
using vi = vector<T>;

template<class T>
using vii = vector<vi<T>>;

template<class T>
using viii = vector<vii<T>>;

using pii = pair<int, int>;

const int inf = 1e9 + 10;
int dist[110][110];

int main()
{
    int n, K;
    while(cin >> n >> K, n + K){
        rep(i, n) rep(j, n) dist[i][j] = (i == j ? 0 : inf);    
        
        while (K--) {
            int t, x, y, z;
            cin >> t;
            if (t == 0) {
                cin >> x >> y;
                x--, y--;
                cout << (dist[x][y] == inf ? -1 : dist[x][y]) << endl;
            }
            else if (t == 1) {
                cin >> x >> y >> z;
                x--, y--;
                if (dist[x][y] <= z) continue;
                dist[x][y] = z;
                dist[y][x] = z;
                rep(k, n) rep(i, n) rep(j, n) dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 3360
final_rank: 16

code_snippet: // ダイクストラ法
#include <bits/stdc++.h>

using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;
using P = pair<int, int>;

const int MAX = 10000001;

int check_route(const VVI& route, const int from, const int to, const int n) {
    VI distance(n + 1, MAX);
    distance[from] = 0;
    priority_queue<P, vector<P>, greater<P>> pq;
    pq.push(make_pair(0, from));
    while (!pq.empty()) {
        P p = pq.top();
        pq.pop();
        if (p.second == to) continue;
        for (int i = 1; i < (int)route[p.second].size(); ++i) {
            if (distance[i] < p.first + route[p.second][i]) continue;
            pq.push(make_pair(p.first + route[p.second][i], i));
            distance[i] = p.first + route[p.second][i];
        }
    }
    if (distance[to] == MAX)
        return -1;
    else
        return distance[to];
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    while (true) {
        int n, k;
        cin >> n >> k;
        if (n == 0 && k == 0) break;

        VVI route(n + 1, VI(n + 1, MAX));

        for (int i = 0; i < k; ++i) {
            int x, a, b, c, d, e;
            cin >> x;
            if (x == 0) {
                cin >> a >> b;
                cout << check_route(route, a, b, n) << endl;
            } else {
                cin >> c >> d >> e;
                route[c][d] = min(route[c][d], e);
                route[d][c] = min(route[d][c], e);
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 3368
final_rank: 14

code_snippet: #include <bits/stdc++.h>

using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;
using P = pair<int, int>;

const int MAX = 10000001;

int check_route(const VVI& route, const int from, const int to, const int n) {
    VI distance(n + 1, MAX);
    distance[from] = 0;
    deque<P> dq;
    dq.push_back(make_pair(from, 0));
    while (!dq.empty()) {
        P p = dq.front();
        dq.pop_front();
        if (p.first == to) continue;
        for (int i = 1; i < (int)route[p.first].size(); ++i) {
            if (i == p.first || route[p.first][i] == MAX) continue;
            if (distance[i] < p.second + route[p.first][i]) continue;
            dq.push_back(make_pair(i, p.second + route[p.first][i]));
            distance[i] = p.second + route[p.first][i];
        }
    }
    if (distance[to] == MAX)
        return -1;
    else
        return distance[to];
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    while (true) {
        int n, k;
        cin >> n >> k;
        if (n == 0 && k == 0) break;

        VVI route(n + 1, VI(n + 1, MAX));

        for (int i = 0; i < k; ++i) {
            int x, a, b, c, d, e;
            cin >> x;
            if (x == 0) {
                cin >> a >> b;
                cout << check_route(route, a, b, n) << endl;
            } else {
                cin >> c >> d >> e;
                route[c][d] = min(route[c][d], e);
                route[d][c] = min(route[d][c], e);
                route[c][c] = 0;
                route[d][d] = 0;
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 460
memory_kb: 3420
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;

const int MAX = 10000001;

void upd_route(VVI& r, const int c, const int d, const int e) {
    for (int i = 1; i < (int)r.size(); ++i) {
        for (int j = 1; j < (int)r[i].size(); ++j) {
            int x = r[i][c] + e + r[d][j];
            int y = r[i][d] + e + r[c][j];
            int z = r[i][j];
            r[i][j] = min({x, y, z});
        }
    }
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    while (true) {
        int n, k;
        cin >> n >> k;
        if (n == 0 && k == 0) break;
        
        VVI route(n + 1, VI(n + 1, MAX));

        for (int i = 0; i < k; ++i) {
            int x, a, b, c, d, e;
            cin >> x;
            if (x == 0) {
                cin >> a >> b;
                if (route[a][b] == MAX)
                    cout << -1 << endl;
                else
                    cout << route[a][b] << endl;
            } else {
                cin >> c >> d >> e;
                route[c][c] = 0;
                route[d][d] = 0;
                upd_route(route, c, d, e);
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3424
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(A) A.begin(),A.end()
using vll = vector<ll>;
#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)
using Graph = vector<vector<int>>;


int main() {
   while(1){ll N, K;
    cin >> N >> K;
    if(N==0)return 0;
    vector<vll> dist(N, vll(N, 1e17));
    rep(i, N) {
        dist[i][i] = 0;
    }
    rep(k, K) {
        ll X;
        cin >> X;
        if (X == 0) {
            ll A, B;
            cin >> A >> B;
            A--; B--;
            if (dist[A][B] > 1e16) {
                cout << -1 << endl;
            }
            else {
                cout << dist[A][B] << endl;
            }
        }
        else {
            ll C, D, E;
            cin >> C >> D >> E;

            C--; D--;
            rep(a, N) {
                rep(b, N) {
                    dist[a][b] = min(dist[a][C] + E + dist[D][b], dist[a][b]);
                    dist[a][b] = min(dist[a][D] + E + dist[C][b], dist[a][b]);
                    dist[b][a] = dist[a][b];
                }
            }
        }
    }}
}
accuracy: 1
time_ms: 20
memory_kb: 3448
final_rank: 5

code_snippet: #include <stdio.h>
#include <vector>
#include <queue>
#define INF 1012345678
using namespace std;

int dist[128], vis[128];
vector<pair<int, int>> ed[128];
priority_queue <pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;

int dijk(int n, int s, int e) {
    int x, d;
    for (int i = 1; i <= n; i++) {
        dist[i] = INF;
        vis[i] = 0;
    }
    pq.push(pair<int, int>(0, s));
    while (pq.size()) {
        d = pq.top().first;
        x = pq.top().second;
        pq.pop();
        if (vis[x]) continue;
        else vis[x] = 1;
        for (auto i : ed[x]) {
            if (d + i.second < dist[i.first]) {
                dist[i.first] = d + i.second;
                pq.push(pair<int, int>(d + i.second, i.first));
            }
        }
    }
    if (dist[e] == INF) return -1;
    else return dist[e];
}

int main(void) {
    int n, k, o, a, b, c;
    for (int tt = 0;; tt++) {
        scanf("%d %d", &n, &k);
        if (n == 0) break;
        for (int i = 0; i < k; i++) {
            scanf("%d", &o);
            if (o) {
                scanf("%d %d %d", &a, &b, &c);
                ed[a].push_back(pair<int, int>(b, c));
                ed[b].push_back(pair<int, int>(a, c));
            }
            else {
                scanf("%d %d", &a, &b);
                printf("%d\n", dijk(n, a, b));
            }
        }

        for (int i = 1; i <= n; i++) ed[i].clear();
        while (pq.size()) pq.pop();
    }
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 2984
final_rank: 7

code_snippet: #include <algorithm>
#include <iostream>
#include <iomanip>
#include <limits.h>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include <stack>

using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define rep1(i, n) for (int i = 1; i < n + 1; i++)
#define all(A) A.begin(), A.end()
#define itr(A, l, r) A.begin() + l, A.begin() + r
#define debug(var) cout << #var << " = " << var << endl;
typedef long long ll;

const int inf = 1e9;

template <typename T>
vector<T> dijkstra(int n, vector<vector<pair<int, T>>> to, int start)
{
    vector<T> dist(n + 1, inf);
    priority_queue<pair<int, T>, vector<pair<int, T>>, greater<pair<int, T>>> pq;
    dist[start] = 0;
    pq.push({0, start});
    while (pq.size() > 0)
    {
        auto now_pair = pq.top();
        pq.pop();
        int now = now_pair.second;
        int now_dist = now_pair.first;
        if (dist[now] < now_dist)
        {
            continue;
        }
        for (auto next_pair : to[now])
        {
            int next = next_pair.first;
            T cost = next_pair.second;
            if (dist[now] + cost >= dist[next])
            {
                continue;
            }
            dist[next] = dist[now] + cost;
            pq.push({dist[next], next});
        }
    }
    return dist;
}

void solve(int n, int k)
{
    vector<vector<pair<int, int>>> to(n + 1, vector<pair<int, int>>());
    rep(i, k)
    {
        int q;
        cin >> q;
        if (q == 0)
        {
            int a, b;
            cin >> a >> b;
            vector<int> dist = dijkstra(n, to, a);
            if (dist[b] == inf)
            {
                cout << -1 << endl;
            }
            else
            {
                cout << dist[b] << endl;
            }
        }
        if (q == 1)
        {
            int c, d, e;
            cin >> c >> d >> e;
            to[c].push_back({d, e});
            to[d].push_back({c, e});
        }
    }
}

int main(void)
{
    while (true)
    {
        int n, k;
        cin >> n >> k;
        if (n == 0 && k == 0)
        {
            return 0;
        }
        solve(n, k);
    }
}
accuracy: 1
time_ms: 100
memory_kb: 3420
final_rank: 11