#include <bits/stdc++.h>
template <class T, typename K = std::size_t>
class Interval {
 public:
  K start;
  K stop;
  T value;
  Interval(K s, K e, const T& v) : start(s), stop(e), value(v) {}
};
template <class T, typename K>
K intervalStart(const Interval<T, K>& i) {
  return i.start;
}
template <class T, typename K>
K intervalStop(const Interval<T, K>& i) {
  return i.stop;
}
template <class T, typename K>
std::ostream& operator<<(std::ostream& out, Interval<T, K>& i) {
  out << "Interval(" << i.start << ", " << i.stop << "): " << i.value;
  return out;
}
template <class T, typename K = std::size_t>
class IntervalStartSorter {
 public:
  bool operator()(const Interval<T, K>& a, const Interval<T, K>& b) {
    return a.start < b.start;
  }
};
template <class T, typename K = std::size_t>
class IntervalTree {
 public:
  std::vector<Interval<T, K> > intervals;
  std::unique_ptr<IntervalTree<T, K> > left;
  std::unique_ptr<IntervalTree<T, K> > right;
  K center;
  IntervalTree<T, K>(void) : left(nullptr), right(nullptr), center(0) {}

 private:
  std::unique_ptr<IntervalTree<T, K> > copyTree(
      const IntervalTree<T, K>& orig) {
    return std::unique_ptr<IntervalTree<T, K> >(new IntervalTree<T, K>(orig));
  }

 public:
  IntervalTree<T, K>(const IntervalTree<T, K>& other)
      : intervals(other.intervals),
        left(other.left ? copyTree(*other.left) : nullptr),
        right(other.right ? copyTree(*other.right) : nullptr),
        center(other.center) {}

