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

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define FORD(i,b,a) for (int i = (int)(b) - 1; i >= a; --i)
#define REP(i,N) FOR(i,0,N)
#define st first
#define nd second
#define pb push_back

typedef pair<int, int> PII;
typedef long long LL;

/**
 * Intervals are left_bound-closed and right_bound-open: [L, R)
 */
template<typename Config>
struct bit {
  template<typename TConfig = Config>
  struct range_updates_config {
    template<class U> static char (&test(typename U::TRangeUpdate const*))[1];
    template<class U> static char (&test(...))[2];

    template<class U = TConfig> constexpr static typename U::TRangeUpdate _neutral(typename U::TRangeUpdate const*) {
      return U::neutralRangeUpdate();
    }
    template<class U = TConfig> constexpr static void* _neutral(...) { return 0; }

    static const bool enabled = (sizeof(test<TConfig>(0)) == 1);
    typedef decltype(_neutral<TConfig>(0)) Type;
    constexpr static Type neutral() {
      return _neutral<TConfig>(0);
    }
  };

  typedef typename Config::TData TData;
  typedef typename range_updates_config<Config>::Type TRangeUpdate;
  typedef const function<bool(const TData&)>& Predicate;

  int size;
  /** Interval represented by the node */
  vector<pair<int, int>> bounds;
  vector<TData> data;
  vector<TRangeUpdate> range_updates;

  bool __intersects(int L, int R, int idx) {
    return bounds[idx].first < R && L < bounds[idx].second;
  }

  bool __covers(int L, int R, int idx) {
    return L <= bounds[idx].first && bounds[idx].second <= R;
  }

  void __update_range_single(int idx, const TRangeUpdate& op) {
    Config::apply(op, data[idx], bounds[idx].first, bounds[idx].second);
    Config::composeRangeUpdates(op, range_updates[idx]);
  }

  template<class T = Config, typename enable_if<!range_updates_config<T>::enabled, int>::type = 0>
  void __push_range_update(int idx) {}

  template<class T = Config, typename enable_if<range_updates_config<T>::enabled, int>::type = 0>
  void __push_range_update(int idx) {
    if (idx < size) {
      __update_range_single(2*idx, range_updates[idx]);
      __update_range_single(2*idx + 1, range_updates[idx]);
      range_updates[idx] = Config::neutralRangeUpdate();
    }
  }

  void __update_range(int L, int R, const TRangeUpdate& op, int idx) {
    if (!__intersects(L, R, idx)) {
      return;
    }
    if (__covers(L, R, idx)) {
      __update_range_single(idx, op);
      return;
    }

    __push_range_update(idx);
    __update_range(L, R, op, 2*idx);
    __update_range(L, R, op, 2*idx+1);

    data[idx] = Config::merge(data[2*idx], data[2*idx+1]);
  }

  TData __query_range(int L, int R, int idx) {
    if (!__intersects(L, R, idx)) {
      return Config::neutral();
    }
    if (__covers(L, R, idx)) {
      return data[idx];
    }

    __push_range_update(idx);
    return Config::merge(
      __query_range(L, R, 2*idx),
      __query_range(L, R, 2*idx+1)
    );
  }

  /**
  * If last=1, the last matching is returned. If last=0, the first one.
  */
  int __find(int L, int R, Predicate fn, int idx, int last) {
    if (!__intersects(L, R, idx) || !fn(data[idx])) {
      return -1;
    }

    if (idx >= size) {
      return idx - size;
    }

    __push_range_update(idx);
    int preferred = __find(L, R, fn, 2*idx+last, last);
    if (preferred != -1) {
      return preferred;
    }
    return __find(L, R, fn, 2*idx+(last^1), last);
  }

public:
  bit(int _size = 0) {
    size = 1;
    while (size < _size) {
      size <<= 1;
    }
    data = vector<TData>(2*size, Config::neutral());
    range_updates = vector<TRangeUpdate>(2*size, range_updates_config<Config>::neutral());
    bounds = vector<pair<int, int>>(2*size);
    for (int i = 0; i < size; ++i) {
      bounds[i+size] = {i, i+1};
    }
    for (int i = size - 1; i >= 0; --i) {
      bounds[i] = {bounds[2*i].first, bounds[2*i+1].second};
    }
  }

  void update_range(int L, int R, const TRangeUpdate& op) {
    __update_range(L, R, op, 1);
  }

  void update_single(int pos, const TRangeUpdate& op) {
    update_range(pos, pos+1, op);
  }

  TData query_range(int L, int R) {
    return __query_range(L, R, 1);
  }

  TData query_single(int pos) {
    return query_range(pos, pos+1);
  }

  void set(int pos, TData value) {
    int idx = size + pos;
    if (range_updates_config<Config>::enabled) {
      idx = 1;
      while (idx < size) {
        __push_range_update(idx);
        idx = 2*idx + (pos >= bounds[2*idx+1].first);
      }
    }
    // Push pending operations

    data[idx] = value;
    idx >>= 1;
    while (idx > 0) {
      data[idx] = Config::merge(data[2*idx], data[2*idx+1]);
      idx >>= 1;
    }
  }

  /** @returns -1 if no element found */
  int first_which(int L, int R, Predicate contain_check) {
    return __find(L, R, contain_check, 1, 0);
  }

  int first_which(Predicate contain_check) {
    return first_which(0, size, contain_check);
  }

  /** @returns -1 if no element found */
  int last_which(int L, int R, Predicate contain_check) {
    return __find(L, R, contain_check, 1, 1);
  }

  int last_which(Predicate contain_check) {
    return last_which(0, size, contain_check);
  }
};

struct bit_config {
  typedef int TData;
  static TData neutral() {
    return TData();
  }
  static TData merge(const TData& left, const TData& right) {
    return left + right;
  }

  typedef int TRangeUpdate;
  static void apply(const TRangeUpdate& op, TData& value, int A, int B) {
    value += op;
  }
  static void composeRangeUpdates(const TRangeUpdate& outer, TRangeUpdate& inner) {
    inner += outer;
  }
  static TRangeUpdate neutralRangeUpdate() {
    return TRangeUpdate();
  }
};

vector<int> starts[111111];
vector<int> endss[111111];

int result[111111];
vector<int> trains[111111];

int main() {
  int N, M;
  scanf("%d%d", &N, &M);
  REP(i,N) {
    int L, R;
    scanf("%d%d", &L, &R);
    starts[L].pb(R);
    endss[R].pb(L);
  }

  FOR(t,1,M+1) for (int i = 0; i <= M; i += t) trains[i].pb(t);

  bit<bit_config> tree(M+1);

  FOR(i,1,M+1) {
    for (int& r: starts[i]) tree.update_range(i, r+1, 1);
    for (int& t: trains[i]) {
      int res = tree.query_single(i);
      if (i >= t) res -= tree.query_single(i - t);
      result[t] += res;
    }
    for (int& l: endss[i]) tree.update_range(l, i+1, -1);
  }
  FOR(i,1,M+1) printf("%d\n", result[i]);
}


Measured memory_bytes: 27128