#include <bits/stdc++.h>
using namespace std;
inline long long getint() {
  long long _x = 0, _tmp = 1;
  char _tc = getchar();
  while ((_tc < '0' || _tc > '9') && _tc != '-') _tc = getchar();
  if (_tc == '-') _tc = getchar(), _tmp = -1;
  while (_tc >= '0' && _tc <= '9') _x *= 10, _x += (_tc - '0'), _tc = getchar();
  return _x * _tmp;
}
inline long long sub(long long _x, long long _y,
                     long long _mod = 1000000007ll) {
  long long _ = _x - _y;
  if (_ < 0) _ += _mod;
  return _;
}
inline long long mul(long long _x, long long _y,
                     long long _mod = 1000000007ll) {
  long long _ = _x * _y;
  if (_ >= _mod) _ %= _mod;
  return _;
}
long long mypow(long long _a, long long _x, long long _mod) {
  if (_x == 0) return 1ll;
  long long _tmp = mypow(_a, _x / 2, _mod);
  _tmp = mul(_tmp, _tmp, _mod);
  if (_x & 1) _tmp = mul(_tmp, _a, _mod);
  return _tmp;
}
inline bool equal(double _x, double _y) {
  return _x > _y - 1e-9 && _x < _y + 1e-9;
}
int __ = 1, _cs;
void build() {}
int q;
void init() { q = getint(); }
inline long long find_p(long long u, long long v) {
  int du = 0, dv = 0;
  long long tu = u, tv = v;
  while (tu > 1) du++, tu >>= 1;
  while (tv > 1) dv++, tv >>= 1;
  if (du < dv) {
    swap(du, dv);
    swap(u, v);
  }
  while (du > dv) {
    du--;
    u >>= 1;
  }
  while (u != v) {
    u >>= 1;
    v >>= 1;
  }
  return u;
}
map<pair<long long, long long>, long long> M;
inline void add(long long u, long long v, long long w) {
  if (u == v) return;
  long long p = find_p(u, v);
  if (v == p) swap(u, v);
  if (u == p) {
    long long tmp = v >> 1;
    while (tmp != p) {
      if (tmp * 2 == v)
        M[{tmp, 0}] += w;
      else
        M[{tmp, 1}] += w;
      tmp >>= 1;
      v >>= 1;
    }
    if (tmp * 2 == v)
      M[{tmp, 0}] += w;
    else
      M[{tmp, 1}] += w;
    return;
  }
  long long tu = u >> 1, tv = v >> 1;
  while (tu != p) {
    if (tu * 2 == u)
      M[{tu, 0}] += w;
    else
      M[{tu, 1}] += w;
    tu >>= 1;
    u >>= 1;
  }
  if (tu * 2 == u)
    M[{tu, 0}] += w;
  else
    M[{tu, 1}] += w;
  while (tv != p) {
    if (tv * 2 == v)
      M[{tv, 0}] += w;
    else
      M[{tv, 1}] += w;
    tv >>= 1;
    v >>= 1;
  }
  if (tv * 2 == v)
    M[{tv, 0}] += w;
  else
    M[{tv, 1}] += w;
}
inline long long query(long long u, long long v) {
  if (u == v) return 0;
  long long p = find_p(u, v);
  if (v == p) swap(u, v);
  long long ans = 0;
  if (u == p) {
    long long tv = v >> 1;
    while (tv != p) {
      if (tv * 2 == v) {
        if (M.count({tv, 0})) ans += M[{tv, 0}];
      } else {
        if (M.count({tv, 1})) ans += M[{tv, 1}];
      }
      tv >>= 1;
      v >>= 1;
    }
    if (tv * 2 == v) {
      if (M.count({tv, 0})) ans += M[{tv, 0}];
    } else {
      if (M.count({tv, 1})) ans += M[{tv, 1}];
    }
  } else {
    long long tv = v >> 1, tu = u >> 1;
    while (tv != p) {
      if (tv * 2 == v) {
        if (M.count({tv, 0})) ans += M[{tv, 0}];
      } else {
        if (M.count({tv, 1})) ans += M[{tv, 1}];
      }
      tv >>= 1;
      v >>= 1;
    }
    if (tv * 2 == v) {
      if (M.count({tv, 0})) ans += M[{tv, 0}];
    } else {
      if (M.count({tv, 1})) ans += M[{tv, 1}];
    }
    while (tu != p) {
      if (tu * 2 == u) {
        if (M.count({tu, 0})) ans += M[{tu, 0}];
      } else {
        if (M.count({tu, 1})) ans += M[{tu, 1}];
      }
      tu >>= 1;
      u >>= 1;
    }
    if (tu * 2 == u) {
      if (M.count({tu, 0})) ans += M[{tu, 0}];
    } else {
      if (M.count({tu, 1})) ans += M[{tu, 1}];
    }
  }
  return ans;
}
void solve() {
  while (q--) {
    int cmd = getint();
    long long u = getint();
    long long v = getint();
    if (cmd == 1)
      add(u, v, getint());
    else
      printf("%lld\n", query(u, v));
  }
}
int main() {
  build();
  while (__--) {
    init();
    solve();
  }
}