 public:
  IntervalTree<T, K>& operator=(const IntervalTree<T, K>& other) {
    center = other.center;
    intervals = other.intervals;
    left = other.left ? copyTree(*other.left) : nullptr;
    right = other.right ? copyTree(*other.right) : nullptr;
    return *this;
  }
  IntervalTree<T, K>(std::vector<Interval<T, K> >& ivals,
                     std::size_t depth = 16, std::size_t minbucket = 64,
                     K leftextent = 0, K rightextent = 0,
                     std::size_t maxbucket = 512)
      : left(nullptr), right(nullptr) {
    --depth;
    IntervalStartSorter<T, K> intervalStartSorter;
    if (depth == 0 || (ivals.size() < minbucket && ivals.size() < maxbucket)) {
      std::sort(ivals.begin(), ivals.end(), intervalStartSorter);
      intervals = ivals;
    } else {
      if (leftextent == 0 && rightextent == 0) {
        std::sort(ivals.begin(), ivals.end(), intervalStartSorter);
      }
      K leftp = 0;
      K rightp = 0;
      K centerp = 0;
      if (leftextent || rightextent) {
        leftp = leftextent;
        rightp = rightextent;
      } else {
        leftp = ivals.front().start;
        std::vector<K> stops;
        stops.resize(ivals.size());
        transform(ivals.begin(), ivals.end(), stops.begin(),
                  intervalStop<T, K>);
        rightp = *max_element(stops.begin(), stops.end());
      }
      centerp = ivals.at(ivals.size() / 2).start;
      center = centerp;
      std::vector<Interval<T, K> > lefts;
      std::vector<Interval<T, K> > rights;
      for (typename std::vector<Interval<T, K> >::const_iterator i =
               ivals.begin();
           i != ivals.end(); ++i) {
        const Interval<T, K>& Interval<T, K> = *i;
        if (Interval<T, K>.stop < center) {
          lefts.push_back(Interval<T, K>);
        } else if (Interval<T, K>.start > center) {
          rights.push_back(Interval<T, K>);
        } else {
          intervals.push_back(Interval<T, K>);
        }
      }
      if (!lefts.empty()) {
        left = std::unique_ptr<IntervalTree<T, K> >(
            new IntervalTree<T, K>(lefts, depth, minbucket, leftp, centerp));
      }
      if (!rights.empty()) {
        right = std::unique_ptr<IntervalTree<T, K> >(
            new IntervalTree<T, K>(rights, depth, minbucket, centerp, rightp));
      }
    }
  }
  std::vector<Interval<T, K> > findOverlapping(K start, K stop) const {
    std::vector<Interval<T, K> > ov;
    this->findOverlapping(start, stop, ov);
    return ov;
  }
  void findOverlapping(K start, K stop,
                       std::vector<Interval<T, K> >& overlapping) const {
    if (!intervals.empty() && !(stop < intervals.front().start)) {
      for (typename std::vector<Interval<T, K> >::const_iterator i =
               intervals.begin();
           i != intervals.end(); ++i) {
        const Interval<T, K>& Interval<T, K> = *i;
        if (Interval<T, K>.stop >= start && Interval<T, K>.start <= stop) {
          overlapping.push_back(Interval<T, K>);
        }
      }
    }
    if (left && start <= center) {
      left->findOverlapping(start, stop, overlapping);
    }
    if (right && stop >= center) {
      right->findOverlapping(start, stop, overlapping);
    }
  }
  std::vector<Interval<T, K> > findContained(K start, K stop) const {
    std::vector<Interval<T, K> > contained;
    this->findContained(start, stop, contained);
    return contained;
  }
  void findContained(K start, K stop,
                     std::vector<Interval<T, K> >& contained) const {
    if (!intervals.empty() && !(stop < intervals.front().start)) {
      for (typename std::vector<Interval<T, K> >::const_iterator i =
               intervals.begin();
           i != intervals.end(); ++i) {
        const Interval<T, K>& Interval<T, K> = *i;
        if (Interval<T, K>.start >= start && Interval<T, K>.stop <= stop) {
          contained.push_back(Interval<T, K>);
        }
      }
    }
    if (left && start <= center) {
      left->findContained(start, stop, contained);
    }
    if (right && stop >= center) {
      right->findContained(start, stop, contained);
    }
  }
  ~IntervalTree(void) = default;
};
using namespace std;
int main(int argc, char** argv) {
  int C;
  int T;
  scanf("%d %d", &C, &T);
  int* table;
  table = (int*)malloc(sizeof(int) * T);
  int* current;
  current = (int*)malloc(sizeof(int) * T);
  int* rank;
  rank = (int*)malloc(sizeof(int) * (C + 1));
  vector<Interval<int> > intervals;
  for (int i = 0; i < T; i++) {
    table[i] = 0;
    current[i] = 0;
  }
  for (int i = 0; i < C; i++) {
    int s, e;
    scanf("%d %d", &s, &e);
    intervals.push_back(Interval<int>(s, e, i + 1));
  }
  IntervalTree<int> tree;
  tree = IntervalTree<int>(intervals);
  int k = 0;
  vector<Interval<int> > results;
  tree.findOverlapping(0, T, results);
  for (auto itr = results.begin(); itr != results.end(); ++itr) {
    rank[intervals[k].value] = k + 1;
    k++;
  }
  for (int i = 1; i <= T; i++) {
    vector<Interval<int> > results;
    tree.findOverlapping(i, i, results);
    for (auto itr = results.begin(); itr != results.end(); ++itr) {
      for (int j = 1; j <= sqrt(T); j++) {
        if (i % j != 0) continue;
        int s = i / j;
        if (current[j - 1] < rank[itr->value]) {
          current[j - 1] = rank[itr->value];
          table[j - 1]++;
        }
        if (current[s - 1] < rank[itr->value]) {
          current[s - 1] = rank[itr->value];
          table[s - 1]++;
        }
      }
    }
  }
  for (int i = 0; i < T; i++) {
    printf("%d\n", table[i]);
  }
}
