#include <bits/stdc++.h>

using namespace std;

const long long N = 1e5 + 5, INF = 1e17 + 5;

long long n, m, a, b, c, d, dist[N];

bool vis[N];

struct Edge{
    long long b, c, d;
};

vector<Edge> graph[N];

long double findtime(long long t, long long wait, Edge e){
    return wait + e.c + ((e.d / (long double)(t + 1 + wait)));
}

long long findwait(long long t, Edge e){
    long long l = 0, r = INF, m1, m2;
    long double m1ans, m2ans;

    while(r - l > 2){
        m1 = l + (r - l) / 3;
        m2 = r - (r - l) / 3;

        m1ans = findtime(t, m1, e);
        m2ans = findtime(t, m2, e);

        if(m1ans <= m2ans) r = m2;
        else l = m1;
    }

    vector<pair<long double, long long>> v;

    for(long long i = l; i <= r; i++){
        v.push_back({findtime(t, i, e), i});
    }

    sort(v.begin(), v.end());

    return v.front().second;
}

void dijkstra(){
    for(int i = 1; i <= n; i++) dist[i] = INF;

    priority_queue<pair<long long, long long>> pq;

    dist[1] = 0;

    pq.push({0, 1});

    long long v;

    while(!pq.empty()){
        v = pq.top().second, pq.pop();

        if(!vis[v]){
            vis[v] = true;

            for(auto e : graph[v]){
                if(!vis[e.b]){
                    long long waitt = findwait(dist[v], e);
                    long long edget = findtime(dist[v], waitt, e);

                    if(dist[v] + edget < dist[e.b]){
                        dist[e.b] = dist[v] + edget;
                        pq.push({-dist[e.b], e.b});
                    }
                }
            }
        }
    }
}

int main(){
    ios_base::sync_with_stdio(false);cin.tie(NULL);
    
    cin >> n >> m;

    for(int i = 0; i < m; i++){
        cin >> a >> b >> c >> d;

        graph[a].push_back({b, c, d});
        graph[b].push_back({a, c, d});
    }

    dijkstra();

    cout << (dist[n] == INF ? -1 : dist[n]);
}
#include<bits/stdc++.h>
using namespace std;
 
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define int               long long
#define endl              "\n"
#define pb                push_back
#define ppb               pop_back
#define pf                push_front
#define ppf               pop_front
#define all(x)            (x).begin(),(x).end()
#define uniq(v)           (v).erase(unique(all(v)),(v).end())
#define sz(x)             (int)((x).size())
#define ff                first
#define ss                second
#define pii               pair<int,int>
#define vi                vector<int>
#define vpi               vector<pair<int,int>>
#define mii               map<int,int>
#define rep(i,a,b)        for(int i=a;i<b;i++)
#define repe(i,a,b)        for(int i=a;i<=b;i++)
#define mem1(a)           memset(a,-1,sizeof(a))
#define mem0(a)           memset(a,0,sizeof(a))
#define ppc               __builtin_popcount
#define ppcll             __builtin_popcountll
#define INF 100000000000000000
#define mod 1000000007
#define esp 10e-7
const int mx=3e5+7;
int a[mx];
int st[4*mx];
void construct_st(int ss,int se,int si)
{
  if(ss==se)
  {
    st[si]=a[ss];
    return;
  }
  int mid=(ss+se)/2;
  construct_st(ss,mid,2*si+1);
  construct_st(mid+1,se,2*si+2);
  st[si]=st[2*si+1]^st[2*si+2];
}
int get_xor(int qs,int qe,int ss,int se,int si)
{
  if(ss>qe||qs>se)
    return 0;
 
  if(qs<=ss&&se<=qe)
    { 
      return st[si];}
  int mid=(ss+se)/2;
  return get_xor(qs,qe,ss,mid,2*si+1)^
    get_xor(qs,qe,mid+1,se,2*si+2);
  // return 0;
}
void update_st(int si,int idx,int y,int ss,int se)
{
  if(idx<ss||idx>se)
    return;
  st[si]^=y;
  int mid=(ss+se)/2;
  if(ss!=se)
  {update_st(2*si+1,idx,y,ss,mid);
    update_st(2*si+2,idx,y,mid+1,se);
  }
}
signed main()
{
    //#ifndef ONLINE_JUDGE
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    //freopen("error.txt" , "w" , stderr);
    //#endif 
    IOS
    int t=1,n,q;
    // cin>>t;
   
    while(t--)
    {
      cin>>n>>q;
      for(int i=0;i<n;i++)
      {
        cin>>a[i];
      }
      int type,x,y;
      construct_st(0,n-1,0);
      // for(int i=0;i<=n;i++)
      //   cout<<st[i]<<" ";
      // cout<<endl;
      while(q--)
      {
        cin>>type>>x>>y;
        
        if(type==1)
        {
          x--;
          update_st(0,x,y,0,n-1);
        }else
        {
           x--;
           y--;
          cout<<get_xor(x,y,0,n-1,0)<<endl;
        }
      }
    }
    
    return 0;
}